Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libgloss/sparc/cache.c')
-rw-r--r--libgloss/sparc/cache.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/libgloss/sparc/cache.c b/libgloss/sparc/cache.c
new file mode 100644
index 000000000..5b6e270d7
--- /dev/null
+++ b/libgloss/sparc/cache.c
@@ -0,0 +1,147 @@
+/* Cache code for SPARClite
+ *
+ * Copyright (c) 1998 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * 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
+ * they apply.
+ */
+
+#include "sparclite.h"
+
+/* Ancillary registers on the DANlite */
+
+#define DIAG 30
+#define ICCR 31
+
+/* Bits in the DIAG register */
+
+#define ICD 0x40000000 /* ICACHE disable */
+#define DCD 0x20000000 /* DCACHE disable */
+
+/* Bits in the ICCR register */
+
+#define CE 1 /* cache enable*/
+
+
+/* Forward declarations. */
+
+void flush_i_cache ();
+
+
+/* Determine if this is a DANlite (MB8686x), as opposed to an earlier
+ SPARClite (MB8683x). This is done by examining the impl and ver
+ fields in the PSR:
+
+ MB8683x: impl(bit31-28)=0x0; ver(bit27-24)=0xf;
+ MB8686x: impl(bit31-28)=0x1; ver(bit27-24)=0xe;
+*/
+
+static int
+is_danlite ()
+{
+ static int checked = 0;
+ static int danlite = 0;
+
+ if (!checked)
+ {
+ int psr = read_psr ();
+ danlite = (psr & 0xff000000) == 0x1e000000;
+ checked = 1;
+ }
+ return danlite;
+}
+
+/* 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
+ opposed to striding the tags at 8 or 16 word intervals, or using the cache
+ flush registers, which don't exist on all processors. */
+
+void
+cache_off ()
+{
+ if (is_danlite ())
+ {
+ /* Disable the ICACHE. Disabling the DCACHE crashes the machine. */
+ unsigned int diag = read_asr (DIAG);
+ write_asr (DIAG, diag | ICD);
+ }
+ else
+ {
+ write_asi (1, 0, 0);
+ }
+}
+
+void
+cache_on ()
+{
+ if (is_danlite ())
+ {
+ unsigned int diag;
+
+ /* Flush the caches. */
+ flush_i_cache ();
+
+ /* Enable the ICACHE and DCACHE */
+ diag = read_asr (DIAG);
+ write_asr (DIAG, diag & ~ (ICD | DCD));
+ }
+ else
+ {
+ unsigned long addr;
+
+ cache_off (); /* Make sure the cache is off */
+
+ /* Reset all of the cache line valid bits */
+
+ for (addr = 0; addr < 0x1000; addr += 8)
+ {
+ write_asi (0xc, addr, 0); /* Clear bank 1, icache */
+ write_asi (0xc, addr + 0x80000000, 0); /* Clear bank 2, icache */
+
+ write_asi (0xe, addr, 0); /* Clear bank 1, dcache */
+ write_asi (0xe, addr + 0x80000000, 0); /* Clear bank 2, dcache */
+ }
+
+ /* turn on the cache */
+
+ write_asi (1, 0, 0x35); /* Write buf ena, prefetch buf ena, data
+ & inst caches enab */
+ }
+}
+
+/* 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
+ storing them in memory.
+ */
+
+void
+flush_i_cache ()
+{
+ if (is_danlite ())
+ {
+ write_asi (0x31, 0, 0); /* Flush entire i/d caches */
+ }
+ else
+ {
+ int cache_reg;
+ unsigned long addr;
+
+ cache_reg = read_asi (1, 0); /* Read cache/bus interface reg */
+
+ if (!(cache_reg & 1))
+ return; /* Just return if cache is already off */
+
+ for (addr = 0; addr < 0x1000; addr += 8)
+ {
+ write_asi (0xc, addr, 0); /* Clear bank 1, icache */
+ write_asi (0xc, addr + 0x80000000, 0); /* Clear bank 2, icache */
+ }
+ }
+}