xerpi

3DS secondary bootup

Dec 23rd, 2017
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
Add Comment
Please, Sign In to add comment