PS2SDK
PS2 Homebrew Libraries
tlbfunc.c
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 <stdio.h>
12 
13 #define kprintf(args...) // sio_printf(args)
14 
15 static int InitTLB32MB(void);
16 
17 struct SyscallData
18 {
19  int syscall;
20  void *function;
21 };
22 
23 static const struct SyscallData SysEntry[] = {
24  {0x5A, &kCopy},
25  {0x5B, (void *)0x80075000},
26  {0x54, NULL}, // ???
27  {0x55, NULL}, // PutTLBEntry
28  {0x56, NULL}, // SetTLBEntry
29  {0x57, NULL}, // GetTLBEntry
30  {0x58, NULL}, // ProbeTLBEntry
31  {0x59, NULL}, // ExpandScratchPad
32 };
33 
34 extern char **_kExecArg;
35 
36 extern unsigned char tlbsrc[];
37 extern unsigned int size_tlbsrc;
38 
39 void *GetEntryAddress(int syscall);
40 void setup(int syscall, void *function);
41 
42 __attribute__((weak))
43 void InitTLBFunctions(void)
44 {
45  int i;
46 
47  setup(SysEntry[0].syscall, SysEntry[0].function);
48  Copy((void *)0x80075000, tlbsrc, size_tlbsrc);
49  FlushCache(0);
50  FlushCache(2);
51  setup(SysEntry[1].syscall, SysEntry[1].function);
52 
53  for (i = 3; i < 8; i++) {
54  setup(SysEntry[i].syscall, GetEntryAddress(SysEntry[i].syscall));
55  }
56 
57  _kExecArg = GetEntryAddress(3);
58 }
59 
61 void InitTLB(void)
62 {
63  if (GetMemorySize() == 0x2000000) {
64  InitTLB32MB();
65  } else {
66  _InitTLB();
67  }
68 }
69 
70 struct TLBEntry
71 {
72  unsigned int PageMask;
73  unsigned int EntryHi;
74  unsigned int EntryLo0;
75  unsigned int EntryLo1;
76 };
77 
78 struct TLBInfo
79 {
80  unsigned int NumKernelTLBEntries;
81  unsigned int NumDefaultTLBEntries;
82  unsigned int NumExtendedTLBEntries;
83  unsigned int NumWiredEntries;
84  const struct TLBEntry *kernelTLB;
85  const struct TLBEntry *defaultTLB;
86  const struct TLBEntry *extendedTLB;
87 };
88 
89 #define TLB_NUM_KERNEL_ENTRIES 0x0D
90 #define TLB_NUM_DEFAULT_ENTRIES 0x12
91 #define TLB_NUM_EXTENDED_ENTRIES 0x08
92 
93 // Compile-time sanity checks.
94 #if (TLB_NUM_KERNEL_ENTRIES + TLB_NUM_DEFAULT_ENTRIES + TLB_NUM_EXTENDED_ENTRIES >= 0x31)
95 #error TLB over flow
96 #endif
97 
98 static const struct TLBEntry kernelTLB[TLB_NUM_KERNEL_ENTRIES] = {
99  {0x00000000, 0x70000000, 0x80000007, 0x00000007},
100  {0x00006000, 0xFFFF8000, 0x00001E1F, 0x00001F1F},
101  {0x00000000, 0x10000000, 0x00400017, 0x00400053},
102  {0x00000000, 0x10002000, 0x00400097, 0x004000D7},
103  {0x00000000, 0x10004000, 0x00400117, 0x00400157},
104  {0x00000000, 0x10006000, 0x00400197, 0x004001D7},
105  {0x00000000, 0x10008000, 0x00400217, 0x00400257},
106  {0x00000000, 0x1000A000, 0x00400297, 0x004002D7},
107  {0x00000000, 0x1000C000, 0x00400313, 0x00400357},
108  {0x00000000, 0x1000E000, 0x00400397, 0x004003D7},
109  {0x0001E000, 0x11000000, 0x00440017, 0x00440415},
110  {0x0001E000, 0x12000000, 0x00480017, 0x00480415},
111  {0x01FFE000, 0x1E000000, 0x00780017, 0x007C0017}};
112 
113 static const struct TLBEntry defaultTLB[TLB_NUM_DEFAULT_ENTRIES] = {
114  {0x0007E000, 0x00080000, 0x0000201F, 0x0000301F},
115  {0x0007E000, 0x00100000, 0x0000401F, 0x0000501F},
116  {0x0007E000, 0x00180000, 0x0000601F, 0x0000701F},
117  {0x001FE000, 0x00200000, 0x0000801F, 0x0000C01F},
118  {0x001FE000, 0x00400000, 0x0001001F, 0x0001401F},
119  {0x001FE000, 0x00600000, 0x0001801F, 0x0001C01F},
120  {0x007FE000, 0x00800000, 0x0002001F, 0x0003001F},
121  {0x007FE000, 0x01000000, 0x0004001F, 0x0005001F},
122  {0x007FE000, 0x01800000, 0x0006001F, 0x0007001F},
123  {0x0007E000, 0x20080000, 0x00002017, 0x00003017},
124  {0x0007E000, 0x20100000, 0x00004017, 0x00005017},
125  {0x0007E000, 0x20180000, 0x00006017, 0x00007017},
126  {0x001FE000, 0x20200000, 0x00008017, 0x0000C017},
127  {0x001FE000, 0x20400000, 0x00010017, 0x00014017},
128  {0x001FE000, 0x20600000, 0x00018017, 0x0001C017},
129  {0x007FE000, 0x20800000, 0x00020017, 0x00030017},
130  {0x007FE000, 0x21000000, 0x00040017, 0x00050017},
131  {0x007FE000, 0x21800000, 0x00060017, 0x00070017}};
132 
133 static const struct TLBEntry extendTLB[TLB_NUM_EXTENDED_ENTRIES] = {
134  {0x0007E000, 0x30100000, 0x0000403F, 0x0000503F},
135  {0x0007E000, 0x30180000, 0x0000603F, 0x0000703F},
136  {0x001FE000, 0x30200000, 0x0000803F, 0x0000C03F},
137  {0x001FE000, 0x30400000, 0x0001003F, 0x0001403F},
138  {0x001FE000, 0x30600000, 0x0001803F, 0x0001C03F},
139  {0x007FE000, 0x30800000, 0x0002003F, 0x0003003F},
140  {0x007FE000, 0x31000000, 0x0004003F, 0x0005003F},
141  {0x007FE000, 0x31800000, 0x0006003F, 0x0007003F}};
142 
143 static struct TLBInfo TLBInfo = {TLB_NUM_KERNEL_ENTRIES, TLB_NUM_DEFAULT_ENTRIES, TLB_NUM_EXTENDED_ENTRIES, 0, kernelTLB, defaultTLB, extendTLB};
144 
145 static int InitTLB32MB(void)
146 {
147  unsigned int i, NumTlbEntries, value, TlbEndIndex;
148  const struct TLBEntry *TLBEntry;
149 
150  kprintf("# TLB spad=0 kernel=1:%d default=%d:%d extended=%d:%d\n", TLBInfo.NumKernelTLBEntries - 1, TLBInfo.NumKernelTLBEntries, TLBInfo.NumKernelTLBEntries + TLBInfo.NumDefaultTLBEntries - 1, TLBInfo.NumKernelTLBEntries + TLBInfo.NumDefaultTLBEntries, TLBInfo.NumKernelTLBEntries + TLBInfo.NumDefaultTLBEntries + TLBInfo.NumExtendedTLBEntries - 1);
151 
152  set_mips_cop_reg(0, COP0_REG_Wired, 0);
153  EE_SYNCP();
154 
155  if (TLBInfo.NumKernelTLBEntries >= 0x31) {
156  kprintf("# TLB over flow (1)");
157  Exit(1);
158  }
159 
160  for (i = 0, TLBEntry = TLBInfo.kernelTLB; i < TLBInfo.NumKernelTLBEntries; i++, TLBEntry++) {
161  _SetTLBEntry(i, TLBEntry->PageMask, TLBEntry->EntryHi, TLBEntry->EntryLo0, TLBEntry->EntryLo1);
162  }
163 
164  if (TLBInfo.NumDefaultTLBEntries + i >= 0x31) {
165  kprintf("# TLB over flow (2)");
166  Exit(1);
167  }
168 
169  for (TLBEntry = TLBInfo.defaultTLB, TlbEndIndex = TLBInfo.NumDefaultTLBEntries + i; i < TlbEndIndex; i++, TLBEntry++) {
170  _SetTLBEntry(i, TLBEntry->PageMask, TLBEntry->EntryHi, TLBEntry->EntryLo0, TLBEntry->EntryLo1);
171  }
172 
173  TLBInfo.NumWiredEntries = NumTlbEntries = i;
174  set_mips_cop_reg(0, COP0_REG_Wired, NumTlbEntries);
175  EE_SYNCP();
176 
177  if (TLBInfo.NumExtendedTLBEntries > 0) {
178  if (TLBInfo.NumExtendedTLBEntries + i >= 0x31) {
179  kprintf("# TLB over flow (3)");
180  Exit(1);
181  }
182 
183  for (TLBEntry = TLBInfo.extendedTLB, TlbEndIndex = TLBInfo.NumExtendedTLBEntries + i; i < TlbEndIndex; i++, TLBEntry++, NumTlbEntries++) {
184  _SetTLBEntry(i, TLBEntry->PageMask, TLBEntry->EntryHi, TLBEntry->EntryLo0, TLBEntry->EntryLo1);
185  }
186  }
187 
188  for (value = 0xE0000000 + (NumTlbEntries << 13); i < 0x30; i++, value += 0x2000) {
189  _SetTLBEntry(i, 0, value, 0, 0);
190  }
191 
192  return NumTlbEntries;
193 }
kernel.h
TLBEntry
Definition: tlbfunc.c:70
SyscallData
Definition: alarm.c:22
__attribute__
typedef __attribute__
Definition: tlbfunc.c:60
stdio.h
TLBInfo
Definition: tlbfunc.c:78
COP0_REG_Wired
@ COP0_REG_Wired
Definition: mipscopaccess.h:26