OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [newlib-1.17.0/] [libgloss/] [sparc/] [cache.c] - Diff between revs 158 and 816

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 158 Rev 816
/* Cache code for SPARClite
/* Cache code for SPARClite
 *
 *
 * Copyright (c) 1998 Cygnus Support
 * Copyright (c) 1998 Cygnus Support
 *
 *
 * The authors hereby grant permission to use, copy, modify, distribute,
 * The authors hereby grant permission to use, copy, modify, distribute,
 * and license this software and its documentation for any purpose, provided
 * and license this software and its documentation for any purpose, provided
 * that existing copyright notices are retained in all copies and that this
 * that existing copyright notices are retained in all copies and that this
 * notice is included verbatim in any distributions. No written agreement,
 * notice is included verbatim in any distributions. No written agreement,
 * license, or royalty fee is required for any of the authorized uses.
 * license, or royalty fee is required for any of the authorized uses.
 * Modifications to this software may be copyrighted by their authors
 * Modifications to this software may be copyrighted by their authors
 * and need not follow the licensing terms described here, provided that
 * and need not follow the licensing terms described here, provided that
 * the new terms are clearly indicated on the first page of each file where
 * the new terms are clearly indicated on the first page of each file where
 * they apply.
 * they apply.
 */
 */
 
 
#include "sparclite.h"
#include "sparclite.h"
 
 
/* Ancillary registers on the DANlite */
/* Ancillary registers on the DANlite */
 
 
#define DIAG 30
#define DIAG 30
#define ICCR 31
#define ICCR 31
 
 
/* Bits in the DIAG register */
/* Bits in the DIAG register */
 
 
#define ICD 0x40000000          /* ICACHE disable */
#define ICD 0x40000000          /* ICACHE disable */
#define DCD 0x20000000          /* DCACHE disable */
#define DCD 0x20000000          /* DCACHE disable */
 
 
/* Bits in the ICCR register */
/* Bits in the ICCR register */
 
 
#define CE 1                    /* cache enable*/
#define CE 1                    /* cache enable*/
 
 
 
 
/* Forward declarations. */
/* Forward declarations. */
 
 
void flush_i_cache ();
void flush_i_cache ();
 
 
 
 
/* Determine if this is a DANlite (MB8686x), as opposed to an earlier
/* Determine if this is a DANlite (MB8686x), as opposed to an earlier
   SPARClite (MB8683x).  This is done by examining the impl and ver
   SPARClite (MB8683x).  This is done by examining the impl and ver
   fields in the PSR:
   fields in the PSR:
 
 
   MB8683x: impl(bit31-28)=0x0; ver(bit27-24)=0xf;
   MB8683x: impl(bit31-28)=0x0; ver(bit27-24)=0xf;
   MB8686x: impl(bit31-28)=0x1; ver(bit27-24)=0xe;
   MB8686x: impl(bit31-28)=0x1; ver(bit27-24)=0xe;
*/
*/
 
 
static int
static int
is_danlite ()
is_danlite ()
{
{
  static int checked = 0;
  static int checked = 0;
  static int danlite = 0;
  static int danlite = 0;
 
 
  if (!checked)
  if (!checked)
    {
    {
      int psr = read_psr ();
      int psr = read_psr ();
      danlite = (psr & 0xff000000) == 0x1e000000;
      danlite = (psr & 0xff000000) == 0x1e000000;
      checked = 1;
      checked = 1;
    }
    }
  return danlite;
  return danlite;
}
}
 
 
/* This cache code is known to work on both the 930 & 932 processors.  It just
/* This cache code is known to work on both the 930 & 932 processors.  It just
   cheats and clears the all of the address space that could contain tags, as
   cheats and clears the all of the address space that could contain tags, as
   opposed to striding the tags at 8 or 16 word intervals, or using the cache
   opposed to striding the tags at 8 or 16 word intervals, or using the cache
   flush registers, which don't exist on all processors.  */
   flush registers, which don't exist on all processors.  */
 
 
void
void
cache_off ()
cache_off ()
{
{
  if (is_danlite ())
  if (is_danlite ())
    {
    {
      /* Disable the ICACHE.  Disabling the DCACHE crashes the machine. */
      /* Disable the ICACHE.  Disabling the DCACHE crashes the machine. */
      unsigned int diag = read_asr (DIAG);
      unsigned int diag = read_asr (DIAG);
      write_asr (DIAG, diag | ICD);
      write_asr (DIAG, diag | ICD);
    }
    }
  else
  else
    {
    {
      write_asi (1, 0, 0);
      write_asi (1, 0, 0);
    }
    }
}
}
 
 
void
void
cache_on ()
cache_on ()
{
{
  if (is_danlite ())
  if (is_danlite ())
    {
    {
      unsigned int diag;
      unsigned int diag;
 
 
      /* Flush the caches. */
      /* Flush the caches. */
      flush_i_cache ();
      flush_i_cache ();
 
 
      /* Enable the ICACHE and DCACHE */
      /* Enable the ICACHE and DCACHE */
      diag = read_asr (DIAG);
      diag = read_asr (DIAG);
      write_asr (DIAG, diag & ~ (ICD | DCD));
      write_asr (DIAG, diag & ~ (ICD | DCD));
    }
    }
  else
  else
    {
    {
      unsigned long addr;
      unsigned long addr;
 
 
      cache_off ();                     /* Make sure the cache is off */
      cache_off ();                     /* Make sure the cache is off */
 
 
      /* Reset all of the cache line valid bits */
      /* Reset all of the cache line valid bits */
 
 
      for (addr = 0; addr < 0x1000; addr += 8)
      for (addr = 0; addr < 0x1000; addr += 8)
        {
        {
          write_asi (0xc, addr, 0);      /* Clear bank 1, icache */
          write_asi (0xc, addr, 0);      /* Clear bank 1, icache */
          write_asi (0xc, addr + 0x80000000, 0); /* Clear bank 2, icache */
          write_asi (0xc, addr + 0x80000000, 0); /* Clear bank 2, icache */
 
 
          write_asi (0xe, addr, 0);      /* Clear bank 1, dcache */
          write_asi (0xe, addr, 0);      /* Clear bank 1, dcache */
          write_asi (0xe, addr + 0x80000000, 0); /* Clear bank 2, dcache */
          write_asi (0xe, addr + 0x80000000, 0); /* Clear bank 2, dcache */
        }
        }
 
 
      /* turn on the cache */
      /* turn on the cache */
 
 
      write_asi (1, 0, 0x35);    /* Write buf ena, prefetch buf ena, data
      write_asi (1, 0, 0x35);    /* Write buf ena, prefetch buf ena, data
                                       & inst caches enab */
                                       & inst caches enab */
    }
    }
}
}
 
 
/* Flush the instruction cache.  We need to do this for the debugger stub so
/* Flush the instruction cache.  We need to do this for the debugger stub so
   that breakpoints, et. al. become visible to the instruction stream after
   that breakpoints, et. al. become visible to the instruction stream after
   storing them in memory.
   storing them in memory.
 */
 */
 
 
void
void
flush_i_cache ()
flush_i_cache ()
{
{
  if (is_danlite ())
  if (is_danlite ())
    {
    {
      write_asi (0x31, 0, 0);     /* Flush entire i/d caches */
      write_asi (0x31, 0, 0);     /* Flush entire i/d caches */
    }
    }
  else
  else
    {
    {
      int cache_reg;
      int cache_reg;
      unsigned long addr;
      unsigned long addr;
 
 
      cache_reg = read_asi (1, 0);       /* Read cache/bus interface reg */
      cache_reg = read_asi (1, 0);       /* Read cache/bus interface reg */
 
 
      if (!(cache_reg & 1))
      if (!(cache_reg & 1))
        return;                 /* Just return if cache is already off */
        return;                 /* Just return if cache is already off */
 
 
      for (addr = 0; addr < 0x1000; addr += 8)
      for (addr = 0; addr < 0x1000; addr += 8)
        {
        {
          write_asi (0xc, addr, 0);      /* Clear bank 1, icache */
          write_asi (0xc, addr, 0);      /* Clear bank 1, icache */
          write_asi (0xc, addr + 0x80000000, 0); /* Clear bank 2, icache */
          write_asi (0xc, addr + 0x80000000, 0); /* Clear bank 2, icache */
        }
        }
    }
    }
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.