ReactOS  0.4.14-dev-1034-g1e60116
mmu.c
Go to the documentation of this file.
1 #include <freeldr.h>
2 #include "ppcmmu/mmu.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 asm ("r3");
138  switch( n ) {
139  case 0:
140  __asm__("mfsr 3,0");
141  break;
142  case 1:
143  __asm__("mfsr 3,1");
144  break;
145  case 2:
146  __asm__("mfsr 3,2");
147  break;
148  case 3:
149  __asm__("mfsr 3,3");
150  break;
151  case 4:
152  __asm__("mfsr 3,4");
153  break;
154  case 5:
155  __asm__("mfsr 3,5");
156  break;
157  case 6:
158  __asm__("mfsr 3,6");
159  break;
160  case 7:
161  __asm__("mfsr 3,7");
162  break;
163  case 8:
164  __asm__("mfsr 3,8");
165  break;
166  case 9:
167  __asm__("mfsr 3,9");
168  break;
169  case 10:
170  __asm__("mfsr 3,10");
171  break;
172  case 11:
173  __asm__("mfsr 3,11");
174  break;
175  case 12:
176  __asm__("mfsr 3,12");
177  break;
178  case 13:
179  __asm__("mfsr 3,13");
180  break;
181  case 14:
182  __asm__("mfsr 3,14");
183  break;
184  case 15:
185  __asm__("mfsr 3,15");
186  break;
187  }
188  return res;
189 }
190 
191 inline void GetBat( int bat, int inst, int *batHi, int *batLo ) {
192  register int bh asm("r3"), bl asm("r4");
193  if( inst ) {
194  switch( bat ) {
195  case 0:
196  __asm__("mfibatu 3,0");
197  __asm__("mfibatl 4,0");
198  break;
199  case 1:
200  __asm__("mfibatu 3,1");
201  __asm__("mfibatl 4,1");
202  break;
203  case 2:
204  __asm__("mfibatu 3,2");
205  __asm__("mfibatl 4,2");
206  break;
207  case 3:
208  __asm__("mfibatu 3,3");
209  __asm__("mfibatl 4,3");
210  break;
211  }
212  } else {
213  switch( bat ) {
214  case 0:
215  __asm__("mfdbatu 3,0");
216  __asm__("mfdbatl 4,0");
217  break;
218  case 1:
219  __asm__("mfdbatu 3,1");
220  __asm__("mfdbatl 4,1");
221  break;
222  case 2:
223  __asm__("mfdbatu 3,2");
224  __asm__("mfdbatl 4,2");
225  break;
226  case 3:
227  __asm__("mfdbatu 3,3");
228  __asm__("mfdbatl 4,3");
229  break;
230  }
231  }
232  *batHi = bh;
233  *batLo = bl;
234 }
235 
236 inline void SetBat( int bat, int inst, int batHi, int batLo ) {
237  register int bh asm("r3"), bl asm("r4");
238  bh = batHi;
239  bl = batLo;
240  if( inst ) {
241  switch( bat ) {
242  case 0:
243  __asm__("mtibatu 0,3");
244  __asm__("mtibatl 0,4");
245  break;
246  case 1:
247  __asm__("mtibatu 1,3");
248  __asm__("mtibatl 1,4");
249  break;
250  case 2:
251  __asm__("mtibatu 2,3");
252  __asm__("mtibatl 2,4");
253  break;
254  case 3:
255  __asm__("mtibatu 3,3");
256  __asm__("mtibatl 3,4");
257  break;
258  }
259  } else {
260  switch( bat ) {
261  case 0:
262  __asm__("mtdbatu 0,3");
263  __asm__("mtdbatl 0,4");
264  break;
265  case 1:
266  __asm__("mtdbatu 1,3");
267  __asm__("mtdbatl 1,4");
268  break;
269  case 2:
270  __asm__("mtdbatu 2,3");
271  __asm__("mtdbatl 2,4");
272  break;
273  case 3:
274  __asm__("mtdbatu 3,3");
275  __asm__("mtdbatl 3,4");
276  break;
277  }
278  }
279  __asm__("isync\n\tsync");
280 }
281 
282 inline int GetSDR1() {
283  register int res asm("r3");
284  __asm__("mfsdr1 3");
285  return res;
286 }
287 
288 inline void SetSDR1( int sdr ) {
289 #if 0
290  int i,j;
291 #endif
292  __asm__("mtsdr1 3");
293 #if 0
294  __asm__("sync");
295  __asm__("isync");
296  __asm__("ptesync");
297 
298  for( i = 0; i < 256; i++ ) {
299  j = i << 12;
300  __asm__("tlbie %0,0" : : "r" (j));
301  }
302  __asm__("eieio");
303  __asm__("tlbsync");
304  __asm__("ptesync");
305 #endif
306 }
307 
308 inline int BatHit( int bath, int batl, int virt ) {
309  int mask = 0xfffe0000 & ~((batl & 0x3f) << 17);
310  return (batl & 0x40) && ((virt & mask) == (bath & mask));
311 }
312 
313 inline int BatTranslate( int bath, int batl, int virt ) {
314  return (virt & 0x007fffff) | (batl & 0xfffe0000);
315 }
316 
317 /* translate address */
318 int PpcVirt2phys( int virt, int inst ) {
319  int msr = GetMSR();
320  int txmask = inst ? 0x20 : 0x10;
321  int i, bath, batl, sr, sdr1, physbase, valo;
322  int hash, hashmask, ptehi, ptelo, ptegaddr;
323  //int vahi, npteg;
324  int vsid, pteh, ptevsid, pteapi;
325 
326  if( msr & txmask ) {
327  sr = GetSR( virt >> 28 );
328  vsid = sr & 0xfffffff;
329  //vahi = vsid >> 4;
330  valo = (vsid << 28) | (virt & 0xfffffff);
331  if( sr & 0x80000000 ) {
332  return valo;
333  }
334 
335  for( i = 0; i < 4; i++ ) {
336  GetBat( i, inst, &bath, &batl );
337  if( BatHit( bath, batl, virt ) ) {
338  return BatTranslate( bath, batl, virt );
339  }
340  }
341 
342  sdr1 = GetSDR1();
343 
344  physbase = sdr1 & ~0xffff;
345  hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff;
346  hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff);
347  //npteg = hashmask + 1;
348 
349  for( pteh = 0; pteh < 0x80; pteh += 64, hash ^= 0x7ffff ) {
350  ptegaddr = ((hashmask & hash) * 64) + physbase;
351 
352  for( i = 0; i < 8; i++ ) {
353  ptehi = GetPhys( ptegaddr + (i * 8) );
354  ptelo = GetPhys( ptegaddr + (i * 8) + 4 );
355 
356  ptevsid = (ptehi >> 7) & 0xffffff;
357  pteapi = ptehi & 0x3f;
358 
359  if( (ptehi & 64) != pteh ) continue;
360  if( ptevsid != (vsid & 0xffffff) ) continue;
361  if( pteapi != ((virt >> 22) & 0x3f) ) continue;
362 
363  return (ptelo & 0xfffff000) | (virt & 0xfff);
364  }
365  }
366  return -1;
367  } else {
368  return virt;
369  }
370 }
371 
372 /* Add a new page table entry for the indicated mapping */
373 BOOLEAN InsertPageEntry( int virt, int phys, int slot, int _sdr1 ) {
374  int i, ptehi, ptelo;
375  int sdr1 = _sdr1 ? _sdr1 : GetSDR1();
376  int sr = GetSR( (virt >> 28) & 0xf );
377  int vsid = sr & 0xfffffff;
378  int physbase = sdr1 & ~0xffff;
379  int hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff;
380  int valo = (vsid << 28) | (virt & 0xfffffff);
381  int hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff);
382  int ptegaddr = ((hashmask & hash) * 64) + physbase;
383 
384  for( i = 0; i < 8; i++ ) {
385  ptehi = GetPhys( ptegaddr + (i * 8) );
386 
387  if( (slot != i) && (ptehi & 0x80000000) ) continue;
388 
389  ptehi = (1 << 31) | (vsid << 7) | ((virt >> 22) & 0x3f);
390  ptelo = phys & ~0xfff;
391 
392  SetPhys( ptegaddr + (i * 8), ptehi );
393  SetPhys( ptegaddr + (i * 8) + 4, ptelo );
394 
395  return TRUE;
396  }
397 
398  return FALSE;
399 }
BOOLEAN InsertPageEntry(int virt, int phys, int slot, int _sdr1)
Definition: mmu.c:373
#define TRUE
Definition: types.h:120
int GetMSR()
Definition: mmu.c:4
int GetDEC()
Definition: mmu.c:10
int PpcVirt2phys(int virt, int inst)
Definition: mmu.c:318
GLdouble n
Definition: glext.h:7729
int GetSR(int n)
Definition: mmu.c:136
void SetSDR1(int sdr)
Definition: mmu.c:288
void SetBat(int bat, int inst, int batHi, int batLo)
Definition: mmu.c:236
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
GLenum GLint GLuint mask
Definition: glext.h:6028
int GetSDR1()
Definition: mmu.c:282
int hash
Definition: main.c:58
__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")
unsigned char BOOLEAN
void GetBat(int bat, int inst, int *batHi, int *batLo)
Definition: mmu.c:191
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
ULONG GetPhys(ULONG Addr)
int BatHit(int bath, int batl, int virt)
Definition: mmu.c:308
Definition: vfat.h:184
int BatTranslate(int bath, int batl, int virt)
Definition: mmu.c:313
GLuint res
Definition: glext.h:9613
void SetPhys(ULONG Addr, ULONG Data)
Definition: _hash_fun.h:40