PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
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
15static int InitTLB32MB(void);
16
17struct SyscallData
18{
19 int syscall;
20 void *function;
21};
22
23static 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
34extern char **_kExecArg;
35
36extern unsigned char tlbsrc[];
37extern unsigned int size_tlbsrc;
38
39void *GetEntryAddress(int syscall);
40void setup(int syscall, void *function);
41
42__attribute__((weak))
43void 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
61void InitTLB(void)
62{
63 if (GetMemorySize() == 0x2000000) {
64 InitTLB32MB();
65 } else {
66 _InitTLB();
67 }
68}
69
71{
72 unsigned int PageMask;
73 unsigned int EntryHi;
74 unsigned int EntryLo0;
75 unsigned int EntryLo1;
76};
77
78struct 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
98static 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
113static 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
133static 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
143static struct TLBInfo TLBInfo = {TLB_NUM_KERNEL_ENTRIES, TLB_NUM_DEFAULT_ENTRIES, TLB_NUM_EXTENDED_ENTRIES, 0, kernelTLB, defaultTLB, extendTLB};
144
145static 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 __asm volatile("mtc0 $zero, $6\n"
153 "sync.p\n");
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 __asm volatile("mtc0 %0, $6\n"
175 "sync.p\n" ::"r"(NumTlbEntries));
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}
Definition tlbfunc.c:71