ReactOS  0.4.15-dev-494-g1d8c567
mmuutil.c
Go to the documentation of this file.
1 #include "ppcmmu/mmu.h"
2 #include "ppcmmu/mmuutil.h"
3 
4 inline int GetMSR() {
5  register int res asm ("r3");
6  __asm__("mfmsr 3");
7  return res;
8 }
9 
10 inline int GetDEC() {
11  register int res asm ("r3");
12  __asm__("mfdec 3");
13  return res;
14 }
15 
16 __asm__("\t.globl GetPhys\n"
17  "GetPhys:\t\n"
18  "mflr 0\n\t"
19  "stwu 0,-16(1)\n\t"
20  "mfmsr 5\n\t"
21  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
22  "mtmsr 6\n\t"
23  "isync\n\t"
24  "sync\n\t"
25  "lwz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
26  "mtmsr 5\n\t"
27  "isync\n\t"
28  "sync\n\t"
29  "lwz 0,0(1)\n\t"
30  "addi 1,1,16\n\t"
31  "mtlr 0\n\t"
32  "blr"
33  );
34 
35 __asm__("\t.globl GetPhysHalf\n"
36  "GetPhysHalf:\t\n"
37  "mflr 0\n\t"
38  "stwu 0,-16(1)\n\t"
39  "mfmsr 5\n\t"
40  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
41  "mtmsr 6\n\t"
42  "isync\n\t"
43  "sync\n\t"
44  "lhz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
45  "mtmsr 5\n\t"
46  "isync\n\t"
47  "sync\n\t"
48  "lwz 0,0(1)\n\t"
49  "addi 1,1,16\n\t"
50  "mtlr 0\n\t"
51  "blr"
52  );
53 
54 __asm__("\t.globl GetPhysByte\n"
55  "GetPhysByte:\t\n"
56  "mflr 0\n\t"
57  "stwu 0,-16(1)\n\t"
58  "mfmsr 5\n\t"
59  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
60  "mtmsr 6\n\t"
61  "isync\n\t"
62  "sync\n\t"
63  "lbz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
64  "mtmsr 5\n\t"
65  "isync\n\t"
66  "sync\n\t"
67  "lwz 0,0(1)\n\t"
68  "addi 1,1,16\n\t"
69  "mtlr 0\n\t"
70  "blr"
71  );
72 
73 __asm__("\t.globl SetPhys\n"
74  "SetPhys:\t\n"
75  "mflr 0\n\t"
76  "stwu 0,-16(1)\n\t"
77  "mfmsr 5\n\t"
78  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
79  "mtmsr 6\n\t"
80  "sync\n\t"
81  "eieio\n\t"
82  "stw 4,0(3)\n\t" /* Set actual value at phys addr r3 */
83  "dcbst 0,3\n\t"
84  "mtmsr 5\n\t"
85  "sync\n\t"
86  "eieio\n\t"
87  "mr 3,4\n\t"
88  "lwz 0,0(1)\n\t"
89  "addi 1,1,16\n\t"
90  "mtlr 0\n\t"
91  "blr"
92  );
93 
94 __asm__("\t.globl SetPhysHalf\n"
95  "SetPhysHalf:\t\n"
96  "mflr 0\n\t"
97  "stwu 0,-16(1)\n\t"
98  "mfmsr 5\n\t"
99  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
100  "mtmsr 6\n\t"
101  "sync\n\t"
102  "eieio\n\t"
103  "sth 4,0(3)\n\t" /* Set actual value at phys addr r3 */
104  "dcbst 0,3\n\t"
105  "mtmsr 5\n\t"
106  "sync\n\t"
107  "eieio\n\t"
108  "mr 3,4\n\t"
109  "lwz 0,0(1)\n\t"
110  "addi 1,1,16\n\t"
111  "mtlr 0\n\t"
112  "blr"
113  );
114 
115 __asm__("\t.globl SetPhysByte\n"
116  "SetPhysByte:\t\n"
117  "mflr 0\n\t"
118  "stwu 0,-16(1)\n\t"
119  "mfmsr 5\n\t"
120  "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
121  "mtmsr 6\n\t"
122  "sync\n\t"
123  "eieio\n\t"
124  "stb 4,0(3)\n\t" /* Set actual value at phys addr r3 */
125  "dcbst 0,3\n\t"
126  "mtmsr 5\n\t"
127  "sync\n\t"
128  "eieio\n\t"
129  "mr 3,4\n\t"
130  "lwz 0,0(1)\n\t"
131  "addi 1,1,16\n\t"
132  "mtlr 0\n\t"
133  "blr"
134  );
135 
136 inline int GetSR(int n) {
137  register int res = 0;
138  switch( n ) {
139  case 0:
140  __asm__("mfsr %0,0" : "=r" (res));
141  break;
142  case 1:
143  __asm__("mfsr %0,1" : "=r" (res));
144  break;
145  case 2:
146  __asm__("mfsr %0,2" : "=r" (res));
147  break;
148  case 3:
149  __asm__("mfsr %0,3" : "=r" (res));
150  break;
151  case 4:
152  __asm__("mfsr %0,4" : "=r" (res));
153  break;
154  case 5:
155  __asm__("mfsr %0,5" : "=r" (res));
156  break;
157  case 6:
158  __asm__("mfsr %0,6" : "=r" (res));
159  break;
160  case 7:
161  __asm__("mfsr %0,7" : "=r" (res));
162  break;
163  case 8:
164  __asm__("mfsr %0,8" : "=r" (res));
165  break;
166  case 9:
167  __asm__("mfsr %0,9" : "=r" (res));
168  break;
169  case 10:
170  __asm__("mfsr %0,10" : "=r" (res));
171  break;
172  case 11:
173  __asm__("mfsr %0,11" : "=r" (res));
174  break;
175  case 12:
176  __asm__("mfsr %0,12" : "=r" (res));
177  break;
178  case 13:
179  __asm__("mfsr %0,13" : "=r" (res));
180  break;
181  case 14:
182  __asm__("mfsr %0,14" : "=r" (res));
183  break;
184  case 15:
185  __asm__("mfsr %0,15" : "=r" (res));
186  break;
187  }
188  return res;
189 }
190 
191 inline void SetSR(int n, int val) {
192  switch( n ) {
193  case 0:
194  __asm__("mtsr 0,%0" : : "r" (val));
195  break;
196  case 1:
197  __asm__("mtsr 1,%0" : : "r" (val));
198  break;
199  case 2:
200  __asm__("mtsr 2,%0" : : "r" (val));
201  break;
202  case 3:
203  __asm__("mtsr 3,%0" : : "r" (val));
204  break;
205  case 4:
206  __asm__("mtsr 4,%0" : : "r" (val));
207  break;
208  case 5:
209  __asm__("mtsr 5,%0" : : "r" (val));
210  break;
211  case 6:
212  __asm__("mtsr 6,%0" : : "r" (val));
213  break;
214  case 7:
215  __asm__("mtsr 7,%0" : : "r" (val));
216  break;
217  case 8:
218  __asm__("mtsr 8,%0" : : "r" (val));
219  break;
220  case 9:
221  __asm__("mtsr 9,%0" : : "r" (val));
222  break;
223  case 10:
224  __asm__("mtsr 10,%0" : : "r" (val));
225  break;
226  case 11:
227  __asm__("mtsr 11,%0" : : "r" (val));
228  break;
229  case 12:
230  __asm__("mtsr 12,%0" : : "r" (val));
231  break;
232  case 13:
233  __asm__("mtsr 13,%0" : : "r" (val));
234  break;
235  case 14:
236  __asm__("mtsr 14,%0" : : "r" (val));
237  break;
238  case 15:
239  __asm__("mtsr 15,%0" : : "r" (val));
240  break;
241  }
242 }
243 
244 void GetBat( int bat, int inst, int *batHi, int *batLo ) {
245  register int bh asm("r3"), bl asm("r4");
246  if( inst ) {
247  switch( bat ) {
248  case 0:
249  __asm__("mfibatu 3,0");
250  __asm__("mfibatl 4,0");
251  break;
252  case 1:
253  __asm__("mfibatu 3,1");
254  __asm__("mfibatl 4,1");
255  break;
256  case 2:
257  __asm__("mfibatu 3,2");
258  __asm__("mfibatl 4,2");
259  break;
260  case 3:
261  __asm__("mfibatu 3,3");
262  __asm__("mfibatl 4,3");
263  break;
264  }
265  } else {
266  switch( bat ) {
267  case 0:
268  __asm__("mfdbatu 3,0");
269  __asm__("mfdbatl 4,0");
270  break;
271  case 1:
272  __asm__("mfdbatu 3,1");
273  __asm__("mfdbatl 4,1");
274  break;
275  case 2:
276  __asm__("mfdbatu 3,2");
277  __asm__("mfdbatl 4,2");
278  break;
279  case 3:
280  __asm__("mfdbatu 3,3");
281  __asm__("mfdbatl 4,3");
282  break;
283  }
284  }
285  *batHi = bh;
286  *batLo = bl;
287 }
288 
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;
292 
293 void SetBat( int bat, int inst, int batHi, int batLo ) {
294  if( inst ) {
295  switch( bat ) {
296  BATSET(0,i);
297  BATSET(1,i);
298  BATSET(2,i);
299  BATSET(3,i);
300  }
301  } else {
302  switch( bat ) {
303  BATSET(0,d);
304  BATSET(1,d);
305  BATSET(2,d);
306  BATSET(3,d);
307  }
308  }
309  __asm__("isync\n\tsync");
310 }
311 
312 inline int GetSDR1() {
313  register int res asm("r3");
314  __asm__("mfsdr1 3");
315  return res;
316 }
317 
318 inline void SetSDR1( int sdr ) {
319  int i,j;
320  __asm__("mtsdr1 3");
321  __asm__("sync");
322  __asm__("isync");
323 
324  for( i = 0; i < 256; i++ ) {
325  j = i << 12;
326  __asm__("tlbie %0,0" : : "r" (j));
327  }
328  __asm__("eieio");
329  __asm__("tlbsync");
330  __asm__("ptesync");
331 }
332 
333 inline int BatTranslate( int batu, int batl, int virt ) {
334  int mask;
335  if(batu & 0x3fc)
336  {
337  mask = ~(0x1ffff | ((batu & 0x3fc)>>2)<<17);
338  if((batu & 2) && ((batu & mask) == (virt & mask)))
339  return (batl & mask) | (virt & ~mask);
340  } else {
341  mask = ~(0x1ffff | (batl << 17));
342  if(!(batl & 0x40) || ((batu & mask) != (virt & mask)))
343  return (batl & mask) | (virt & ~mask);
344  }
345  return -1;
346 }
347 
348 inline int BatHit( int batu, int batl, int virt ) {
349  return BatTranslate( batu, batl, virt ) != -1;
350 }
351 
352 /* translate address */
353 int PpcVirt2phys( vaddr_t virt, int inst ) {
354  int msr = GetMSR();
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;
359 
360  if( msr & txmask ) {
361  sr = GetSR( virt >> 28 );
362  vsid = sr & 0xfffffff;
363  vahi = vsid >> 4;
364  valo = (vsid << 28) | (virt & 0xfffffff);
365  if( sr & 0x80000000 ) {
366  return valo;
367  }
368 
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 );
373  }
374  }
375 
376  sdr1 = GetSDR1();
377 
378  physbase = sdr1 & ~0xffff;
379  hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff;
380  hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff);
381  npteg = hashmask + 1;
382 
383  for( pteh = 0; pteh < 0x80; pteh += 64, hash ^= 0x7ffff ) {
384  ptegaddr = ((hashmask & hash) * 64) + physbase;
385 
386  for( i = 0; i < 8; i++ ) {
387  ptehi = GetPhys( ptegaddr + (i * 8) );
388  ptelo = GetPhys( ptegaddr + (i * 8) + 4 );
389 
390  ptevsid = (ptehi >> 7) & 0xffffff;
391  pteapi = ptehi & 0x3f;
392 
393  if( (ptehi & 64) != pteh ) continue;
394  if( ptevsid != (vsid & 0xffffff) ) continue;
395  if( pteapi != ((virt >> 22) & 0x3f) ) continue;
396 
397  return (ptelo & 0xfffff000) | (virt & 0xfff);
398  }
399  }
400  return -1;
401  } else {
402  return virt;
403  }
404 }
405 
406 int PtegNumber(vaddr_t virt, int hfun)
407 {
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);
411 }
#define PPC_VSID_MASK
Definition: mmu.h:67
int GetMSR()
Definition: mmuutil.c:4
int GetSDR1()
Definition: mmuutil.c:312
GLdouble n
Definition: glext.h:7729
int BatHit(int batu, int batl, int virt)
Definition: mmuutil.c:348
int GetSR(int n)
Definition: mmuutil.c:136
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void SetBat(int bat, int inst, int batHi, int batLo)
Definition: mmuutil.c:293
GLenum GLint GLuint mask
Definition: glext.h:6028
int hash
Definition: main.c:58
int PtegNumber(vaddr_t virt, int hfun)
Definition: mmuutil.c:406
unsigned long vaddr_t
Definition: mmu.h:90
GLuint GLfloat * val
Definition: glext.h:7180
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define d
Definition: ke_i.h:81
ULONG GetPhys(ULONG Addr)
void GetBat(int bat, int inst, int *batHi, int *batLo)
Definition: mmuutil.c:244
#define HTABSIZ
Definition: mmu.h:59
#define BATSET(n, t)
Definition: mmuutil.c:289
__asm__("\t.globl GetPhys\n" "GetPhys:\t\n" "mflr 0\n\t" "stwu 0,-16(1)\n\t" "mfmsr 5\n\t" "andi. 6,5,0xffef\n\t" "mtmsr 6\n\t" "isync\n\t" "sync\n\t" "lwz 3,0(3)\n\t" "mtmsr 5\n\t" "isync\n\t" "sync\n\t" "lwz 0,0(1)\n\t" "addi 1,1,16\n\t" "mtlr 0\n\t" "blr")
void SetSR(int n, int val)
Definition: mmuutil.c:191
int PpcVirt2phys(vaddr_t virt, int inst)
Definition: mmuutil.c:353
void SetSDR1(int sdr)
Definition: mmuutil.c:318
GLuint res
Definition: glext.h:9613
Definition: _hash_fun.h:40
int GetDEC()
Definition: mmuutil.c:10
int BatTranslate(int batu, int batl, int virt)
Definition: mmuutil.c:333