Advertisement
xerpi

spi.bin RE

Mar 25th, 2016
299
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.37 KB | None | 0 0
  1. //spi.bin RE by xerpi
  2.  
  3. struct spi_msg_old {
  4.     uint32_t baudrate; //0
  5.     uint32_t buffer;   //4 // buffer
  6.     uint32_t size;     //8 // size
  7.     uint8_t device;    //C // device
  8. };
  9.  
  10. // sub_102290 spi.bin
  11. // SPI service 0x50040
  12. // SpiWriteDevice
  13. void spi_write_msg_old_ds(struct spi_msg_old *msg)
  14. {
  15.     uint8_t *spi_data;
  16.     uint8_t *spi_cnt;
  17.  
  18.     uint32_t device = msg->device;
  19.  
  20.     if (msg->device >= 3) { // CS
  21.         device -= 3;
  22.         spi_cnt = 0x1EC42000; // SPI_CNT0
  23.         sign_ext16(r2);
  24.     } else { //CC
  25.         spi_cnt = 0x1EC60000; // spi_data
  26.     }
  27.  
  28.     if (msg->device >= 3)
  29.         spi_data = 0x1EC60002; // SPI_DATA0
  30.     else
  31.         spi_data = 0x1EC42002; // SPI_DATA1
  32.  
  33.  
  34.     uint32_t foo = (device << 8) | (msg->baudrate & 0xFF);
  35.  
  36.     // Chipselect hold (keep selected), SPI bus enable
  37.     *(uint16_t *)spi_cnt = (foo | 0x8800);
  38.  
  39.     int idx = 0; // buffer idx
  40.  
  41.     if (msg->size > 0) {
  42.         do {
  43.             *spi_data = msg->buffer[idx];
  44.  
  45.             while (*(uint16_t *)spi_cnt & 0x80)
  46.                 ;
  47.  
  48.             idx++;
  49.         } while (idx <= msg->size);
  50.     }
  51.  
  52.     // 1 byte left
  53.     *(uint16_t *)spi_cnt = r4;
  54.     *spi_data = msg->buffer[idx];
  55.  
  56.     while (*(uint16_t *)spi_cnt & 0x80)
  57.         ;
  58.  
  59.     return;
  60. }
  61.  
  62. // spi initialized?
  63. static u8 byte_105018[1] = {0};
  64. // Bus on/off
  65. static u8 byte_105019[3] = {0, 0, 0};
  66. // [0-5]:Device status, [6-11]: on/off?
  67. static u8 dword_10501C[4 * 3] = {0};
  68.  
  69. static u8 dword_1050CC[9] = {0};
  70.  
  71. // initializes spi global vars, reads PDN_SPI_CNT status
  72. void sub_1006F0()
  73. {
  74.     if (byte_105018[0] != 0) {
  75.         return;
  76.     }
  77.  
  78.     byte_105018[0] = 1;
  79.  
  80.     int i;
  81.     for (i = 0; i < 6; i++)
  82.         dword_10501C[6 + i] = 0;
  83.  
  84.  
  85.     r5 = dword_1050CC;
  86.     r4 = 0;
  87.     do {
  88.         r0 = r4 + (r4 << 1); //0, 3, 6, 9..
  89.         r0 = &dword_1050CC[r0 * 4];
  90.         { //sub_101DE0();
  91.             r4 = r0;
  92.             sub_101A48(); // stores 1 to r0
  93.             r0 = 0;
  94.             *(uint32_t *)(r4 + 4) = r0;
  95.             *(uint32_t *)(r4 + 8) = r0;
  96.         }
  97.         r4 = r4 + 1;
  98.     } while (r4 < 3);
  99.  
  100.     r3 = *(uint16_t *)(0x1EC401C0);
  101.     if (r3 & 1) {
  102.         byte_105019[0] = 1;
  103.     } else {
  104.         byte_105019[0] = 0;
  105.     }
  106.  
  107.     r3 = *(uint16_t *)(0x1EC401C0);
  108.     r3 = r3 << 30;
  109.  
  110.     if (r3 < 0) {
  111.         byte_105019[1] = 1;
  112.     } else {
  113.         byte_105019[1] = 0;
  114.     }
  115.  
  116.     r2 = *(uint16_t *)(0x1EC401C0);
  117.     r2 = r2 << 29;
  118.  
  119.     if (r2 < 0) {
  120.         byte_105019[2] = 1;
  121.     } else {
  122.         byte_105019[2] = 0;
  123.     }
  124. }
  125.  
  126.  
  127. // r0 = this??
  128. // r1 = device
  129. int SpiWriteDevice(int r0, int device, int r2, int r3)
  130. {
  131.     if (r3 > 4) {
  132.         // error
  133.         r0 = 0xE0E03FFD;
  134.         return;
  135.     }
  136.  
  137.     STMFD SP!, {R4-R7,LR}
  138.  
  139.     uint8_t bus;
  140.     if (device < 6) {
  141.         if (device >= 0 && device <= 2) {
  142.             bus = 0;
  143.         } else if (device >= 3 && device <= 5) {
  144.             bus = 1;
  145.         }
  146.     } else {
  147.         bus = 2;
  148.     }
  149.  
  150.     r5 = dword_1050CC;
  151.  
  152.     r6 = byte_105019 + 9;
  153.     r12 = byte_105019 + 3;
  154.  
  155.     r0 = 0xC8A03FF8;
  156.  
  157.     r6 = *(int8_t *)(r6 + device);
  158.     r12 = *(uint8_t *)(r12 + device);
  159.  
  160.     if (byte_105019[bus] == 0) {
  161.         goto loc_101390;
  162.     }
  163.  
  164.     *(uint8_t *)var_1C = r1;
  165.  
  166.     if (r6 == 0) {
  167.         goto loc_101388;
  168.     }
  169.  
  170.     r0 = r4 + (r4 << 1);
  171.  
  172.     *(uint32_t *)var_28 = r12;
  173.  
  174.     r4 = r5 + (r0 << 2);
  175.     r0 = r4;
  176.  
  177.     *(uint64_t *)var_24 = [r2:r3];
  178.  
  179.     sub_101DA8();
  180.  
  181.     r0 = SP;
  182.     spi_write_msg_new(r0);
  183.  
  184.     r0 = r4;
  185.     sub_101D88();
  186.  
  187. loc_101384:
  188.     r0 = 0;
  189. loc_101388:
  190.     sp += 14;
  191.     LDMFD SP!, {R4-R7,PC}
  192.  
  193. loc_101390:
  194.     *(uint8_t *)var_1C = r1;
  195.     if (r6 == 0) {
  196.         goto loc_101388;
  197.     }
  198.  
  199.     *(uint32_t *)var_28 = r12;
  200.     r4 = r5 + (r0 << 2);
  201.     r0 = r4;
  202.     *(uint64_t *)var_24 = [r2:r3];
  203.  
  204.     sub_101DA8();
  205.  
  206.     r0 = SP;
  207.     spi_write_msg_old_ds();
  208.  
  209.     r0 = r4;
  210.     sub_101D88();
  211.  
  212.     goto loc_101384;
  213. }
  214.  
  215. // r0 = this
  216. // r1 = device
  217. // r2 = on/off
  218. // r3 = status
  219. // SPI service 0x80040
  220. // sub_101428
  221. void SpiEnableSpiBus(int r0, int device, int onoff, int r3)
  222. {
  223.     int bus;
  224.  
  225.     if (device >= 0 && device <= 2)
  226.         bus = 0;
  227.     else if (device >= 3 && device <= 5)
  228.         bus = 1;
  229.     else
  230.         bus = 2;
  231.  
  232.     byte_105019[bus] = onoff;
  233.  
  234.     u16 old = *(uint16_t *)(0x1EC401C0); // PDN_SPI_CNT
  235.     u16 new = 1 << bus;
  236.  
  237.     if (onoff == 0) {
  238.         new = old & ~new;
  239.     } else {
  240.         new = old | new;
  241.     }
  242.  
  243.     *(uint16_t *)(0x1EC401C0) = new;
  244.  
  245.     dword_10501C[device] = r3;
  246.  
  247.     return 0;
  248. }
  249.  
  250. // SPI service 0x10040
  251. // sub_1012B4
  252. int SpiSetDeviceState(int r0, int device, int status, int r3)
  253. {
  254.     dword_10501C[device] = status;
  255.     dword_10501C[device + 6] = 1;
  256.     return 0;
  257. }
  258.  
  259. // SPI service 0x30440
  260. void sub_1014DC()
  261. {
  262.     // TODO
  263. }
  264.  
  265. // SPI service 0x90040
  266. // enables 3rd bus
  267. // sub_1014B8
  268. int SpiEnableTwlSpiBus(int r0, int onoff)
  269. {
  270.     u16 data = *(uint16_t *)(0x101401C0);
  271.  
  272.     if (onoff == 0)
  273.         data = data & ~0b100;
  274.     else
  275.         data = data | 0b100;
  276.  
  277.     *(uint16_t *)(0x101401C0) = data;
  278.  
  279.     return 0;
  280. }
  281.  
  282.  
  283. struct spi_msg_out {
  284.     uint32_t baudrate; //0
  285.     uint32_t buffer;   //4 // buffer
  286.     uint32_t size;     //8 // size
  287.     uint8_t device;    //C // device
  288. };
  289.  
  290. // sub_102340: spi.bin
  291. // SPI service 0x50040
  292. // SpiWriteDevice
  293. void spi_write_msg_new(struct spi_msg_out *msg)
  294. {
  295.     uint8_t device_id = msg->device;
  296.  
  297.     uint32_t reg_cnt = 0x1EC60800; // SPI_NEW_CNT2
  298.     if (device_id < 7) {
  299.         if (device_id >= 3 && device_id <= 5) {
  300.             reg_cnt = 0x1EC42800; // SPI_NEW_CNT0
  301.         } else if (device_id == 6) {
  302.             reg_cnt = 0x1EC43800; // SPI_NEW_CNT1
  303.         }
  304.     }
  305.  
  306.     uint32_t reg_fifo = 0x1EC6080C; // SPI_NEW_FIFO2
  307.     if (device_id < 7) {
  308.         if (device_id >= 3 && device_id <= 5) {
  309.             reg_fifo = 0x1EC4280C; // SPI_NEW_FIFO0
  310.         } else if (device_id == 6) {
  311.             reg_fifo = 0x1EC4380C; // SPI_NEW_FIFO1
  312.         }
  313.     }
  314.  
  315.     uint32_t device_bits;
  316.     if (device_id < 6) {
  317.         if (device_id == 0 || device_id == 3) {
  318.             device_bits = 0;
  319.         } else if (device_id == 1 || device_id == 4) {
  320.             device_bits = 0x40;
  321.         } else if (device_id == 2 || device_id == 5) {
  322.             device_bits = 0x80;
  323.         }
  324.     } else {
  325.         device_bits = 0;
  326.     }
  327.  
  328.     // while busy...
  329.     while (*(uint32_t *)reg_cnt & 0x8000)
  330.         ;
  331.  
  332.     *(uint32_t *)(reg_cnt + 8) = msg->size; // SPI_NEW_BLKLEN
  333.     //0xA000 = xfer dir: out, enable = 1
  334.     *(uint32_t *)reg_cnt = (msg->baudrate & 0xFF) | device_bits | 0xA000;
  335.  
  336.     if (msg->size > 0) {
  337.         uint32_t count = 0;
  338.         do {
  339.             if ((count & 0x1F) == 0) {
  340.                 // SPI_NEW_STATUS, FIFO busy
  341.                 while (*(uint32_t *)(reg_cnt + 0x10) & 1)
  342.                     ;
  343.             }
  344.  
  345.             uint32_t buffer_idx = count & ~0b11;
  346.             count = count + 4;
  347.             *(uint32_t *)reg_fifo = *(uint32_t *)(msg->buffer + buffer_idx);
  348.         } while (count < msg->size);
  349.     }
  350.  
  351.     // while busy...
  352.     while (*(uint32_t *)reg_cnt & 0x8000)
  353.         ;
  354.  
  355.     *(uint32_t *)(reg_cnt + 4) = 0; // SPI_NEW_???
  356. }
  357.  
  358. struct spi_msg_inout {
  359.     uint32_t e0;         //0x00 baudrate?
  360.     uint32_t out_buffer; //0x04
  361.     uint32_t out_size;   //0x08
  362.     uint32_t in_buffer;  //0x0C
  363.     uint32_t in_size;    //0x10
  364.     uint8_t  device;     //0x14
  365. };
  366.  
  367. //wtf is this shit?
  368. static void sub_101CD8(int r0, int r1)
  369. {
  370.     r2 = r0 - 0x3477;
  371.     if (r2 >= 0) {
  372.         r2 = r1 - (r0 > r2);
  373.     } else if (r2 < 0) {
  374.         goto loc_101CEC;
  375.     }
  376.  
  377.     SleepThread([r1:r0]); //ns
  378.  
  379. loc_101CEC:
  380.     r2 = 0x44A2FA85;
  381.  
  382.     r3 = lo(r0 * r2);
  383.     r0 = hi(r0 * r2);
  384.  
  385.     r1 = lo(r1 * r2);
  386.     r2 = hi(r1 * r2);
  387.  
  388.     r0 = r0 + r1;
  389.  
  390.     // Crappy delay
  391.     while (r0 > 0)
  392.         r0 -= 2;
  393. }
  394.  
  395. // sub_1028A8
  396. // SPI Service: 0x60042
  397. // ReadWriteDeviceArray
  398. void spi_write_msg_inout_new(struct spi_msg_inout *msg)
  399. {
  400.     uint8_t device_id = msg->device;
  401.  
  402.     uint32_t reg_cnt = 0x1EC60800; // SPI_NEW_CNT2
  403.     if (device_id < 7) {
  404.         if (device_id >= 3 && device_id <= 5) {
  405.             reg_cnt = 0x1EC42800; // SPI_NEW_CNT0
  406.         } else if (device_id == 6) {
  407.             reg_cnt = 0x1EC43800; // SPI_NEW_CNT1
  408.         }
  409.     }
  410.  
  411.     uint32_t reg_fifo = 0x1EC6080C; // SPI_NEW_FIFO2
  412.     if (device_id < 7) {
  413.         if (device_id >= 3 && device_id <= 5) {
  414.             reg_fifo = 0x1EC4280C; // SPI_NEW_FIFO0
  415.             goto loc_102928;
  416.         } else if (device_id == 6) {
  417.             reg_fifo = 0x1EC4380C; // SPI_NEW_FIFO1
  418.         }
  419.     }
  420.  
  421.     uint8_t device_bits;
  422.     if (device_id < 6) {
  423.         if (device_id == 1 || device_id == 4) {
  424.             device_bits = 0x40;
  425.         } else if (device_id == 2 || device_id == 5) {
  426.             device_bits = 0x80;
  427.         } else {
  428.             device_bits = 0;
  429.         }
  430.     } else {
  431.         device_bits = 0;
  432.     }
  433.  
  434.     // while busy...
  435.     while (*(uint32_t *)reg_cnt & 0x8000)
  436.         ;
  437.  
  438.     *(uint32_t *)(reg_cnt + 8) = msg->size; // SPI_NEW_BLKLEN
  439.  
  440.     uint32_t cnt_in_flags = (msg->e0 & 0xFF) | device_bits | 0x8000; //enable, in
  441.     uint32_t cnt_out_flags = cnt_in_flags | 0x2000; //enable, out
  442.  
  443.     *(uint32_t *)reg_cnt = cnt_out_flags;
  444.  
  445.     r0 = msg->e0 & 0xFF;
  446.  
  447.     if (r0 < 6) {
  448.         if (r0 == 0) {
  449.             r7 = 0x83400;
  450.         } else if (r0 == 1) {
  451.             r7 = 0x41A00;
  452.         } else if (r0 == 2) {
  453.             r7 = 0x20D00;
  454.         } else if (r0 == 3) {
  455.             r7 = 0x10680;
  456.         } else if (r0 == 4) {
  457.             r7 = 0x8340;
  458.         } else if (r0 == 5) {
  459.             r7 = 0x41A0;
  460.         } else {
  461.             r7 = 0x83400;
  462.         }
  463.     } else {
  464.         r7 = 0x83400;
  465.     }
  466.  
  467.     r8 = 0;
  468.  
  469.     uint32_t out_count = 0;
  470.     if (msg->out_size > 0) {
  471.         do {
  472.             if ((out_count & 0x1F) == 0) {
  473.                 // SPI_NEW_STATUS, FIFO busy
  474.                 while (*(uint32_t *)(reg_cnt + 0x10) & 1)
  475.                     ;
  476.             }
  477.  
  478.             uint32_t buffer_idx = out_count & ~0b11;
  479.             out_count = out_count + 4;
  480.             *(uint32_t *)reg_fifo = *(uint32_t *)(msg->out_buffer + buffer_idx);
  481.  
  482.         } while (out_count < msg->out_size);
  483.     }
  484.  
  485.     // while busy...
  486.     while (*(uint32_t *)reg_cnt & 0x8000)
  487.         ;
  488.  
  489.     *(uint32_t *)(reg_cnt + 8) = msg->in_size; // SPI_NEW_BLKLEN
  490.     *(uint32_t *)reg_cnt = cnt_in_flags;
  491.  
  492.     uint32_t in_count = 0;
  493.     if (msg->in_size > 0) {
  494.         do {
  495.             if ((in_count & 0x1F) == 0) {
  496.                 while (*(uint32_t *)(reg_cnt + 0x10) & 1) //SPI_NEW_STATUS, FIFO busy
  497.                     ;
  498.  
  499.                 if (msg->in_size >= 0x40) {
  500.                     sub_101CD8(r7, r8);
  501.                 }
  502.             }
  503.  
  504.             uint32_t buffer_idx = in_count & ~0b11;
  505.             in_count = in_count + 4;
  506.             *(uint32_t *)(msg->in_buffer + buffer_idx) = *(uint32_t *)reg_fifo;
  507.         } while (in_count < msg->in_size);
  508.     }
  509.  
  510.     // while busy...
  511.     while (*(uint32_t *)reg_cnt & 0x8000)
  512.         ;
  513.  
  514.     *(uint32_t *)(reg_cnt + 4) = 0;
  515. }
  516.  
  517.  
  518. struct spi_msg_out_2 {
  519.     uint32_t baudrate; //0x00 baudrate?
  520.     uint32_t buffer1;  //0x04
  521.     uint32_t size1;    //0x08
  522.     uint32_t buffer2;  //0x0C
  523.     uint32_t size2;    //0x10
  524.     uint8_t  device;   //0x14
  525. };
  526.  
  527. // sub_102AF8
  528. // SPI service: 0x70042
  529. // ReadWriteDevice2Array
  530. void spi_write_msg_out_2_new(struct spi_msg_out_2 *msg)
  531. {
  532.     uint8_t device_id = msg->device;
  533.  
  534.     uint32_t reg_cnt = 0x1EC60800; // SPI_NEW_CNT2
  535.     if (device_id < 7) {
  536.         if (device_id >= 3 && device_id <= 5) {
  537.             reg_cnt = 0x1EC42800;
  538.         } else if (device_id == 6) {
  539.             reg_cnt = 0x1EC43800;
  540.         }
  541.     }
  542.  
  543.     uint32_t reg_fifo = 0x1EC6080C; // SPI_NEW_FIFO2
  544.     if (device_id < 7) {
  545.         if (device_id >= 3 && device_id <= 5) {
  546.             reg_fifo = 0x1EC4280C;
  547.         } else if (device_id == 6) {
  548.             reg_fifo = 0x1EC4380C;
  549.         }
  550.     }
  551.  
  552.     uint8_t device_bits;
  553.     if (device_id < 6) {
  554.         if (device_id == 0 || device_id == 3) {
  555.             device_bits = 0;
  556.         } else if (device_id == 1 || device_id == 4) {
  557.             device_bits = 0x40;
  558.         } else if (device_id == 2 || device_id == 5) {
  559.             device_bits = 0x80;
  560.         }
  561.     } else {
  562.         device_bits = 0;
  563.     }
  564.  
  565.     while (*(uint32_t *)reg_cnt & 0x8000)
  566.         ;
  567.  
  568.     uint32_t cnt_flags = (msg->baudrate & 0xFF) | device_bits | 0x8000;
  569.  
  570.     *(uint32_t *)(reg_cnt + 0x8) = msg->size1;
  571.     *(uint32_t *)reg_cnt = cnt_flags | 0x2000;
  572.  
  573.     uint32_t count1 = 0;
  574.     if (msg->size1 > 0) {
  575.         do {
  576.             if ((count1 & 0x1F) == 0) {
  577.                 while (*(uint32_t *)(reg_cnt + 0x10) & 1)
  578.                     ;
  579.             }
  580.             uint32_t buffer_idx = count1 & ~0b11;
  581.             count1 = count1 + 4;
  582.             *(uint32_t *)reg_fifo = *(uint32_t *)(msg->buffer1 + buffer_idx);
  583.         } while (count1 < msg->size1);
  584.     }
  585.  
  586.  
  587.     while (*(uint32_t *)reg_cnt & 0x8000)
  588.         ;
  589.  
  590.     *(uint32_t *)(reg_cnt + 0x8) = msg->size2;
  591.     *(uint32_t *)reg_cnt = cnt_flags | 0x2000;
  592.  
  593.     uint32_t count2 = 0;
  594.     if (msg->size2 > 0) {
  595.         do {
  596.             if ((count2 & 0x1F) == 0) {
  597.                 while (*(uint32_t *)(reg_cnt + 0x10) & 1)
  598.                     ;
  599.             }
  600.  
  601.             uint32_t buffer_idx = count2 & ~3;
  602.             count2 = count2 + 4;
  603.             *(uint32_t *)reg_fifo = *(uint32_t *)(msg->buffer2 + buffer_idx);
  604.         } while (count2 < msg->size2);
  605.     }
  606.  
  607.     while (*(uint32_t *)reg_cnt & 0x8000)
  608.         ;
  609.  
  610.     *(uint32_t *)(reg_cnt + 0x4) = 0;
  611. }
  612.  
  613. /******** HID RE *********/
  614.  
  615. // r0 = i2c handle pointer
  616. void sub_103EEC(int r0, int r1, int r2, int r3)
  617. {
  618.     //Read Thread ID Privileged Read Write only Register
  619.     asm("mrc p15, 0, r4, c13, c0, 3\n");
  620.     //r4 = TLS
  621.  
  622.     // WriteRegister8 (u8 devid, u8 regid, u8 regdata)
  623.     r1 = 0x500C0;
  624.     *(uint32_t *)(r4 + 0x80) = r1;
  625.  
  626.     r1 = *(uint8_t *)(&var_14);
  627.     *(uint8_t *)(r4 + 0x84) = r1; // devid
  628.  
  629.     r1 = *(uint8_t *)(&var_10);
  630.     *(uint8_t *)(r4 + 0x88) = r1; // regid
  631.  
  632.     r1 = *(uint8_t *)(&var_C);
  633.     *(uint8_t *)(r4 + 0x8C) = r1; // regdata
  634.  
  635.     // Handle i2c session
  636.     r0 = *(uint32_t *)r0;
  637.  
  638.     // Result SendSyncRequest(Handle session)
  639.     asm("svc 0x32\n");
  640.  
  641.     if (r0 >= 0) {
  642.         r0 = *(uint32_t *)(r4 + 0x4);
  643.     }
  644.  
  645.     return r0;
  646. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement