# HG changeset patch # User Mychaela Falconia # Date 1514235030 0 # Node ID 2eae53bb4a4eab330cd733db933c7968698e46ba # Parent 6d9a6627b0850d0d657db09773b0758c7ab2615d pirelli/fw-disasm: Switch_ON() analysis complete diff -r 6d9a6627b085 -r 2eae53bb4a4e pirelli/fw-disasm --- a/pirelli/fw-disasm Sun Dec 24 18:03:25 2017 +0000 +++ b/pirelli/fw-disasm Mon Dec 25 20:50:30 2017 +0000 @@ -723,6 +723,11 @@ 32db8c: b002 add sp, #8 32db8e: bd10 pop {r4, pc} +; The following function computes the battery remaining % number +; from the battery mV passed in R0. It first increases the mV value +; by a factor that depends on the system current draw (it appears +; that they are after the "true" battery voltage before the internal +; resistance), and then does the table look-up for the % number. 32dfee: b510 push {r4, lr} 32dff0: b082 sub sp, #8 32dff2: 1c04 add r4, r0, #0 @@ -814,15 +819,21 @@ 32e0a0: b002 add sp, #8 32e0a2: bd10 pop {r4, pc} +; The following function seems to compute the system's current draw. +; It starts with the display backlight's current draw from 0x1775138, +; converts it from ADC units to mA per the fixed *855/1000 formula, +; and then throws in a ton of other factors which are impractical +; to follow in this totally unknown fw. 32e340: b510 push {r4, lr} 32e342: b08c sub sp, #48 ; 0x30 +; function returns the value of 16-bit var in 0x1775138 32e344: f0b0 ffbd bl 0x3df2c2 32e348: 1c04 add r4, r0, #0 32e34a: 484a ldr r0, =0x357 ; via 0x32e474 32e34c: 4360 mul r0, r4 32e34e: 217d mov r1, #125 ; 0x7d 32e350: 00c9 lsl r1, r1, #3 - 32e352: f0c8 ff6b bl 0x3f722c + 32e352: f0c8 ff6b bl 0x3f722c ; I$DIV 32e356: 0408 lsl r0, r1, #16 32e358: 1404 asr r4, r0, #16 32e35a: f085 fea4 bl 0x3b40a6 @@ -1409,7 +1420,7 @@ 39f04e: 43d2 mvn r2, r2 39f050: 2305 mov r3, #5 39f052: f03b fdef bl 0x3dac34 - 39f056: f002 f9f1 bl 0x3a143c + 39f056: f002 f9f1 bl 0x3a143c ; $Power_OFF_Button 39f05a: e125 b 0x39f2a8 ; end of PUSHOFF_IT_STS handling 39f05c: 9802 ldr r0, [sp, #8] @@ -1424,7 +1435,7 @@ 39f06e: 43d2 mvn r2, r2 39f070: 2305 mov r3, #5 39f072: f03b fddf bl 0x3dac34 - 39f076: f002 fa9c bl 0x3a15b2 + 39f076: f002 fa9c bl 0x3a15b2 ; $Power_OFF_Remote 39f07a: e115 b 0x39f2a8 ; end of REMOT_IT_STS handling 39f07c: 9802 ldr r0, [sp, #8] @@ -1697,6 +1708,86 @@ 39f2b0: bd10 pop {r4, pc} 39f2b2: 46c0 nop (mov r8, r8) +$Power_ON_Button: + 3a13dc: b570 push {r4, r5, r6, lr} + 3a13de: 1c05 add r5, r0, #0 +; set is_gsm_on + 3a13e0: 2232 mov r2, #50 ; 0x32 + 3a13e2: 48ee ldr r0, =0x1774e38 ; via 0x3a179c + 3a13e4: 6801 ldr r1, [r0, #0] + 3a13e6: 2001 mov r0, #1 + 3a13e8: 5450 strb r0, [r2, r1] +; Kp pointers: are they set? + 3a13ea: 4eed ldr r6, =0x1774e98 ; via 0x3a17a0 + 3a13ec: 6834 ldr r4, [r6, #0] + 3a13ee: 6830 ldr r0, [r6, #0] + 3a13f0: 2800 cmp r0, #0 + 3a13f2: d002 beq 0x3a13fa + 3a13f4: 6870 ldr r0, [r6, #4] + 3a13f6: 2800 cmp r0, #0 + 3a13f8: d106 bne 0x3a1408 + 3a13fa: 2001 mov r0, #1 + 3a13fc: f710 fa4f bl 0x2b189e ; rvf_delay() + 3a1400: 6834 ldr r4, [r6, #0] + 3a1402: 2c00 cmp r4, #0 + 3a1404: d1f6 bne 0x3a13f4 + 3a1406: e7f8 b 0x3a13fa +; end of the wait for Kp pointers to be initialized +; different boot causes result in different key codes being sent + 3a1408: 2d01 cmp r5, #1 + 3a140a: d00d beq 0x3a1428 + 3a140c: 2d04 cmp r5, #4 + 3a140e: d009 beq 0x3a1424 + 3a1410: 2d08 cmp r5, #8 + 3a1412: d005 beq 0x3a1420 + 3a1414: 2d02 cmp r5, #2 + 3a1416: d001 beq 0x3a141c + 3a1418: 2036 mov r0, #54 ; 0x36 + 3a141a: e006 b 0x3a142a + 3a141c: 2035 mov r0, #53 ; 0x35 + 3a141e: e004 b 0x3a142a + 3a1420: 2034 mov r0, #52 ; 0x34 + 3a1422: e002 b 0x3a142a + 3a1424: 2033 mov r0, #51 ; 0x33 + 3a1426: e000 b 0x3a142a + 3a1428: 2019 mov r0, #25 ; 0x19 + 3a142a: f055 feef bl 0x3f720c ; $IND_CALL + 3a142e: 2005 mov r0, #5 + 3a1430: f710 fa35 bl 0x2b189e ; rvf_delay() + 3a1434: 6874 ldr r4, [r6, #4] + 3a1436: f055 fee9 bl 0x3f720c ; $IND_CALL + 3a143a: bd70 pop {r4, r5, r6, pc} + +$Power_OFF_Button: + 3a143c: b530 push {r4, r5, lr} + 3a143e: b082 sub sp, #8 + 3a1440: f707 f84e bl 0x2a84e0 + 3a1444: 48d7 ldr r0, =0xa0020 ; via 0x3a17a4 + 3a1446: 9000 str r0, [sp, #0] + 3a1448: a0b9 add r0, pc, #740 ; 0x2e4 + 3a144a: 2110 mov r1, #16 ; 0x10 + 3a144c: 2200 mov r2, #0 + 3a144e: 43d2 mvn r2, r2 + 3a1450: 2302 mov r3, #2 + 3a1452: f039 fbef bl 0x3dac34 + 3a1456: 4dd2 ldr r5, =0x1774e98 ; via 0x3a17a0 + 3a1458: 2019 mov r0, #25 ; 0x19 + 3a145a: 682c ldr r4, [r5, #0] + 3a145c: f055 fed6 bl 0x3f720c ; $IND_CALL + 3a1460: 2005 mov r0, #5 + 3a1462: f710 fa1c bl 0x2b189e ; rvf_delay() + 3a1466: 686c ldr r4, [r5, #4] + 3a1468: f055 fed0 bl 0x3f720c ; $IND_CALL + 3a146c: b002 add sp, #8 + 3a146e: bd30 pop {r4, r5, pc} + +$Set_Switch_ON_Cause: + 3a1470: b500 push {lr} + 3a1472: f7a7 ff4b bl 0x34930c + 3a1476: 49cc ldr r1, =0x1774cd0 ; via 0x3a17a8 + 3a1478: 8008 strh r0, [r1, #0] + 3a147a: bd00 pop {pc} + $Switch_ON: 3a147c: b5f0 push {r4, r5, r6, r7, lr} 3a147e: b082 sub sp, #8 @@ -1786,6 +1877,7 @@ 3a1528: 1c02 add r2, r0, #0 3a152a: 48a3 ldr r0, =0x1774ccc ; via 0x3a17b8 3a152c: 8002 strh r2, [r0, #0] +; "First capacity (%):" trace 3a152e: 489d ldr r0, =0xa0020 ; via 0x3a17a4 3a1530: 9000 str r0, [sp, #0] 3a1532: a090 add r0, pc, #576 ; 0x240 @@ -1799,6 +1891,7 @@ 3a1544: 4328 orr r0, r5 3a1546: 0600 lsl r0, r0, #24 3a1548: 0e05 lsr r5, r0, #24 +; bit 1 is set in R5 if the battery is critically low 3a154a: 0928 lsr r0, r5, #4 3a154c: d309 bcc 0x3a1562 3a154e: 489b ldr r0, =0xd2a ; via 0x3a17bc @@ -1808,10 +1901,13 @@ 3a1556: 7871 ldrb r1, [r6, #1] 3a1558: 4008 and r0, r1 3a155a: 7070 strb r0, [r6, #1] - 3a155c: f7a8 f98c bl 0x349878 + 3a155c: f7a8 f98c bl 0x349878 ; $ABB_Power_Off 3a1560: e024 b 0x3a15ac +; end of RTC alarm low battery check +; set display backlight to max 3a1562: 2040 mov r0, #64 ; 0x40 3a1564: f03d fe5f bl 0x3df226 +; find the highest set bit in R5 3a1568: 2107 mov r1, #7 3a156a: 2001 mov r0, #1 3a156c: 4088 lsl r0, r1 @@ -1825,6 +1921,7 @@ 3a157c: 1409 asr r1, r1, #16 3a157e: 2900 cmp r1, #0 3a1580: d5f3 bpl 0x3a156a +; end of the find-highest-bit loop 3a1582: 2200 mov r2, #0 3a1584: 2802 cmp r0, #2 3a1586: d000 beq 0x3a158a @@ -1837,11 +1934,13 @@ 3a1594: 2000 mov r0, #0 3a1596: 08e9 lsr r1, r5, #3 3a1598: d204 bcs 0x3a15a4 - 3a159a: f7ff ff1f bl 0x3a13dc - 3a159e: f012 fa73 bl 0x3b3a88 +; boot path w/o charging power + 3a159a: f7ff ff1f bl 0x3a13dc ; $Power_ON_Button + 3a159e: f012 fa73 bl 0x3b3a88 ; $pwr_handle_discharge 3a15a2: e003 b 0x3a15ac - 3a15a4: f7ff ff1a bl 0x3a13dc - 3a15a8: f000 f805 bl 0x3a15b6 +; boot path with charging power + 3a15a4: f7ff ff1a bl 0x3a13dc ; $Power_ON_Button + 3a15a8: f000 f805 bl 0x3a15b6 ; $PWR_Charger_Plug 3a15ac: b002 add sp, #8 3a15ae: bdf0 pop {r4, r5, r6, r7, pc} @@ -1866,15 +1965,15 @@ 3a15c6: 30b2 add r0, #178 ; 0xb2 3a15c8: f710 f969 bl 0x2b189e ; rvf_delay() 3a15cc: 2003 mov r0, #3 - 3a15ce: f789 fcc9 bl 0x32af64 - 3a15d2: f7f3 fb5d bl 0x394c90 - 3a15d6: f78c fc1b bl 0x32de10 + 3a15ce: f789 fcc9 bl 0x32af64 ; $rvf_stop_timer ? + 3a15d2: f7f3 fb5d bl 0x394c90 ; $pwr_send_charger_plug_event ? + 3a15d6: f78c fc1b bl 0x32de10 ; $pwr_get_battery_type ? 3a15da: bd00 pop {pc} $PWR_Charger_Unplug: 3a15dc: b500 push {lr} 3a15de: b082 sub sp, #8 - 3a15e0: f7f3 fb8f bl 0x394d02 + 3a15e0: f7f3 fb8f bl 0x394d02 ; $pwr_send_charger_unplug_event ? 3a15e4: 486f ldr r0, =0xa0020 ; via 0x3a17a4 3a15e6: 9000 str r0, [sp, #0] 3a15e8: a068 add r0, pc, #416 ; 0x1a0 @@ -1901,12 +2000,12 @@ 3a1616: 7800 ldrb r0, [r0, #0] 3a1618: 2800 cmp r0, #0 3a161a: d102 bne 0x3a1622 - 3a161c: f012 fa34 bl 0x3b3a88 + 3a161c: f012 fa34 bl 0x3b3a88 ; $pwr_handle_discharge 3a1620: e004 b 0x3a162c 3a1622: 2001 mov r0, #1 3a1624: 213c mov r1, #60 ; 0x3c 3a1626: 2201 mov r2, #1 - 3a1628: f7a7 fdf0 bl 0x34920c + 3a1628: f7a7 fdf0 bl 0x34920c ; $ABB_Write_Register_on_page 3a162c: b002 add sp, #8 3a162e: bd00 pop {pc} @@ -1937,11 +2036,11 @@ 3a165c: 203c mov r0, #60 ; 0x3c 3a165e: 4d50 ldr r5, =0x1774e98 ; via 0x3a17a0 3a1660: 682c ldr r4, [r5, #0] - 3a1662: f055 fdd3 bl 0x3f720c + 3a1662: f055 fdd3 bl 0x3f720c ; $IND_CALL 3a1666: 2005 mov r0, #5 - 3a1668: f710 f919 bl 0x2b189e + 3a1668: f710 f919 bl 0x2b189e ; rvf_delay() 3a166c: 686c ldr r4, [r5, #4] - 3a166e: f055 fdcd bl 0x3f720c + 3a166e: f055 fdcd bl 0x3f720c ; $IND_CALL 3a1672: bd30 pop {r4, r5, pc} 3a1674: b500 push {lr} @@ -2030,6 +2129,10 @@ 3a172c: 4770 bx lr 3a172e: 46c0 nop (mov r8, r8) + 3b40a6: 488c ldr r0, =0x1774db0 ; via 0x3b42d8 + 3b40a8: 6800 ldr r0, [r0, #0] + 3b40aa: 4770 bx lr + $Init_Target: 3bb7d4: b570 push {r4, r5, r6, lr} 3bb7d6: b081 sub sp, #4 @@ -2818,6 +2921,92 @@ 3dc9e0: b003 add sp, #12 ; 0xc 3dc9e2: bd00 pop {pc} +; A higher-level display backlight control function: takes a backlight +; level index as input (0 means off, 1-4 are defined levels, anything >=5 +; means maximum), calls the lower-level function with the corresponding +; PWL value, and sets the 0x1775138 var to a number that seems to be +; the backlight's expected current draw. + 3df226: b500 push {lr} + 3df228: 2800 cmp r0, #0 + 3df22a: d105 bne 0x3df238 + 3df22c: f000 f827 bl 0x3df27e + 3df230: 492a ldr r1, =0x1775138 ; via 0x3df2dc + 3df232: 2000 mov r0, #0 + 3df234: 8008 strh r0, [r1, #0] + 3df236: bd00 pop {pc} + 3df238: 2801 cmp r0, #1 + 3df23a: d019 beq 0x3df270 + 3df23c: 2802 cmp r0, #2 + 3df23e: d012 beq 0x3df266 + 3df240: 2803 cmp r0, #3 + 3df242: d00b beq 0x3df25c + 3df244: 2804 cmp r0, #4 + 3df246: d004 beq 0x3df252 + 3df248: 20ff mov r0, #255 ; 0xff + 3df24a: f000 f818 bl 0x3df27e + 3df24e: 2162 mov r1, #98 ; 0x62 + 3df250: e012 b 0x3df278 + 3df252: 20c0 mov r0, #192 ; 0xc0 + 3df254: f000 f813 bl 0x3df27e + 3df258: 2157 mov r1, #87 ; 0x57 + 3df25a: e00d b 0x3df278 + 3df25c: 2080 mov r0, #128 ; 0x80 + 3df25e: f000 f80e bl 0x3df27e + 3df262: 214c mov r1, #76 ; 0x4c + 3df264: e008 b 0x3df278 + 3df266: 2040 mov r0, #64 ; 0x40 + 3df268: f000 f809 bl 0x3df27e + 3df26c: 2141 mov r1, #65 ; 0x41 + 3df26e: e003 b 0x3df278 + 3df270: 2001 mov r0, #1 + 3df272: f000 f804 bl 0x3df27e + 3df276: 2108 mov r1, #8 + 3df278: 4818 ldr r0, =0x1775138 ; via 0x3df2dc + 3df27a: 8001 strh r1, [r0, #0] + 3df27c: bd00 pop {pc} + +; The following 0x3df27e function controls the display backlight. +; 0 argument means fully off, otherwise the master on/off control is on +; and the argument is the value for PWL control before the inversion. + 3df27e: b530 push {r4, r5, lr} + 3df280: 2800 cmp r0, #0 + 3df282: d10d bne 0x3df2a0 + 3df284: 4c16 ldr r4, =0x177513a ; via 0x3df2e0 + 3df286: 7820 ldrb r0, [r4, #0] + 3df288: 2800 cmp r0, #0 + 3df28a: d016 beq 0x3df2ba +; 0x2785d0 must be the display backlight master on/off control function + 3df28c: 2000 mov r0, #0 + 3df28e: f699 f99f bl 0x2785d0 + 3df292: 2000 mov r0, #0 + 3df294: 4913 ldr r1, =0xfffe8000 ; via 0x3df2e4 + 3df296: 7008 strb r0, [r1, #0] + 3df298: 4913 ldr r1, =0xfffe8001 ; via 0x3df2e8 + 3df29a: 7008 strb r0, [r1, #0] + 3df29c: 7020 strb r0, [r4, #0] + 3df29e: bd30 pop {r4, r5, pc} + 3df2a0: 4910 ldr r1, =0xfffe8000 ; via 0x3df2e4 + 3df2a2: 4240 neg r0, r0 + 3df2a4: 7008 strb r0, [r1, #0] + 3df2a6: 4c0e ldr r4, =0x177513a ; via 0x3df2e0 + 3df2a8: 7820 ldrb r0, [r4, #0] + 3df2aa: 2800 cmp r0, #0 + 3df2ac: d105 bne 0x3df2ba + 3df2ae: 2501 mov r5, #1 + 3df2b0: 704d strb r5, [r1, #1] + 3df2b2: 2001 mov r0, #1 + 3df2b4: f699 f98c bl 0x2785d0 + 3df2b8: 7025 strb r5, [r4, #0] + 3df2ba: bd30 pop {r4, r5, pc} + + 3df2bc: 4808 ldr r0, =0x177513a ; via 0x3df2e0 + 3df2be: 7800 ldrb r0, [r0, #0] + 3df2c0: 4770 bx lr + + 3df2c2: 4806 ldr r0, =0x1775138 ; via 0x3df2dc + 3df2c4: 8800 ldrh r0, [r0, #0] + 3df2c6: 4770 bx lr + $AI_EnableBit: 3e300c: 4a44 ldr r2, =0xfffef00a ; via 0x3e3120 3e300e: 2101 mov r1, #1 @@ -3486,10 +3675,22 @@ 0x17649b8: ABB_Hisr 0x1764a10: ABB_HisrStack +0x17729d0: init data array that should have been const instead, + mapping from system current draw to voltage drop + that can be modeled as the battery's internal resistance: + 005A ( 90) 0017 (23) + 00AA (170) 002D (45) + 00FA (250) 0050 (80) + 0x17741e0: abb_sem 0x1774b7c: 16-bit var battery voltage in mV +0x1774ccc: 16-bit var initial battery % is stored here + +0x1774cd0: 16-bit var, ABB_Read_Status() return value at the beginning + of Switch_ON() is stored here + 0x1774cd4: 32-bit var BatOperationMode 0x1774e38: SPI_GBL_INFO_PTR @@ -3500,3 +3701,9 @@ 0x1775041: byte var set to 0 in spi_abb_read_int_reg_callback() in ADC end processing + +0x1775138: 16-bit var, stores a number that goes up as the display + backlight intensity increases, probably the backlight's + expected current draw + +0x177513a: 8-bit var, flag indicating if the display backlight is on