SHOW:
|
|
- or go back to the newest paste.
1 | CPU2/CPU3 bootup code: sub_FFF2EC68 | |
2 | CPU1 entrypoint: 0x1FFAE064; CPU2/CPU3 entrypoint at: 0x1FFAE490, 0xFFF2E490 | |
3 | ||
4 | // CPU2/3 startup routine | |
5 | void sub_FFF2E490() | |
6 | { | |
7 | int cpu_id; | |
8 | u32 val; | |
9 | ||
10 | __asm__ volatile { | |
11 | "cpsid aif\nt" | |
12 | }; | |
13 | ||
14 | __mrc(0xF, &val, 0xF, 0xC, 0); // Read Performance Monitor Control Register | |
15 | val |= 0xFFFF00D; | |
16 | __mcr(0xF, val, 0xF, 0xC, 0); | |
17 | ||
18 | 0x17E00100 = 1; // Enable interrupts | |
19 | ||
20 | cpu_id = __mrc(0xF, 0, 0, 0, 5) & 3; | |
21 | ||
22 | /* Tell the CPU0 we are here */ | |
23 | if (cpu_id == 3) | |
24 | 0x10141313 = 1; | |
25 | else | |
26 | 0x10141312 = 1; | |
27 | ||
28 | do { | |
29 | __wfi(); | |
30 | 0x17E00110 = 0x17E0010C; // ack interrupt | |
31 | } while (0x17E0010C != cpu_id); | |
32 | ||
33 | JUMPOUT(0x1FFAE064); | |
34 | } | |
35 | ||
36 | // a1: enable_SMP? | |
37 | int sub_FFF2EC68(int a1) | |
38 | { | |
39 | int v1; // r8@1 | |
40 | signed int v2; // r10@4 | |
41 | signed int v3; // r0@16 | |
42 | int v4; // r0@24 | |
43 | signed int v5; // r3@25 | |
44 | signed int v6; // r9@27 | |
45 | unsigned int v7; // r1@42 | |
46 | int result; // r0@44 | |
47 | signed int v9; // r0@47 | |
48 | signed int v10; // r2@47 | |
49 | signed int v11; // r1@47 | |
50 | int v12; // t1@48 | |
51 | ||
52 | v1 = a1; | |
53 | if (!a1) { | |
54 | if ((0x10140FFC & 0b10) >> 1) { // If we have more than 2 CPUs.. | |
55 | if ((0x10140FFC & 0b100) >> 2) // If 4 CPUs | |
56 | v2 = 0b101; | |
57 | else // If 3 CPUs | |
58 | v2 = 0b011; | |
59 | ||
60 | if ((0x10141300 & 0b111) != v2) { | |
61 | 0x10141304 |= 1; // Power on 3rd ARM11 MPCore | |
62 | if ((0x10140FFC & 0b100) >> 2) // If 4 CPUs | |
63 | 0x10141304 |= 0x100; // Power on 4rd ARM11 MPCore | |
64 | ||
65 | sub_FFF2E454(0x193); // delay | |
66 | ||
67 | 0x17E00100 = 1; // enable interrupts | |
68 | 0x17E01288 = 0x1000000; // Interrupt Pending clear Registers | |
69 | ||
70 | 0x10141300 = v2 & 0b111 | 0x8000; // enable clk mult, clk=2x, busy=1 | |
71 | ||
72 | 0x17E01458 = 0; // Interrupt Priority Registers | |
73 | 0x17E01858 |= 1; // Interrupt CPU targets Registers | |
74 | 0x17E01108 = 0x1000000; // Interrupt Enable set Registers ID0-ID31 | |
75 | ||
76 | do { | |
77 | __wfi(); | |
78 | } while (!(0x10141300 & 0x8000)); // While PDN_MPCORE_CLKCNT busy | |
79 | ||
80 | 0x17E01188 = 0x1000000; //Interrupt Enable set Registers ID32 and upwards | |
81 | ||
82 | 0x10140400 = 3; // CLK_UNK1 | |
83 | } | |
84 | 0x10140410 = 0x3FFFF; // CLK_UNK2 | |
85 | } | |
86 | ||
87 | /* Start shit */ | |
88 | 0x1FFFFFF0 = 1; | |
89 | while (0x1FFFFFF0 != 2) ; | |
90 | 0x1FFFFFF0 = 3; | |
91 | 0x1FFAF405 = 0x1FFFFFF1; | |
92 | 0x1FFAF406 = 0x1FFFFFF2; | |
93 | if (0x1FFFFFF1 == 3) { | |
94 | v3 = 0; | |
95 | do | |
96 | ++v3; | |
97 | while (v3 < 0x800000); | |
98 | 0x1FFFFFF0 = 1; | |
99 | while (0x1FFFFFF0 != 2) ; | |
100 | 0x1FFFFFF0 = 3; | |
101 | } | |
102 | /* End shit */ | |
103 | ||
104 | if ((0x10140FFC & 2) >> 1 && (0x17E00004 & 3) == 3) { // If we have 4 CPUs | |
105 | 0x17E00008 &= 0xFFFFFF0F; // SCU power on CPU2 and CPU3 | |
106 | ||
107 | v4 = 0x10141300 & 0b111; | |
108 | if ((0x10140FFC & 0b100) >> 2) // If 4 CPUs | |
109 | v5 = 1; | |
110 | else | |
111 | v5 = 2; | |
112 | ||
113 | v6 = 1 << v1; | |
114 | if (v4 != v5) { | |
115 | 0x17E00100 = 1; // enable interrupts | |
116 | 0x17E01288 = 0x1000000; | |
117 | 0x10141300 = v5 & 0b111 | 0x8000; // enable clk mult, clk=1x, busy=1 | |
118 | 0x17E01458 = 0; | |
119 | 0x17E01858 |= v6; | |
120 | 0x17E01108 = 0x1000000; | |
121 | do { | |
122 | __wfi(); | |
123 | } while (!(0x10141300 & 0x8000)); // While PDN_MPCORE_CLKCNT busy | |
124 | 0x17E01188 = 0x1000000; | |
125 | } | |
126 | ||
127 | 0x10140420 |= 1; // Enable bootrom overlay | |
128 | 0x10140424 = 0x1FFAE490; // Set CPU2/3 entrypoint (overlay value) | |
129 | ||
130 | if (!(0x10141312 & 0x10)) { // If CPU2 has not booted | |
131 | 0x10141312 |= 2; // Enable CPU2 bootrom data overlay? | |
132 | 0x10141312 |= 1; // Enable CPU2 bootrom instruction overlay | |
133 | } | |
134 | if (!(0x10141313 & 0x10)) { // If CPU3 has not booted | |
135 | 0x10141313 |= 2; // Enable CPU3 bootrom data overlay? | |
136 | 0x10141313 |= 1; // Enable CPU3 bootrom instruction overlay | |
137 | } | |
138 | ||
139 | /* Wait until CPU2 is online */ | |
140 | while ((0x10141312 & 0x12) != 0x10) | |
141 | ; | |
142 | ||
143 | /* Wait until CPU3 is online */ | |
144 | while ((0x10141313 & 0x12) != 0x10) | |
145 | ; | |
146 | ||
147 | 0x10140420 &= 0xFE; // Disable bootrom overlay | |
148 | ||
149 | if (v4 != v5) { | |
150 | 0x17E00100 = 1; | |
151 | 0x17E01288 = 0x1000000; | |
152 | 0x10141300 = v4 & 0b111 | 0x8000; // enable clk mult, clk=orignal state, busy=1 | |
153 | 0x17E01458 = 0; | |
154 | 0x17E01858 |= v6; | |
155 | 0x17E01108 = 0x1000000; | |
156 | do { | |
157 | __wfi(); | |
158 | } while (!(0x10141300 & 0x8000)); | |
159 | 0x17E01188 = 0x1000000; | |
160 | } | |
161 | } | |
162 | 0x1FFFFFDC = 0x1FFAE064; // CPU1 entrypoint | |
163 | } | |
164 | v7 = *(_DWORD *) (4 * v1 + 0x1FFAF3C4); | |
165 | __mcr(15, 0, 0, 8, 7, 0); | |
166 | __mcr(15, 0, (v7 >> 9 << 9) | 0x12, 2, 0, 0); | |
167 | __mcr(15, 0, (v7 >> 14 << 14) | 0x12, 2, 0, 1); | |
168 | __mcr(15, 0, 2u, 2, 0, 2); | |
169 | __mcr(15, 0, 0, 13, 0, 1); | |
170 | __mcr(15, 0, 1u, 3, 0, 0); | |
171 | sub_FFF2E594(); | |
172 | ||
173 | if (!v1) | |
174 | 0x17E00000 |= 1; // Enable SCU | |
175 | ||
176 | // Rest is 3DS shit... | |
177 | ||
178 | __mcr(15, 0, __mrc(15, 0, 1, 0, 1) | 0x2F, 1, 0, 1); | |
179 | result = __mrc(15, 0, 1, 0, 0) | 0xC03805; | |
180 | __mcr(15, 0, result, 1, 0, 0); | |
181 | __mcr(15, 0, 0, 7, 5, 4); | |
182 | __mcr(15, 0, 0, 7, 5, 0); | |
183 | __mcr(15, 0, 0, 7, 6, 0); | |
184 | __mcr(15, 0, 0, 8, 7, 0); | |
185 | __mcr(15, 0, 0, 7, 10, 5); | |
186 | __mcr(15, 0, 0, 7, 5, 4); | |
187 | if (!v1) { | |
188 | *0x1FFAF40C = *0x1FFAF40C & 0xFC6FEBFF | 0x2800000; | |
189 | *0x1FFAF420 = *0x1FFAF420 & 0xF65FFFE1 | 0x70000001; | |
190 | *0x1FFAF424 &= 0xFFFFFFFC; | |
191 | *0x1FFAF410 |= 0x1FFu; | |
192 | *0x1FFAF418 = 0xFFFF; | |
193 | while (*0x1FFAF414 & 1) ; | |
194 | *0x1FFAF414 = 0; | |
195 | *0x1FFAF408 |= 1u; | |
196 | v9 = 536821756; | |
197 | v10 = 536530940; | |
198 | v11 = 512; | |
199 | do { | |
200 | --v11; | |
201 | *(_DWORD *) (v9 + 4) = *(_DWORD *) (v10 + 4); | |
202 | v12 = *(_DWORD *) (v10 + 8); | |
203 | v10 += 8; | |
204 | *(_DWORD *) (v9 + 8) = v12; | |
205 | v9 += 8; | |
206 | } | |
207 | while (v11); | |
208 | if (0x1FFED000u << 20) | |
209 | __breakpoint(89); | |
210 | if (0x1FFEC000u << 20) | |
211 | __breakpoint(90); | |
212 | ((void (*)(void))sub_FFF2F2CC) (); | |
213 | sub_FFF2F2CC(0x1FFEC000u, 536547328, 0x1000u); | |
214 | sub_FFF2F2CC(0x1FFEC000 - (unsigned __int16)&sub_FFF2D000, | |
215 | 0x1FFAD000u >> 16 << 16, | |
216 | (unsigned __int16)&sub_FFF2D000); | |
217 | __mcr(15, 0, 0, 7, 10, 0); | |
218 | __mcr(15, 0, 0, 7, 10, 4); | |
219 | *0x1FFAF41C = 0xFFFF; | |
220 | result = 0x1FFAF414; | |
221 | while (*0x1FFAF414 & 1) ; | |
222 | *0x1FFAF414 = 0; | |
223 | } | |
224 | __mcr(15, 0, 0, 7, 14, 0); | |
225 | __mcr(15, 0, 0, 7, 10, 5); | |
226 | __mcr(15, 0, 0, 7, 5, 0); | |
227 | __mcr(15, 0, 0, 7, 5, 6); | |
228 | __mcr(15, 0, 0, 7, 10, 4); | |
229 | __mcr(15, 0, 0, 7, 5, 4); | |
230 | return result; | |
231 | } |