summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_l1cache.S
blob: fa39bfd20ec18772ac096542bbdae9957ca478c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/*  *********************************************************************
    *  SB1250 Board Support Package
    *  
    *  L1C initialization			File: bcmcore_l1cache.S
    *  
    *  This module contains code to initialize the CPU's caches
    *  
    *  Note: all the routines in this module rely on registers only,
    *        since DRAM may not be active yet.
    *
    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
    *  
    *********************************************************************  
    *
    *  XX Copyright 2000,2001
    *  Broadcom Corporation. All rights reserved.
    *
    *  BROADCOM PROPRIETARY AND CONFIDENTIAL
    *  
    *  This software is furnished under license and may be used and 
    *  copied only in accordance with the license.
    ********************************************************************* */

#include "sbmips.h"
#include "bsp_config.h"

		.text

		.set push	
		.set mips32

/*  *********************************************************************
    *  Macros
    ********************************************************************* */

#define CP0_CFG_ISMSK      (0x7 << 22)
#define CP0_CFG_ISSHF      22
#define CP0_CFG_ILMSK      (0x7 << 19)
#define CP0_CFG_ILSHF      19
#define CP0_CFG_IAMSK      (0x7 << 16)
#define CP0_CFG_IASHF      16
#define CP0_CFG_DSMSK      (0x7 << 13)
#define CP0_CFG_DSSHF      13
#define CP0_CFG_DLMSK      (0x7 << 10)
#define CP0_CFG_DLSHF      10
#define CP0_CFG_DAMSK      (0x7 << 7)
#define CP0_CFG_DASHF      7

#define cacheop(kva, size, linesize, op) \
        .set    noreorder;       \
        addu    t1, kva, size;   \
        subu    t2, linesize, 1; \
        not     t2;              \
        and     t0, kva, t2;     \
        addu    t1, -1;          \
        and     t1, t2;          \
10:     cache   op, 0(t0);       \
        bne     t0, t1, 10b;     \
        addu    t0, linesize;    \
11:                              \
        .set    reorder

#define size_icache(size, linesize) \
        mfc0    t7, C0_CONFIG, 1;       \
        and     t0, t7, CP0_CFG_ILMSK;  \
        srl     t0, t0, CP0_CFG_ILSHF;  \
        move    linesize, zero;         \
        beq     t0, zero,1f;            \
        add     t0, 1;                  \
        li      linesize, 1;            \
        sll     linesize, t0;           \
1:      and     t0, t7, CP0_CFG_ISMSK;  \
        srl     t0, t0, CP0_CFG_ISSHF;  \
        li      size, 64;               \
        sll     size, t0;               \
        and     t0, t7, CP0_CFG_IAMSK;  \
        srl     t0, t0, CP0_CFG_IASHF;  \
        add     t0, 1;                  \
        mult    size, t0;               \
        mflo    size;                   \
        mult    size, linesize;         \
        mflo    size
        
#define size_dcache(size, linesize) \
        mfc0    t7, C0_CONFIG, 1;       \
        and     t0, t7, CP0_CFG_DLMSK;  \
        srl     t0, t0, CP0_CFG_DLSHF;  \
        move    linesize, zero;         \
        beq     t0, zero,1f;            \
        add     t0, 1;                  \
        li      linesize, 1;            \
        sll     linesize, t0;           \
1:      and     t0, t7, CP0_CFG_DSMSK;  \
        srl     t0, t0, CP0_CFG_DSSHF;  \
        li      size, 64;               \
        sll     size, t0;               \
        and     t0, t7, CP0_CFG_DAMSK;  \
        srl     t0, t0, CP0_CFG_DASHF;  \
        add     t0, 1;                  \
        mult    size, t0;               \
        mflo    size;                   \
        mult    size, linesize;         \
        mflo    size
        

/*  *********************************************************************
    *  BCMCORE_L1CACHE_INIT()
    *  
    *  Initialize the L1 Cache
    *  
    *  Input parameters: 
    *  	   nothing
    *  	   
    *  Return value:
    *  	   nothing
    *  
    *  Registers used:
    *  	   t0,t1,t2
    ********************************************************************* */

LEAF(bcmcore_l1cache_init)

        mtc0    zero, C0_TAGLO  # Initialize TAGLO register
        mtc0    zero, C0_TAGLO,1 # Initialize DataLo register

        li      a0, K0BASE      # Initialise primary instruction cache.
        size_icache(a1, a2)
        cacheop(a0, a1, a2, Index_Store_Tag_I)

        li      a0, K0BASE      # Initialise primary data cache.
        size_dcache(a1, a2)
        cacheop(a0, a1, a2, Index_Store_Tag_D)

		jr	ra

END(bcmcore_l1cache_init)

/*  *********************************************************************
    *  BCMCORE_L1CACHE_INVAL_I()
    *  
    *  Invalidate the entire ICache
    *  
    *  Input parameters: 
    *  	   nothing
    *  	   
    *  Return value:
    *  	   nothing
    *  
    *  Registers used:
    *  	   t0,t1,t2
    ********************************************************************* */
LEAF(bcmcore_l1cache_inval_i)
		
        li      a0, K0BASE
        size_icache(a1, a2)
        cacheop(a0, a1, a2, Index_Invalidate_I)

		j	ra

END(bcmcore_l1cache_inval_i)

/*  *********************************************************************
    *  BCMCORE_L1CACHE_FLUSH_D()
    *  
    *  Flush the entire DCache
    *  
    *  Input parameters: 
    *  	   nothing
    *  	   
    *  Return value:
    *  	   nothing
    *  
    *  Registers used:
    *  	   t0,t1,t2
    ********************************************************************* */
LEAF(bcmcore_l1cache_flush_d)

        li      a0, K0BASE
        size_dcache(a1, a2)

# before flushing cache clear tags pointing to flash memory to avoid writes into flash
        addu    t1, a0, a1
        subu    t2, a2, 1
        not     t2
        and     t0, a0, t2
        addu    t1, -1
        and     t1, t2
1:
        cache   Index_Load_Tag_D, 0(t0)
        nop
        nop
        nop
        nop
        nop
        nop
        mfc0    t2, C0_TAGLO         # Read TAGLO register
        and     t2, 0x1f000000       # check address
        li      t3, 0x1f000000
        bne     t2, t3, 2f
        mtc0    zero, C0_TAGLO
        cache   Index_Store_Tag_D, 0(t0)    # Reset tag for flash memory locations
2:
        .set noreorder;
        bne     t0, t1, 1b
        addu    t0, a2
        .set reorder

        cacheop(a0, a1, a2, Index_Writeback_Inv_D)

		j	ra

END(bcmcore_l1cache_flush_d)

		.set pop

/*  *********************************************************************
    *  End
    ********************************************************************* */