1 #include "ppcmmu/mmu.h"
2 #include "ppcmmu/mmuutil.h"
5 register int res
asm ("r3");
11 register int res
asm ("r3");
16 __asm__("\t.globl GetPhys\n"
21 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
25 "lwz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
35 __asm__("\t.globl GetPhysHalf\n"
40 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
44 "lhz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
54 __asm__("\t.globl GetPhysByte\n"
59 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
63 "lbz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
73 __asm__("\t.globl SetPhys\n"
78 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
82 "stw 4,0(3)\n\t" /* Set actual value at phys addr r3 */
94 __asm__("\t.globl SetPhysHalf\n"
99 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
103 "sth 4,0(3)\n\t" /* Set actual value at phys addr r3 */
115 __asm__("\t.globl SetPhysByte\n"
120 "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
124 "stb 4,0(3)\n\t" /* Set actual value at phys addr r3 */
136 inline int GetSR(int n
) {
137 register int res
= 0;
140 __asm__("mfsr %0,0" : "=r" (res
));
143 __asm__("mfsr %0,1" : "=r" (res
));
146 __asm__("mfsr %0,2" : "=r" (res
));
149 __asm__("mfsr %0,3" : "=r" (res
));
152 __asm__("mfsr %0,4" : "=r" (res
));
155 __asm__("mfsr %0,5" : "=r" (res
));
158 __asm__("mfsr %0,6" : "=r" (res
));
161 __asm__("mfsr %0,7" : "=r" (res
));
164 __asm__("mfsr %0,8" : "=r" (res
));
167 __asm__("mfsr %0,9" : "=r" (res
));
170 __asm__("mfsr %0,10" : "=r" (res
));
173 __asm__("mfsr %0,11" : "=r" (res
));
176 __asm__("mfsr %0,12" : "=r" (res
));
179 __asm__("mfsr %0,13" : "=r" (res
));
182 __asm__("mfsr %0,14" : "=r" (res
));
185 __asm__("mfsr %0,15" : "=r" (res
));
191 inline void SetSR(int n
, int val
) {
194 __asm__("mtsr 0,%0" : : "r" (val
));
197 __asm__("mtsr 1,%0" : : "r" (val
));
200 __asm__("mtsr 2,%0" : : "r" (val
));
203 __asm__("mtsr 3,%0" : : "r" (val
));
206 __asm__("mtsr 4,%0" : : "r" (val
));
209 __asm__("mtsr 5,%0" : : "r" (val
));
212 __asm__("mtsr 6,%0" : : "r" (val
));
215 __asm__("mtsr 7,%0" : : "r" (val
));
218 __asm__("mtsr 8,%0" : : "r" (val
));
221 __asm__("mtsr 9,%0" : : "r" (val
));
224 __asm__("mtsr 10,%0" : : "r" (val
));
227 __asm__("mtsr 11,%0" : : "r" (val
));
230 __asm__("mtsr 12,%0" : : "r" (val
));
233 __asm__("mtsr 13,%0" : : "r" (val
));
236 __asm__("mtsr 14,%0" : : "r" (val
));
239 __asm__("mtsr 15,%0" : : "r" (val
));
244 void GetBat( int bat
, int inst
, int *batHi
, int *batLo
) {
245 register int bh
asm("r3"), bl
asm("r4");
249 __asm__("mfibatu 3,0");
250 __asm__("mfibatl 4,0");
253 __asm__("mfibatu 3,1");
254 __asm__("mfibatl 4,1");
257 __asm__("mfibatu 3,2");
258 __asm__("mfibatl 4,2");
261 __asm__("mfibatu 3,3");
262 __asm__("mfibatl 4,3");
268 __asm__("mfdbatu 3,0");
269 __asm__("mfdbatl 4,0");
272 __asm__("mfdbatu 3,1");
273 __asm__("mfdbatl 4,1");
276 __asm__("mfdbatu 3,2");
277 __asm__("mfdbatl 4,2");
280 __asm__("mfdbatu 3,3");
281 __asm__("mfdbatl 4,3");
289 #define BATSET(n,t) \
290 case n: __asm__("mt" #t "batu " #n ",%0\n\tmt" #t "batl " #n ",%1" \
291 : : "r" (batHi), "r" (batLo)); break;
293 void SetBat( int bat
, int inst
, int batHi
, int batLo
) {
309 __asm__("isync\n\tsync");
312 inline int GetSDR1() {
313 register int res
asm("r3");
318 inline void SetSDR1( int sdr
) {
324 for( i
= 0; i
< 256; i
++ ) {
326 __asm__("tlbie %0,0" : : "r" (j
));
333 inline int BatTranslate( int batu
, int batl
, int virt
) {
337 mask
= ~(0x1ffff | ((batu
& 0x3fc)>>2)<<17);
338 if((batu
& 2) && ((batu
& mask
) == (virt
& mask
)))
339 return (batl
& mask
) | (virt
& ~mask
);
341 mask
= ~(0x1ffff | (batl
<< 17));
342 if(!(batl
& 0x40) || ((batu
& mask
) != (virt
& mask
)))
343 return (batl
& mask
) | (virt
& ~mask
);
348 inline int BatHit( int batu
, int batl
, int virt
) {
349 return BatTranslate( batu
, batl
, virt
) != -1;
352 /* translate address */
353 int PpcVirt2phys( vaddr_t virt
, int inst
) {
355 int txmask
= inst
? 0x20 : 0x10;
356 int i
, bath
, batl
, sr
, sdr1
, physbase
, vahi
, valo
;
357 int npteg
, hash
, hashmask
, ptehi
, ptelo
, ptegaddr
;
358 int vsid
, pteh
, ptevsid
, pteapi
;
361 sr
= GetSR( virt
>> 28 );
362 vsid
= sr
& 0xfffffff;
364 valo
= (vsid
<< 28) | (virt
& 0xfffffff);
365 if( sr
& 0x80000000 ) {
369 for( i
= 0; i
< 4; i
++ ) {
370 GetBat( i
, inst
, &bath
, &batl
);
371 if( BatHit( bath
, batl
, virt
) ) {
372 return BatTranslate( bath
, batl
, virt
);
378 physbase
= sdr1
& ~0xffff;
379 hashmask
= ((sdr1
& 0x1ff) << 10) | 0x3ff;
380 hash
= (vsid
& 0x7ffff) ^ ((valo
>> 12) & 0xffff);
381 npteg
= hashmask
+ 1;
383 for( pteh
= 0; pteh
< 0x80; pteh
+= 64, hash
^= 0x7ffff ) {
384 ptegaddr
= ((hashmask
& hash
) * 64) + physbase
;
386 for( i
= 0; i
< 8; i
++ ) {
387 ptehi
= GetPhys( ptegaddr
+ (i
* 8) );
388 ptelo
= GetPhys( ptegaddr
+ (i
* 8) + 4 );
390 ptevsid
= (ptehi
>> 7) & 0xffffff;
391 pteapi
= ptehi
& 0x3f;
393 if( (ptehi
& 64) != pteh
) continue;
394 if( ptevsid
!= (vsid
& 0xffffff) ) continue;
395 if( pteapi
!= ((virt
>> 22) & 0x3f) ) continue;
397 return (ptelo
& 0xfffff000) | (virt
& 0xfff);
406 int PtegNumber(vaddr_t virt
, int hfun
)
408 int sr
= GetSR( (virt
>> 28) & 0xf );
409 int vsid
= sr
& PPC_VSID_MASK
;
410 return ((((vsid
& 0x7ffff) ^ ((virt
>> 12) & 0xffff)) ^ (hfun
? -1 : 0)) & ((HTABSIZ
- 1) >> 3) & 0x3ff);