summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmuAsm.S
blob: a0f298e5c36c40c6741d8db5698c68e7fa37b746 (plain) (blame)
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
220
221
222
223
224
/*
 *  mmuAsm.S
 *
 *  $Id$
 *
 *  Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
 *
 *  This file contains the low-level support for various MMU
 *  features.
 *
 *  The license and distribution terms for this file may be
 *  found in found in the file LICENSE in this distribution or at
 *  http://www.OARcorp.com/rtems/license.html.
 *	
 */

#include <libcpu/cpu.h>
#include <libcpu/io.h>
#include <rtems/score/targopts.h>
#include "asm.h"

	.globl  asm_setdbat1
	.type	asm_setdbat1,@function
asm_setdbat1:	
	mtspr DBAT1U, r3
	mtspr DBAT1L, r4
	SYNC
	blr

	.globl  asm_setdbat2
	.type	asm_setdbat2,@function
asm_setdbat2:	
	mtspr DBAT2U, r3
	mtspr DBAT2L, r4
	SYNC
	blr

	.globl  asm_setdbat3
	.type	asm_setdbat3,@function
asm_setdbat3:	
	mtspr DBAT3U, r3
	mtspr DBAT3L, r4
	SYNC
	blr
		
	.globl L1_caches_enables
	.type  L1_caches_enables, @function
	
L1_caches_enables:	
	/*
	 * Enable caches and 604-specific features if necessary.
	 */
	mfspr	r9,PVR
	rlwinm	r9,r9,16,16,31
	cmpi	0,r9,1
	beq	4f			/* not needed for 601 */
	mfspr	r11,HID0
	andi.	r0,r11,HID0_DCE
	ori	r11,r11,HID0_ICE|HID0_DCE
	ori	r8,r11,HID0_ICFI
	bne	3f			/* don't invalidate the D-cache */
	ori	r8,r8,HID0_DCI		/* unless it wasn't enabled */
3:
	sync
	mtspr	HID0,r8			/* enable and invalidate caches */
	sync
	mtspr	HID0,r11		/* enable caches */
	sync
	isync
	cmpi	0,r9,4			/* check for 604 */
	cmpi	1,r9,9			/* or 604e */
	cmpi	2,r9,10			/* or mach5 */
	cror	2,2,6
	cror	2,2,10
	bne	4f
	ori	r11,r11,HID0_SIED|HID0_BHTE /* for 604[e], enable */
	bne	2,5f
	ori	r11,r11,HID0_BTCD
5:	mtspr	HID0,r11		/* superscalar exec & br history tbl */
4:
	blr
	
	.globl get_L2CR
	.type  get_L2CR, @function	
get_L2CR:	
	/* Make sure this is a 750 chip */
	mfspr	r3,PVR
	rlwinm	r3,r3,16,16,31
	cmplwi	r3,0x0008
	li	r3,0
	bnelr
	
	/* Return the L2CR contents */
	mfspr	r3,L2CR
	blr

	.globl set_L2CR
	.type  set_L2CR, @function
set_L2CR:	
	/* Usage:
	 * When setting the L2CR register, you must do a few special things.  
	 * If you are enabling the cache, you must perform a global invalidate. 
	 * If you are disabling the cache, you must flush the cache contents first.
	 * This routine takes care of doing these things.  When first
	 * enabling the cache, make sure you pass in the L2CR you want, as well as 
	 * passing in the global invalidate bit set.  A global invalidate will 
	 * only be performed if the L2I bit is set in applyThis.  When enabling 
	 * the cache, you should also set the L2E bit in applyThis.  If you
	 * want to modify the L2CR contents after the cache has been enabled, 
	 * the recommended procedure is to first call __setL2CR(0) to disable 
	 * the cache and then call it again with the new values for L2CR.  Examples:
	 *
	 *	_setL2CR(0)		-	disables the cache
	 *	_setL2CR(0xb9A14000)	-	enables my G3 MCP750 card:
	 *				-	L2E set to turn on the cache
	 *				-	L2SIZ set to 1MB
	 *				-	L2CLK set to %2
	 *				-	L2RAM set to pipelined syncronous late-write
	 *				-	L2I set to perform a global invalidation
	 *				-	L2OH set to 1 nS
	 *
	 * A similar call should work for your card.  You need to know the correct 
	 * setting for your card and then place them in the fields I have outlined 
	 * above.  Other fields support optional features, such as L2DO which caches 
	 * only data, or L2TS which causes cache pushes from the L1 cache to go to 
	 *the L2 cache instead of to main memory.
	 */
	
	/* Make sure this is a 750 chip */
	mfspr	r4,PVR
	rlwinm	r4,r4,16,16,31
	cmplwi	r4,0x0008
	beq	thisIs750
	li	r3,-1
	blr
	
thisIs750:
	/* Get the current enable bit of the L2CR into r4 */
	mfspr	r4,L2CR
	rlwinm	r4,r4,0,0,0
	
	/* See if we want to perform a global inval this time. */
	rlwinm	r6,r3,0,10,10		/* r6 contains the new invalidate bit */
	rlwinm.	r5,r3,0,0,0		/* r5 contains the new enable bit */
	rlwinm	r3,r3,0,11,9		/* Turn off the invalidate bit */
	rlwinm	r3,r3,0,1,31		/* Turn off the enable bit */
	or	r3,r3,r4		/* Keep the enable bit the same as it was for now. */
	bne	dontDisableCache	/* Only disable the cache if L2CRApply has the enable bit off */

disableCache:
	/* Disable the cache.  First, we turn off data relocation. */
	mfmsr	r7
	rlwinm	r4,r7,0,28,26		/* Turn off DR bit */
	rlwinm	r4,r4,0,17,15		/* Turn off EE bit - an external exception while we are flushing
					   the cache is fatal (comment this line and see!) */
	sync
	mtmsr	r4
	sync
	
	/*
		Now, read the first 2MB of memory to put new data in the cache.
		(Actually we only need the size of the L2 cache plus
		the size of the L1 cache, but 2MB will cover everything just to be safe).
	*/
	lis	r4,0x0001
	mtctr	r4
	li	r4,0
loadLoop:
	lwzx	r0,r0,r4
	addi	r4,r4,0x0020		/* Go to start of next cache line */
	bdnz	loadLoop
	
	/* Now, flush the first 2MB of memory */
	lis	r4,0x0001
	mtctr	r4
	li	r4,0
	sync
flushLoop:
	dcbf	r0,r4
	addi	r4,r4,0x0020	/* Go to start of next cache line */
	bdnz	flushLoop
	
	/* Turn off the L2CR enable bit. */
	rlwinm	r3,r3,0,1,31
	
	/* Reenable data relocation. */
	sync
	mtmsr	r7
	sync
	
dontDisableCache:
	/* Set up the L2CR configuration bits */
	sync
	mtspr	L2CR,r3
	sync
	cmplwi	r6,0
	beq	noInval
	
	/* Perform a global invalidation */
	oris	r3,r3,0x0020
	sync
	mtspr	1017,r3
	sync
invalCompleteLoop:			/* Wait for the invalidation to complete */
	mfspr	r3,1017
	rlwinm.	r4,r3,0,31,31
	bne	invalCompleteLoop
	
	rlwinm	r3,r3,0,11,9;		/* Turn off the L2I bit */
	sync
	mtspr	L2CR,r3
	sync
	
noInval:
	/* See if we need to enable the cache */
	cmplwi	r5,0
	beqlr
	
enableCache:
	/* Enable the cache */
	oris	r3,r3,0x8000
	mtspr	L2CR,r3
	sync
	blr