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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib/] [libgloss/] [sparc/] [cache.c] - Blame information for rev 56

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 56 joel
/* Cache code for SPARClite
2
 *
3
 * Copyright (c) 1998 Cygnus Support
4
 *
5
 * The authors hereby grant permission to use, copy, modify, distribute,
6
 * and license this software and its documentation for any purpose, provided
7
 * that existing copyright notices are retained in all copies and that this
8
 * notice is included verbatim in any distributions. No written agreement,
9
 * license, or royalty fee is required for any of the authorized uses.
10
 * Modifications to this software may be copyrighted by their authors
11
 * and need not follow the licensing terms described here, provided that
12
 * the new terms are clearly indicated on the first page of each file where
13
 * they apply.
14
 */
15
 
16
#include "sparclite.h"
17
 
18
/* Ancillary registers on the DANlite */
19
 
20
#define DIAG 30
21
#define ICCR 31
22
 
23
/* Bits in the DIAG register */
24
 
25
#define ICD 0x40000000          /* ICACHE disable */
26
#define DCD 0x20000000          /* DCACHE disable */
27
 
28
/* Bits in the ICCR register */
29
 
30
#define CE 1                    /* cache enable*/
31
 
32
 
33
/* Forward declarations. */
34
 
35
void flush_i_cache ();
36
 
37
 
38
/* Determine if this is a DANlite (MB8686x), as opposed to an earlier
39
   SPARClite (MB8683x).  This is done by examining the impl and ver
40
   fields in the PSR:
41
 
42
   MB8683x: impl(bit31-28)=0x0; ver(bit27-24)=0xf;
43
   MB8686x: impl(bit31-28)=0x1; ver(bit27-24)=0xe;
44
*/
45
 
46
static int
47
is_danlite ()
48
{
49
  static int checked = 0;
50
  static int danlite = 0;
51
 
52
  if (!checked)
53
    {
54
      int psr = read_psr ();
55
      danlite = (psr & 0xff000000) == 0x1e000000;
56
      checked = 1;
57
    }
58
  return danlite;
59
}
60
 
61
/* This cache code is known to work on both the 930 & 932 processors.  It just
62
   cheats and clears the all of the address space that could contain tags, as
63
   opposed to striding the tags at 8 or 16 word intervals, or using the cache
64
   flush registers, which don't exist on all processors.  */
65
 
66
void
67
cache_off ()
68
{
69
  if (is_danlite ())
70
    {
71
      /* Disable the ICACHE.  Disabling the DCACHE crashes the machine. */
72
      unsigned int diag = read_asr (DIAG);
73
      write_asr (DIAG, diag | ICD);
74
    }
75
  else
76
    {
77
      write_asi (1, 0, 0);
78
    }
79
}
80
 
81
void
82
cache_on ()
83
{
84
  if (is_danlite ())
85
    {
86
      unsigned int diag;
87
 
88
      /* Flush the caches. */
89
      flush_i_cache ();
90
 
91
      /* Enable the ICACHE and DCACHE */
92
      diag = read_asr (DIAG);
93
      write_asr (DIAG, diag & ~ (ICD | DCD));
94
    }
95
  else
96
    {
97
      unsigned long addr;
98
 
99
      cache_off ();                     /* Make sure the cache is off */
100
 
101
      /* Reset all of the cache line valid bits */
102
 
103
      for (addr = 0; addr < 0x1000; addr += 8)
104
        {
105
          write_asi (0xc, addr, 0);      /* Clear bank 1, icache */
106
          write_asi (0xc, addr + 0x80000000, 0); /* Clear bank 2, icache */
107
 
108
          write_asi (0xe, addr, 0);      /* Clear bank 1, dcache */
109
          write_asi (0xe, addr + 0x80000000, 0); /* Clear bank 2, dcache */
110
        }
111
 
112
      /* turn on the cache */
113
 
114
      write_asi (1, 0, 0x35);    /* Write buf ena, prefetch buf ena, data
115
                                       & inst caches enab */
116
    }
117
}
118
 
119
/* Flush the instruction cache.  We need to do this for the debugger stub so
120
   that breakpoints, et. al. become visible to the instruction stream after
121
   storing them in memory.
122
 */
123
 
124
void
125
flush_i_cache ()
126
{
127
  if (is_danlite ())
128
    {
129
      write_asi (0x31, 0, 0);     /* Flush entire i/d caches */
130
    }
131
  else
132
    {
133
      int cache_reg;
134
      unsigned long addr;
135
 
136
      cache_reg = read_asi (1, 0);       /* Read cache/bus interface reg */
137
 
138
      if (!(cache_reg & 1))
139
        return;                 /* Just return if cache is already off */
140
 
141
      for (addr = 0; addr < 0x1000; addr += 8)
142
        {
143
          write_asi (0xc, addr, 0);      /* Clear bank 1, icache */
144
          write_asi (0xc, addr + 0x80000000, 0); /* Clear bank 2, icache */
145
        }
146
    }
147
}

powered by: WebSVN 2.1.0

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