Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * cortex arm arch v7 cache flushing and invalidation
3
 * included by l.s and rebootcode.s
4
 */
5
 
6
TEXT cacheiinv(SB), $-4				/* I invalidate */
7
	MOVW	$0, R0
8
	MTCP	CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall /* ok on cortex */
9
	ISB
10
	RET
11
 
12
/*
13
 * set/way operators, passed a suitable set/way value in R0.
14
 */
15
TEXT cachedwb_sw(SB), $-4
16
	MTCP	CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEsi
17
	RET
18
 
19
TEXT cachedwbinv_sw(SB), $-4
20
	MTCP	CpSC, 0, R0, C(CpCACHE), C(CpCACHEwbi), CpCACHEsi
21
	RET
22
 
23
TEXT cachedinv_sw(SB), $-4
24
	MTCP	CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvd), CpCACHEsi
25
	RET
26
 
27
	/* set cache size select */
28
TEXT setcachelvl(SB), $-4
29
	MTCP	CpSC, CpIDcssel, R0, C(CpID), C(CpIDidct), 0
30
	ISB
31
	RET
32
 
33
	/* return cache sizes */
34
TEXT getwayssets(SB), $-4
35
	MFCP	CpSC, CpIDcsize, R0, C(CpID), C(CpIDidct), 0
36
	RET
37
 
38
/*
39
 * l1 cache operations.
40
 * l1 and l2 ops are intended to be called from C, thus need save no
41
 * caller's regs, only those we need to preserve across calls.
42
 */
43
 
44
TEXT cachedwb(SB), $-4
45
	MOVW.W	R14, -8(R13)
46
	MOVW	$cachedwb_sw(SB), R0
47
	MOVW	$1, R8
48
	BL	wholecache(SB)
49
	MOVW.P	8(R13), R15
50
 
51
TEXT cachedwbinv(SB), $-4
52
	MOVW.W	R14, -8(R13)
53
	MOVW	$cachedwbinv_sw(SB), R0
54
	MOVW	$1, R8
55
	BL	wholecache(SB)
56
	MOVW.P	8(R13), R15
57
 
58
TEXT cachedinv(SB), $-4
59
	MOVW.W	R14, -8(R13)
60
	MOVW	$cachedinv_sw(SB), R0
61
	MOVW	$1, R8
62
	BL	wholecache(SB)
63
	MOVW.P	8(R13), R15
64
 
65
TEXT cacheuwbinv(SB), $-4
66
	MOVM.DB.W [R14], (R13)	/* save lr on stack */
67
	MOVW	CPSR, R1
68
	CPSID			/* splhi */
69
 
70
	MOVM.DB.W [R1], (R13)	/* save R1 on stack */
71
 
72
	BL	cachedwbinv(SB)
73
	BL	cacheiinv(SB)
74
 
75
	MOVM.IA.W (R13), [R1]	/* restore R1 (saved CPSR) */
76
	MOVW	R1, CPSR
77
	MOVM.IA.W (R13), [R14]	/* restore lr */
78
	RET
79
 
80
/*
81
 * architectural l2 cache operations
82
 */
83
 
84
TEXT _l2cacheuwb(SB), $-4
85
	MOVW.W	R14, -8(R13)
86
	MOVW	$cachedwb_sw(SB), R0
87
	MOVW	$2, R8
88
	BL	wholecache(SB)
89
	MOVW.P	8(R13), R15	/* return */
90
 
91
TEXT _l2cacheuwbinv(SB), $-4
92
	MOVW.W	R14, -8(R13)
93
	MOVW	CPSR, R1
94
	CPSID			/* splhi */
95
 
96
	MOVM.DB.W [R1], (R13)	/* save R1 on stack */
97
 
98
	MOVW	$cachedwbinv_sw(SB), R0
99
	MOVW	$2, R8
100
	BL	wholecache(SB)
101
 
102
	BL	_l2cacheuinv(SB)
103
 
104
	MOVM.IA.W (R13), [R1]	/* restore R1 (saved CPSR) */
105
	MOVW	R1, CPSR
106
	MOVW.P	8(R13), R15	/* return */
107
 
108
TEXT _l2cacheuinv(SB), $-4
109
	MOVW.W	R14, -8(R13)
110
	MOVW	$cachedinv_sw(SB), R0
111
	MOVW	$2, R8
112
	BL	wholecache(SB)
113
	MOVW.P	8(R13), R15	/* return */
114
 
115
/*
116
 * callers are assumed to be the above l1 and l2 ops.
117
 * R0 is the function to call in the innermost loop.
118
 * R8 is the cache level (1-origin: 1 or 2).
119
 *
120
 * R0	func to call at entry
121
 * R1	func to call after entry
122
 * R2	nsets
123
 * R3	way shift (computed from R8)
124
 * R4	set shift (computed from R8)
125
 * R5	nways
126
 * R6	set scratch
127
 * R7	way scratch
128
 * R8	cache level, 0-origin
129
 * R9	extern reg up
130
 * R10	extern reg m
131
 *
132
 * initial translation by 5c, then massaged by hand.
133
 */
134
TEXT wholecache+0(SB), $-4
135
	MOVW	CPSR, R2
136
	MOVM.DB.W [R2,R14], (SP) /* save regs on stack */
137
 
138
	MOVW	R0, R1		/* save argument for inner loop in R1 */
139
	SUB	$1, R8		/* convert cache level to zero origin */
140
 
141
	/* we might not have the MMU on yet, so map R1 (func) to R14's space */
142
	MOVW	R14, R0		/* get R14's segment ... */
143
	AND	$KSEGM, R0
144
	BIC	$KSEGM,	R1	/* strip segment from func address */
145
	ORR	R0, R1		/* combine them */
146
 
147
	/* get cache sizes */
148
	SLL	$1, R8, R0	/* R0 = (cache - 1) << 1 */
149
	MTCP	CpSC, CpIDcssel, R0, C(CpID), C(CpIDidct), 0 /* set cache select */
150
	ISB
151
	MFCP	CpSC, CpIDcsize, R0, C(CpID), C(CpIDidct), 0 /* get cache sizes */
152
 
153
	/* compute # of ways and sets for this cache level */
154
	SRA	$3, R0, R5	/* R5 (ways) = R0 >> 3 */
155
	AND	$((1<<10)-1), R5 /* R5 = (R0 >> 3) & MASK(10) */
156
	ADD	$1, R5		/* R5 (ways) = ((R0 >> 3) & MASK(10)) + 1 */
157
 
158
	SRA	$13, R0, R2	/* R2 = R0 >> 13 */
159
	AND	$((1<<15)-1), R2 /* R2 = (R0 >> 13) & MASK(15) */
160
	ADD	$1, R2		/* R2 (sets) = ((R0 >> 13) & MASK(15)) + 1 */
161
 
162
	/* precompute set/way shifts for inner loop */
163
	MOVW	$(CACHECONF+0), R3	/* +0 = l1waysh */
164
	MOVW	$(CACHECONF+4), R4	/* +4 = l1setsh */
165
	CMP	$0, R8		/* cache == 1? */
166
	ADD.NE	$(4*2), R3	/* no, assume l2: +8 = l2waysh */
167
	ADD.NE	$(4*2), R4	/* +12 = l2setsh */
168
 
169
	MOVW	R14, R0		/* get R14's segment ... */
170
	AND	$KSEGM, R0
171
 
172
	BIC	$KSEGM,	R3	/* strip segment from address */
173
	ORR	R0, R3		/* combine them */
174
	BIC	$KSEGM,	R4	/* strip segment from address */
175
	ORR	R0, R4		/* combine them */
176
	MOVW	(R3), R3
177
	MOVW	(R4), R4
178
 
179
	CMP	$0, R3		/* sanity checks */
180
	BEQ	wbuggery
181
	CMP	$0, R4
182
	BEQ	sbuggery
183
 
184
	CPSID			/* splhi to make entire op atomic */
185
	BARRIERS
186
 
187
	/* iterate over ways */
188
	MOVW	$0, R7		/* R7: way */
189
outer:
190
	/* iterate over sets */
191
	MOVW	$0, R6		/* R6: set */
192
inner:
193
	/* compute set/way register contents */
194
	SLL	R3, R7, R0 	/* R0 = way << R3 (L?WAYSH) */
195
	ORR	R8<<1, R0	/* R0 = way << L?WAYSH | (cache - 1) << 1 */
196
	ORR	R6<<R4, R0 	/* R0 = way<<L?WAYSH | (cache-1)<<1 |set<<R4 */
197
 
198
	BL	(R1)		/* call set/way operation with R0 arg. */
199
 
200
	ADD	$1, R6		/* set++ */
201
	CMP	R2, R6		/* set >= sets? */
202
	BLT	inner		/* no, do next set */
203
 
204
	ADD	$1, R7		/* way++ */
205
	CMP	R5, R7		/* way >= ways? */
206
	BLT	outer		/* no, do next way */
207
 
208
	MOVM.IA.W (SP), [R2,R14] /* restore regs */
209
	BARRIERS
210
	MOVW	R2, CPSR	/* splx */
211
 
212
	RET
213
 
214
wbuggery:
215
	PUTC('?')
216
	PUTC('c')
217
	PUTC('w')
218
	B	topanic
219
sbuggery:
220
	PUTC('?')
221
	PUTC('c')
222
	PUTC('s')
223
topanic:
224
	MOVW	$.string<>+0(SB), R0
225
	BIC	$KSEGM,	R0	/* strip segment from address */
226
	MOVW	R14, R1		/* get R14's segment ... */
227
	AND	$KSEGM, R1
228
	ORR	R1, R0		/* combine them */
229
	SUB	$12, R13	/* not that it matters, since we're panicing */
230
	MOVW	R14, 8(R13)
231
	BL	panic(SB)	/* panic("msg %#p", LR) */
232
bugloop:
233
	WFI
234
	B	bugloop
235
 
236
	DATA	.string<>+0(SB)/8,$"bad cach"
237
	DATA	.string<>+8(SB)/8,$"e params"
238
	DATA	.string<>+16(SB)/8,$"\073 pc %\043p"
239
	DATA	.string<>+24(SB)/1,$"\z"
240
	GLOBL	.string<>+0(SB),$25