Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- CPU2/CPU3 bootup code: sub_FFF2EC68
- CPU1 entrypoint: 0x1FFAE064; CPU2/CPU3 entrypoint at: 0x1FFAE490, 0xFFF2E490
- // CPU2/3 startup routine
- void sub_FFF2E490()
- {
- int cpu_id;
- u32 val;
- __asm__ volatile {
- "cpsid aif\nt"
- };
- __mrc(0xF, &val, 0xF, 0xC, 0); // Read Performance Monitor Control Register
- val |= 0xFFFF00D;
- __mcr(0xF, val, 0xF, 0xC, 0);
- 0x17E00100 = 1; // Enable interrupts
- cpu_id = __mrc(0xF, 0, 0, 0, 5) & 3;
- /* Tell the CPU0 we are here */
- if (cpu_id == 3)
- 0x10141313 = 1;
- else
- 0x10141312 = 1;
- do {
- __wfi();
- 0x17E00110 = 0x17E0010C; // ack interrupt
- } while (0x17E0010C != cpu_id);
- JUMPOUT(0x1FFAE064);
- }
- // a1: enable_SMP?
- int sub_FFF2EC68(int a1)
- {
- int v1; // r8@1
- signed int v2; // r10@4
- signed int v3; // r0@16
- int v4; // r0@24
- signed int v5; // r3@25
- signed int v6; // r9@27
- unsigned int v7; // r1@42
- int result; // r0@44
- signed int v9; // r0@47
- signed int v10; // r2@47
- signed int v11; // r1@47
- int v12; // t1@48
- v1 = a1;
- if (!a1) {
- if ((0x10140FFC & 0b10) >> 1) { // If we have more than 2 CPUs..
- if ((0x10140FFC & 0b100) >> 2) // If 4 CPUs
- v2 = 0b101;
- else // If 3 CPUs
- v2 = 0b011;
- if ((0x10141300 & 0b111) != v2) {
- 0x10141304 |= 1; // Power on 3rd ARM11 MPCore
- if ((0x10140FFC & 0b100) >> 2) // If 4 CPUs
- 0x10141304 |= 0x100; // Power on 4rd ARM11 MPCore
- sub_FFF2E454(0x193); // delay
- 0x17E00100 = 1; // enable interrupts
- 0x17E01288 = 0x1000000; // Interrupt Pending clear Registers
- 0x10141300 = v2 & 0b111 | 0x8000; // enable clk mult, clk=2x, busy=1
- 0x17E01458 = 0; // Interrupt Priority Registers
- 0x17E01858 |= 1; // Interrupt CPU targets Registers
- 0x17E01108 = 0x1000000; // Interrupt Enable set Registers ID0-ID31
- do {
- __wfi();
- } while (!(0x10141300 & 0x8000)); // While PDN_MPCORE_CLKCNT busy
- 0x17E01188 = 0x1000000; //Interrupt Enable set Registers ID32 and upwards
- 0x10140400 = 3; // CLK_UNK1
- }
- 0x10140410 = 0x3FFFF; // CLK_UNK2
- }
- /* Start shit */
- 0x1FFFFFF0 = 1;
- while (0x1FFFFFF0 != 2) ;
- 0x1FFFFFF0 = 3;
- 0x1FFAF405 = 0x1FFFFFF1;
- 0x1FFAF406 = 0x1FFFFFF2;
- if (0x1FFFFFF1 == 3) {
- v3 = 0;
- do
- ++v3;
- while (v3 < 0x800000);
- 0x1FFFFFF0 = 1;
- while (0x1FFFFFF0 != 2) ;
- 0x1FFFFFF0 = 3;
- }
- /* End shit */
- if ((0x10140FFC & 2) >> 1 && (0x17E00004 & 3) == 3) { // If we have 4 CPUs
- 0x17E00008 &= 0xFFFFFF0F; // SCU power on CPU2 and CPU3
- v4 = 0x10141300 & 0b111;
- if ((0x10140FFC & 0b100) >> 2) // If 4 CPUs
- v5 = 1;
- else
- v5 = 2;
- v6 = 1 << v1;
- if (v4 != v5) {
- 0x17E00100 = 1; // enable interrupts
- 0x17E01288 = 0x1000000;
- 0x10141300 = v5 & 0b111 | 0x8000; // enable clk mult, clk=1x, busy=1
- 0x17E01458 = 0;
- 0x17E01858 |= v6;
- 0x17E01108 = 0x1000000;
- do {
- __wfi();
- } while (!(0x10141300 & 0x8000)); // While PDN_MPCORE_CLKCNT busy
- 0x17E01188 = 0x1000000;
- }
- 0x10140420 |= 1; // Enable bootrom overlay
- 0x10140424 = 0x1FFAE490; // Set CPU2/3 entrypoint (overlay value)
- if (!(0x10141312 & 0x10)) { // If CPU2 has not booted
- 0x10141312 |= 2; // Enable CPU2 bootrom data overlay?
- 0x10141312 |= 1; // Enable CPU2 bootrom instruction overlay
- }
- if (!(0x10141313 & 0x10)) { // If CPU3 has not booted
- 0x10141313 |= 2; // Enable CPU3 bootrom data overlay?
- 0x10141313 |= 1; // Enable CPU3 bootrom instruction overlay
- }
- /* Wait until CPU2 is online */
- while ((0x10141312 & 0x12) != 0x10)
- ;
- /* Wait until CPU3 is online */
- while ((0x10141313 & 0x12) != 0x10)
- ;
- 0x10140420 &= 0xFE; // Disable bootrom overlay
- if (v4 != v5) {
- 0x17E00100 = 1;
- 0x17E01288 = 0x1000000;
- 0x10141300 = v4 & 0b111 | 0x8000; // enable clk mult, clk=orignal state, busy=1
- 0x17E01458 = 0;
- 0x17E01858 |= v6;
- 0x17E01108 = 0x1000000;
- do {
- __wfi();
- } while (!(0x10141300 & 0x8000));
- 0x17E01188 = 0x1000000;
- }
- }
- 0x1FFFFFDC = 0x1FFAE064; // CPU1 entrypoint
- }
- v7 = *(_DWORD *) (4 * v1 + 0x1FFAF3C4);
- __mcr(15, 0, 0, 8, 7, 0);
- __mcr(15, 0, (v7 >> 9 << 9) | 0x12, 2, 0, 0);
- __mcr(15, 0, (v7 >> 14 << 14) | 0x12, 2, 0, 1);
- __mcr(15, 0, 2u, 2, 0, 2);
- __mcr(15, 0, 0, 13, 0, 1);
- __mcr(15, 0, 1u, 3, 0, 0);
- sub_FFF2E594();
- if (!v1)
- 0x17E00000 |= 1; // Enable SCU
- // Rest is 3DS shit...
- __mcr(15, 0, __mrc(15, 0, 1, 0, 1) | 0x2F, 1, 0, 1);
- result = __mrc(15, 0, 1, 0, 0) | 0xC03805;
- __mcr(15, 0, result, 1, 0, 0);
- __mcr(15, 0, 0, 7, 5, 4);
- __mcr(15, 0, 0, 7, 5, 0);
- __mcr(15, 0, 0, 7, 6, 0);
- __mcr(15, 0, 0, 8, 7, 0);
- __mcr(15, 0, 0, 7, 10, 5);
- __mcr(15, 0, 0, 7, 5, 4);
- if (!v1) {
- *0x1FFAF40C = *0x1FFAF40C & 0xFC6FEBFF | 0x2800000;
- *0x1FFAF420 = *0x1FFAF420 & 0xF65FFFE1 | 0x70000001;
- *0x1FFAF424 &= 0xFFFFFFFC;
- *0x1FFAF410 |= 0x1FFu;
- *0x1FFAF418 = 0xFFFF;
- while (*0x1FFAF414 & 1) ;
- *0x1FFAF414 = 0;
- *0x1FFAF408 |= 1u;
- v9 = 536821756;
- v10 = 536530940;
- v11 = 512;
- do {
- --v11;
- *(_DWORD *) (v9 + 4) = *(_DWORD *) (v10 + 4);
- v12 = *(_DWORD *) (v10 + 8);
- v10 += 8;
- *(_DWORD *) (v9 + 8) = v12;
- v9 += 8;
- }
- while (v11);
- if (0x1FFED000u << 20)
- __breakpoint(89);
- if (0x1FFEC000u << 20)
- __breakpoint(90);
- ((void (*)(void))sub_FFF2F2CC) ();
- sub_FFF2F2CC(0x1FFEC000u, 536547328, 0x1000u);
- sub_FFF2F2CC(0x1FFEC000 - (unsigned __int16)&sub_FFF2D000,
- 0x1FFAD000u >> 16 << 16,
- (unsigned __int16)&sub_FFF2D000);
- __mcr(15, 0, 0, 7, 10, 0);
- __mcr(15, 0, 0, 7, 10, 4);
- *0x1FFAF41C = 0xFFFF;
- result = 0x1FFAF414;
- while (*0x1FFAF414 & 1) ;
- *0x1FFAF414 = 0;
- }
- __mcr(15, 0, 0, 7, 14, 0);
- __mcr(15, 0, 0, 7, 10, 5);
- __mcr(15, 0, 0, 7, 5, 0);
- __mcr(15, 0, 0, 7, 5, 6);
- __mcr(15, 0, 0, 7, 10, 4);
- __mcr(15, 0, 0, 7, 5, 4);
- return result;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement