ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
tlbsrc.c
Go to the documentation of this file.
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Licenced under Academic Free License version 2.0
7 # Review ps2sdk README & LICENSE files for further details.
8 */
9 
10 #include <kernel.h>
11 #include <ee_cop0_defs.h>
12 
13 /* Doesn't work, but here are the COP0 register definitions:
14 #define Index $0
15 #define EntryLo0 $2
16 #define EntryLo1 $3
17 #define PageMask $5
18 #define Wired $6
19 #define EntryHi $10 */
20 
21 struct SyscallPatchData{
22  unsigned int syscall;
23  void *function;
24 };
25 
26 char *_kExecArg[] __attribute__((section(".kExecArg")));
27 char *_kExecArg[] = {NULL}; /* 0x80075330 */
28 
29 //Function prototypes:
30 int PutTLBEntry(unsigned int PageMask, unsigned int EntryHi, unsigned int EntryLo0, unsigned int EntryLo1);
31 int SetTLBEntry(unsigned int index, unsigned int PageMask, unsigned int EntryHi, unsigned int EntryLo0, unsigned int EntryLo1);
32 int GetTLBEntry(unsigned int index, unsigned int *PageMask, unsigned int *EntryHi, unsigned int *EntryLo0, unsigned int *EntryLo1);
33 int ProbeTLBEntry(unsigned int EntryHi, unsigned int *PageMask, unsigned int *EntryLo0, unsigned int *EntryLo1);
34 int ExpandScratchPad(unsigned int page);
35 
36 static const struct SyscallPatchData SyscallPatchData[]={
37  { 0x55, &PutTLBEntry},
38  { 0x56, &SetTLBEntry},
39  { 0x57, &GetTLBEntry},
40  { 0x58, &ProbeTLBEntry},
41  { 0x59, &ExpandScratchPad},
42  { 0x03, &_kExecArg},
43 };
44 
45 int _start(int syscall) __attribute__((section(".start")));
46 
47 /* 0x80075000 */
48 int _start(int syscall){
49  unsigned int i;
50 
51  for(i=0; i<6; i++){
53  return((unsigned int)SyscallPatchData[i].function);
54  }
55  }
56 
57  return 0;
58 }
59 
60 /* 0x80075038 */
61 int PutTLBEntry(unsigned int PageMask, unsigned int EntryHi, unsigned int EntryLo0, unsigned int EntryLo1){
62  int result;
63 
64  switch(EntryHi>>24){
65  case 0x40:
66  case 0x30:
67  case 0x20:
68  case 0x00:
69  __asm volatile( "mtc0 %1, $5\n"
70  "mtc0 %2, $10\n"
71  "mtc0 %3, $2\n"
72  "mtc0 %4, $3\n"
73  "sync.p\n"
74  "tlbwr\n"
75  "sync.p\n"
76  "tlbp\n"
77  "sync.p\n"
78  "mfc0 %0, $0\n" :"=r"(result):"r"(PageMask),"r"(EntryHi),"r"(EntryLo0),"r"(EntryLo1));
79  break;
80  case 0x50:
81  case 0x10:
82  default: //SP193: I don't remember seeing a default case. Anyway... Keeping Compilers Happy (TM).
83  result=-1;
84  }
85 
86  return result;
87 }
88 
89 /* 0x800750c8 */
90 int SetTLBEntry(unsigned int index, unsigned int PageMask, unsigned int EntryHi, unsigned int EntryLo0, unsigned int EntryLo1){
91  int result;
92 
93  if(index<0x30){
94  __asm volatile( "mtc0 %0, $0\n"
95  "mtc0 %1, $5\n"
96  "mtc0 %2, $10\n"
97  "mtc0 %3, $2\n"
98  "mtc0 %4, $3\n"
99  "sync.p\n"
100  "tlbwi\n"
101  "sync.p\n" ::"r"(index),"r"(PageMask),"r"(EntryHi),"r"(EntryLo0),"r"(EntryLo1));
102 
103  result=index;
104  }
105  else result=-1;
106 
107  return result;
108 }
109 
110 /* 0x80075108 */
111 int GetTLBEntry(unsigned int index, unsigned int *PageMask, unsigned int *EntryHi, unsigned int *EntryLo0, unsigned int *EntryLo1){
112  int result;
113 
114  if(index<0x30){
115  __asm volatile( "mtc0 %0, $0\n"
116  "sync.p\n"
117  "tlbr\n"
118  "sync.p\n"
119  "mfc0 $v0, $5\n"
120  "sw $v0, (%1)\n"
121  "mfc0 $v0, $10\n"
122  "sw $v0, (%2)\n"
123  "mfc0 $v0, $2\n"
124  "sw $v0, (%3)\n"
125  "mfc0 $v0, $3\n"
126  "sw $v0, (%4)\n" ::"r"(index),"r"(PageMask),"r"(EntryHi),"r"(EntryLo0),"r"(EntryLo1));
127 
128  result=index;
129  }
130  else result=-1;
131 
132  return result;
133 }
134 
135 /* 0x80075158 */
136 int ProbeTLBEntry(unsigned int EntryHi, unsigned int *PageMask, unsigned int *EntryLo0, unsigned int *EntryLo1){
137  int result, index;
138 
139  __asm volatile( "mtc0 %1, $10\n"
140  "sync.p\n"
141  "tlbp\n"
142  "sync.p\n"
143  "mfc0 %0, $0\n" :"=r"(index):"r"(EntryHi));
144 
145  if(index>=0){
146  __asm volatile( "tlbr\n"
147  "sync.p\n"
148  "mfc0 $v0, $5\n"
149  "sw $v0, (%0)\n"
150  "mfc0 $v1, $2\n"
151  "sw $v1, (%1)\n"
152  "mfc0 $v0, $3\n"
153  "sw $v0, (%2)\n" ::"r"(PageMask),"r"(EntryLo0),"r"(EntryLo1));
154 
155  result=index;
156  }
157  else result=-1;
158 
159  return result;
160 }
161 
162 /* 0x800751a8 */
163 int ExpandScratchPad(unsigned int page){
164  int result, index;
165  unsigned int PageMask, EntryHi, EntryLo0, EntryLo1;
166 
167  if(!(page&0xFFF)){
168  if(0xFFFFE<page-1){
169  if((index=ProbeTLBEntry(0x70004000, &PageMask, &EntryLo0, &EntryLo1))>=0){
170  if(page==0){
171  EntryHi=0xE0010000+((index-1)<<13);
172 
173  __asm volatile( "mfc0 $v0, $6\n"
174  "addiu $v0, $v0, 0xFFFF\n"
175  "mtc0 $v0, $6\n"
176  "mtc0 %0, $0\n"
177  "mtc0 $zero, $5\n"
178  "mtc0 %1, $10\n"
179  "mtc0 $zero, $2\n"
180  "mtc0 $zero, $3\n"
181  "sync.p\n"
182  "tlbwi\n"
183  "sync.p\n" ::"r"(index),"r"(EntryHi));
184  }
185  else{
186  __asm volatile( "mfc0 %0, $6\n"
187  "addiu $v0, %0, 1\n"
188  "mtc0 $v0, $6\n" ::"r"(index));
189  }
190  }
191 
192  if(page!=0){
193  /* Not sure why this code saves the EntryLo0 and EntryLo1 values on the stack, and sets a word on the stack to zero, but does not use them:
194 
195  0($sp)=0
196  4($sp)=$v0=(page+0x1000&0xFFFFF000)>>6|0x1F
197  8($sp)=$a0=(page&0xFFFFF000)>>6|0x1F */
198 
199  EntryHi=0x70004000;
200  EntryLo0=((page+0x1000)&0xFFFFF000)>>6|0x1F;
201  EntryLo1=(page&0xFFFFF000)>>6|0x1F;
202 
203  __asm volatile( "mtc0 %0, $0\n"
204  "daddu $v1, $zero, $zero\n"
205  "mtc0 $v1, $5\n"
206  "mtc0 %1, $10\n"
207  "mtc0 %2, $2\n"
208  "mtc0 %3, $3\n"
209  "sync.p\n"
210  "tlbwi\n"
211  "sync.p\n" ::"r"(index),"r"(EntryHi),"r"(EntryLo0),"r"(EntryLo1));
212 
213  result=index;
214  }
215  else result=0;
216  }
217  else result=-1;
218  }
219  else result=-1;
220 
221  return result;
222 }
223 
s32 index
Definition: libpad.c:194
s32 result
Definition: rpc_client.c:23
unsigned int syscall
Definition: osdsrc.c:17
#define NULL
Definition: tamtypes.h:91
int GetTLBEntry(unsigned int index, unsigned int *PageMask, unsigned int *EntryHi, unsigned int *EntryLo0, unsigned int *EntryLo1)
Definition: tlbsrc.c:111
char * _kExecArg[]
Definition: tlbsrc.c:26
int ProbeTLBEntry(unsigned int EntryHi, unsigned int *PageMask, unsigned int *EntryLo0, unsigned int *EntryLo1)
Definition: tlbsrc.c:136
int PutTLBEntry(unsigned int PageMask, unsigned int EntryHi, unsigned int EntryLo0, unsigned int EntryLo1)
Definition: tlbsrc.c:61
int SetTLBEntry(unsigned int index, unsigned int PageMask, unsigned int EntryHi, unsigned int EntryLo0, unsigned int EntryLo1)
Definition: tlbsrc.c:90
int _start(int syscall)
Definition: tlbsrc.c:48
int ExpandScratchPad(unsigned int page)
Definition: tlbsrc.c:163