Rockbox.org home
Downloads
Release release
Dev builds dev builds
Extras extras
themes themes
Documentation
Manual manual
Wiki wiki
Device Status device status
Support
Forums forums
Mailing lists mailing lists
IRC IRC
Development
Bugs bugs
Patches patches
Dev Guide dev guide
Search



Donate

Rockbox Technical Forums


Login with username, password and session length
Home Help Search Staff List Login Register
News:

Rockbox Ports are now being developed for various digital audio players!

+  Rockbox Technical Forums
|-+  Rockbox Development
| |-+  Starting Development and Compiling
| | |-+  Beginning steps in kernel disassembly and analysis
« previous next »
  • Print
Pages: 1 [2] 3

Author Topic: Beginning steps in kernel disassembly and analysis  (Read 3984 times)

Offline dconrad

  • Developer
  • Member
  • *
  • Posts: 120
Re: Beginning steps in kernel disassembly and analysis
« Reply #15 on: June 20, 2021, 12:19:26 PM »
Quote from: amachronic on June 20, 2021, 05:44:40 AM
0x2c2c2c2c is most definitely the value pointed to by smart_config.write_gram_cmd. 0x2c is the standard write_memory_start command of MIPI DCS, used to initiate writing data to the LCD controller's framebuffer RAM. It's not fb_videomode.flag.

Aha, so it's cmd_buf[], I see it there now in my example driver setup.

Quote
In the M3K kernel sources the init_pixclock member is dropped vs. the YuanhuanLiang repo. That's probably why your fb_videomode struct is too big. Maybe you should check the M3K sources for other structs that seem "wrong", it's possible that the Eros Q is using sources similar to the M3K's. (A reminder that your source won't necessarily line up with the binary!)

I see! That did make it fit, and all the values look sane now. Bookmarking the m3k sources...

Quote
So with this in mind, jzfb stuff looks lined up right to me:

Code: [Select]
805147ac = bitfield
             clkply_active_rising=1
             newcfg_fmt_conv=1
             others=0
             (this is standard fare, nothing exotic)
805147b8 = smart_config.bus_width
805147c0 = smart_config.length_data_table
805147c4 = smart_config.data_table

Also a look at this
Code: [Select]
           805147a4 00              uint:1    0h                      pinmd:1
           805147a4 00              uint:1    0h                      pixclk_falli
           805147a4 00              uint:1    0h                      data_enable_
           805147a5 00 00 00 00 00  smart_co                          field_0x1d

That start address 805147a5 is almost certainly wrong. The alignment of the struct is at least 4 bytes and struct alignment = maximum alignment of any member. Plus, the first member must be aligned wrong because enums seem to be ints under the ABI used (an implementation detail which I haven't bothered to verify but seems to be true).

Weirdly, Ghidra doesn't align structs by default -- in the lower right corner of the struct editor is an unobtrusive "Align" checkbox. Checking that will make Ghidra insert the correct padding to follow C alignment rules (afaict). It seems Ghidra defaults to "packed" alignment by default... it confused me for a couple hours too. :o

In this particular case I think I can say with certainty the alignment is wrong -- but in general, you would need to check the generated code to see if the compiler emitted code to access aligned addresses or unaligned addresses. The lw/sw instructions to load/store a word require 4 byte aligned addresses, whereas to access an improperly aligned word, the compiler would need to generate different instructions -- in the case of MIPS the instructions used would depend on the ISA version targeted, IIRC the older versions don't have any unaligned load/store instructions.

The align checkbox... That magically fixed it! Yep, now that'll be the first thing I check.

Quote
That's my assumption. Sure, it's defined in other parts of the xburst tree for other SoCs, but this is an X1000 kernel... where else would it be defined?

Oh, I thought it was the jzfb_platform_data from drivers/video/jz_vfb/vfb.h at first, which is really short in comparison, but it's missing *dsi_pdata and lcd_type between *modes and bpp, so I was confused.

This is definitely a crash course in data structures, something I probably should have taken a class on in college...  ;D
Logged

Offline amachronic

  • Developer
  • Member
  • *
  • Posts: 261
Re: Beginning steps in kernel disassembly and analysis
« Reply #16 on: June 20, 2021, 12:48:22 PM »
ah, didn't realize that other driver used the same name... it looks like an in-memory framebuffer with no hardware interface. The real LCD driver would be under drivers/video/jz_fb_v12/. Or maybe the v11 or v13 versions. I'm not sure why they put 3 versions in one source tree.
Logged

Offline dconrad

  • Developer
  • Member
  • *
  • Posts: 120
Re: Beginning steps in kernel disassembly and analysis
« Reply #17 on: June 20, 2021, 03:47:04 PM »
Do you think it's worth trying to construct the platform_device structure? It requires building the device struct which is a bit daunting. Plus, there are some #ifdefs that I'm not sure if this device would have or not. Just not sure if that's something worth going through or not.

Edit: the big one defined in kernel/include/linux/device.h
« Last Edit: June 20, 2021, 03:49:21 PM by dconrad »
Logged

Offline amachronic

  • Developer
  • Member
  • *
  • Posts: 261
Re: Beginning steps in kernel disassembly and analysis
« Reply #18 on: June 20, 2021, 04:33:42 PM »
FWIW, I didn't ever figure out struct device and didn't try -- once I realized how complicated it was. But I did do some random clicking inside of them and it might've been useful once or twice... there's probably not much there which can't be found another way, because that struct is generic.

One tactic you could use to handle this kind of thing -- create the struct, but pad out the unknown parts with byte arrays. Choose the size of the byte arrays to make the known members line up properly, and if you find more information, you can always split up the byte arrays and add new members in the middle, etc.

So, maybe find a driver which you have source code for and which statically initializes a platform_device/device struct; locate the beginning of that struct in the binary, then go over the struct's members in order, stepping inside all nested structs along the way. Then, identify the initialized members and learn their offsets. Of course any initialized data that you aren't expecting will throw off the count, but with luck you can identify a few members. Then you can tentatively identify adjacent members via the source code as long as you don't have to pass over anything of unknown size.
Logged

Offline dconrad

  • Developer
  • Member
  • *
  • Posts: 120
Re: Beginning steps in kernel disassembly and analysis
« Reply #19 on: June 20, 2021, 05:03:15 PM »
Quote from: amachronic on June 20, 2021, 04:33:42 PM
FWIW, I didn't ever figure out struct device and didn't try -- once I realized how complicated it was. But I did do some random clicking inside of them and it might've been useful once or twice... there's probably not much there which can't be found another way, because that struct is generic.

One tactic you could use to handle this kind of thing -- create the struct, but pad out the unknown parts with byte arrays. Choose the size of the byte arrays to make the known members line up properly, and if you find more information, you can always split up the byte arrays and add new members in the middle, etc.

So, maybe find a driver which you have source code for and which statically initializes a platform_device/device struct; locate the beginning of that struct in the binary, then go over the struct's members in order, stepping inside all nested structs along the way. Then, identify the initialized members and learn their offsets. Of course any initialized data that you aren't expecting will throw off the count, but with luck you can identify a few members. Then you can tentatively identify adjacent members via the source code as long as you don't have to pass over anything of unknown size.

That seems like a sane way to do it. I'll have to give it a shot.

Meanwhile, I think I have some real, actual information about the LCD and backlight! well, maybe. I haven't quite figured out what the controller is, and I don't know what pins it uses to connect, but I think I've found quite a few details about it. I think all the values make sense, as far as I can tell - though I don't have much experience with these beyond what I've seen in example structs in the X1000 kernel source.

The platform_data struct:
Code: [Select]
                             jzfb_platform_data                              XREF[1]:     805728e8(*) 
        80514788 01 00 00        jzfb_pla
                 00 14 48
                 51 80 00
           80514788 01 00 00 00     long      1h                      num_modes                         XREF[1]:     805728e8(*) 
           8051478c 14 48 51 80     addr      fb_videomode            *modes        =
           80514790 00 00 00 00     addr      00000000                *dsi_data
           80514794 0d 00 00 80     jzfb_lcd  LCD_TYPE_SLCD           lcd_type
           80514798 18 00 00 00     uint      18h                     bpp
           8051479c 1f 00 00 00     uint      1Fh                     width
           805147a0 1f 00 00 00     uint      1Fh                     height
           805147a4 00              uint:1    0h                      pinmd:1
           805147a4 00              uint:1    0h                      pixclk_falli
           805147a4 00 00 00 00     uint:1    0h                      data_enable_
           805147a8 00 00 00 00 11  smart_co                          field_0x20
                    00 00 00 01 00
                    00 00 4c 48 51
              805147a8 00 00 00 00     smart_lc  SMART_LCD_TYPE_PARALLEL smart_type
              805147ac 11              uint:1    1h                      clkply_activ
              805147ac 11              uint:1    0h                      rsply_cmd_hi
              805147ac 11              uint:1    0h                      csply_active
              805147ac 11              uint:1    0h                      newcfg_6800_
              805147ac 11              uint:1    1h                      newcfg_fmt_c
              805147ac 11              uint:1    0h                      datatx_type_
              805147ac 11 00 00 00     uint:1    0h                      newcfg_cmd_9
              805147b0 01 00 00 00     ulong     1h                      length_cmd
              805147b4 4c 48 51 80     addr      8051484c                write_gram_cmd
              805147b8 08 00 00 00     ulong     8h                      bus_width
              805147bc 00 00 00 00     uint      0h                      data_times
              805147c0 38 00 00 00     ulong     38h                     length_data_
              805147c4 7c 48 51 80     addr      8051487c                *data_table
              805147c8 00 00 00 00     addr      00000000                (*init)
              805147cc 00 00 00 00     addr      00000000                (*gpio_for_s
              805147d0 00 00 00 00     int       0h                      te_gpio
              805147d4 00 00 00 00     int       0h                      te_irq_level
           805147d8 00 00 00 00 00  uint:1    0h                      dither_enabl
                    00 00 00
           805147e0 00 00 00 00 00  dither                            dither
                    00 00 00 00 00
                    00 00 00 00 00
              805147e0 00 00 00 00     uint      0h                      dither_red
              805147e4 00 00 00 00     uint      0h                      dither_green
              805147e8 00 00 00 00 00  uint      0h                      dither_blue
                       00 00 00
           805147f0 a8 94 01 80 d4  lcd_call                          lcd_callback
                    93 01 80 00 00
                    00 00 00 00 00
              805147f0 a8 94 01 80     addr      800194a8                *lcd_initial
              805147f4 d4 93 01 80     addr      800193d4                *lcd_initial
              805147f8 00 00 00 00     addr      00000000                *lcd_power_o
              805147fc 00 00 00 00     addr      00000000                *lcd_power_o
              80514800 00 00 00 00     addr      00000000                *lcd_power_o
              80514804 00 00 00 00     addr      00000000                *lcd_power_o
              80514808 00 00 00 00     addr      00000000                *dma_transfe
              8051480c 00 00 00 00     addr      00000000                *dma_transfe
        80514810 00              ??         00h
        80514811 00              ??         00h
        80514812 00              ??         00h
        80514813 00              ??         00h

The fb_videomode struct and cmd_buf[] array:
Code: [Select]
                             fb_videomode                                    XREF[1]:     8051478c(*) 
        80514814 e0 8d 4b        fb_video
                 80 50 00
                 00 00 40
           80514814 e0 8d 4b 80     addr      s_320x240_804b8de0      name          = "320x240"         XREF[1]:     8051478c(*) 
           80514818 50 00 00 00     uint      50h                     refresh
           8051481c 40 01 00 00     uint      140h                    xres
           80514820 f0 00 00 00     uint      F0h                     yres
           80514824 50 c3 00 00     uint      C350h                   pixclock
           80514828 00 00 00 00     uint      0h                      left_margin
           8051482c 00 00 00 00     uint      0h                      right_margin
           80514830 00 00 00 00     uint      0h                      upper_margin
           80514834 00 00 00 00     uint      0h                      lower_margin
           80514838 00 00 00 00     uint      0h                      hsync_len
           8051483c 00 00 00 00     uint      0h                      vsync_len
           80514840 03 00 00 00     uint      3h                      sync
           80514844 00 00 00 00     uint      0h                      vmode
           80514848 00 00 00 00     uint      0h                      flag
                             cmd_buf[]
        8051484c 2c 2c 2c 2c     ulong[1]
           8051484c [0]               2C2C2C2Ch

And the command set; this seems to be really generic, as far as I've seen:
Code: [Select]
        8051487c 00 00 00        smart_lc
                 00 c8 00
                 00 00 01
           8051487c 00 00 00 00 c8  smart_lc                          [0]
                    00 00 00
              8051487c 00 00 00 00     smart_co  SMART_CONFIG_CMD        type          //Set EXTC
              80514880 c8 00 00 00     uint      C8h                     value
           80514884 01 00 00 00 ff  smart_lc                          [1]
                    00 00 00
              80514884 01 00 00 00     smart_co  SMART_CONFIG_DATA       type
              80514888 ff 00 00 00     uint      FFh                     value
           8051488c 01 00 00 00 93  smart_lc                          [2]
                    00 00 00
              8051488c 01 00 00 00     smart_co  SMART_CONFIG_DATA       type
              80514890 93 00 00 00     uint      93h                     value
           80514894 01 00 00 00 42  smart_lc                          [3]
                    00 00 00
              80514894 01 00 00 00     smart_co  SMART_CONFIG_DATA       type
              80514898 42 00 00 00     uint      42h                     value
           8051489c 00 00 00 00 36  smart_lc                          [4]
                    00 00 00
              8051489c 00 00 00 00     smart_co  SMART_CONFIG_CMD        type          //Memory Access Co
              805148a0 36 00 00 00     uint      36h                     value
           805148a4 01 00 00 00 d8  smart_lc                          [5]
                    00 00 00
              805148a4 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //MY,MX,MV,ML,BGR,MH
              805148a8 d8 00 00 00     uint      D8h                     value
           805148ac 00 00 00 00 3a  smart_lc                          [6]
                    00 00 00
              805148ac 00 00 00 00     smart_co  SMART_CONFIG_CMD        type          //Pixel Format Set
              805148b0 3a 00 00 00     uint      3Ah                     value
           805148b4 01 00 00 00 66  smart_lc                          [7]
                    00 00 00
              805148b4 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //DPI [2:0],DBI [2
              805148b8 66 00 00 00     uint      66h                     value
           805148bc 00 00 00 00 c0  smart_lc                          [8]
                    00 00 00
              805148bc 00 00 00 00     smart_co  SMART_CONFIG_CMD        type          //Power Control 1
              805148c0 c0 00 00 00     uint      C0h                     value
           805148c4 01 00 00 00 15  smart_lc                          [9]
                    00 00 00
              805148c4 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //VRH[5:0]
              805148c8 15 00 00 00     uint      15h                     value
           805148cc 01 00 00 00 15  smart_lc                          [10]
                    00 00 00
              805148cc 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //VC[3:0]
              805148d0 15 00 00 00     uint      15h                     value
           805148d4 00 00 00 00 c1  smart_lc                          [11]
                    00 00 00
              805148d4 00 00 00 00     smart_co  SMART_CONFIG_CMD        type          //Power Control 2
              805148d8 c1 00 00 00     uint      C1h                     value
           805148dc 01 00 00 00 01  smart_lc                          [12]
                    00 00 00
              805148dc 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //SAP[2:0],BT[3:0]
              805148e0 01 00 00 00     uint      1h                      value
           805148e4 00 00 00 00 c5  smart_lc                          [13]
                    00 00 00
              805148e4 00 00 00 00     smart_co  SMART_CONFIG_CMD        type          //VCOM
              805148e8 c5 00 00 00     uint      C5h                     value
           805148ec 01 00 00 00 da  smart_lc                          [14]
                    00 00 00
              805148ec 01 00 00 00     smart_co  SMART_CONFIG_DATA       type
              805148f0 da 00 00 00     uint      DAh                     value
           805148f4 00 00 00 00 b1  smart_lc                          [15]
                    00 00 00
              805148f4 00 00 00 00     smart_co  SMART_CONFIG_CMD        type
              805148f8 b1 00 00 00     uint      B1h                     value
           805148fc 01 00 00 00 00  smart_lc                          [16]
                    00 00 00
              805148fc 01 00 00 00     smart_co  SMART_CONFIG_DATA       type
              80514900 00 00 00 00     uint      0h                      value
           80514904 01 00 00 00 1b  smart_lc                          [17]
                    00 00 00
              80514904 01 00 00 00     smart_co  SMART_CONFIG_DATA       type
              80514908 1b 00 00 00     uint      1Bh                     value
           8051490c 00 00 00 00 b4  smart_lc                          [18]
                    00 00 00
              8051490c 00 00 00 00     smart_co  SMART_CONFIG_CMD        type
              80514910 b4 00 00 00     uint      B4h                     value
           80514914 01 00 00 00 02  smart_lc                          [19]
                    00 00 00
              80514914 01 00 00 00     smart_co  SMART_CONFIG_DATA       type
              80514918 02 00 00 00     uint      2h                      value
           8051491c 00 00 00 00 e0  smart_lc                          [20]
                    00 00 00
              8051491c 00 00 00 00     smart_co  SMART_CONFIG_CMD        type
              80514920 e0 00 00 00     uint      E0h                     value
           80514924 01 00 00 00 0f  smart_lc                          [21]
                    00 00 00
              80514924 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P01-VP63
              80514928 0f 00 00 00     uint      Fh                      value
           8051492c 01 00 00 00 13  smart_lc                          [22]
                    00 00 00
              8051492c 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P02-VP62
              80514930 13 00 00 00     uint      13h                     value
           80514934 01 00 00 00 17  smart_lc                          [23]
                    00 00 00
              80514934 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P03-VP61
              80514938 17 00 00 00     uint      17h                     value
           8051493c 01 00 00 00 04  smart_lc                          [24]
                    00 00 00
              8051493c 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P04-VP59
              80514940 04 00 00 00     uint      4h                      value
           80514944 01 00 00 00 13  smart_lc                          [25]
                    00 00 00
              80514944 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P05-VP57
              80514948 13 00 00 00     uint      13h                     value
           8051494c 01 00 00 00 07  smart_lc                          [26]
                    00 00 00
              8051494c 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P06-VP50
              80514950 07 00 00 00     uint      7h                      value
           80514954 01 00 00 00 40  smart_lc                          [27]
                    00 00 00
              80514954 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P07-VP43
              80514958 40 00 00 00     uint      40h                     value
           8051495c 01 00 00 00 39  smart_lc                          [28]
                    00 00 00
              8051495c 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P08-VP27,36
              80514960 39 00 00 00     uint      39h                     value
           80514964 01 00 00 00 4f  smart_lc                          [29]
                    00 00 00
              80514964 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P09-VP20
              80514968 4f 00 00 00     uint      4Fh                     value
           8051496c 01 00 00 00 06  smart_lc                          [30]
                    00 00 00
              8051496c 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P10-VP13
              80514970 06 00 00 00     uint      6h                      value
           80514974 01 00 00 00 0d  smart_lc                          [31]
                    00 00 00
              80514974 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P11-VP6
              80514978 0d 00 00 00     uint      Dh                      value
           8051497c 01 00 00 00 0a  smart_lc                          [32]
                    00 00 00
              8051497c 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P12-VP4
              80514980 0a 00 00 00     uint      Ah                      value
           80514984 01 00 00 00 1f  smart_lc                          [33]
                    00 00 00
              80514984 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P13-VP2
              80514988 1f 00 00 00     uint      1Fh                     value
           8051498c 01 00 00 00 22  smart_lc                          [34]
                    00 00 00
              8051498c 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P14-VP1
              80514990 22 00 00 00     uint      22h                     value
           80514994 01 00 00 00 00  smart_lc                          [35]
                    00 00 00
              80514994 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P15-VP0
              80514998 00 00 00 00     uint      0h                      value
           8051499c 00 00 00 00 e1  smart_lc                          [36]
                    00 00 00
              8051499c 00 00 00 00     smart_co  SMART_CONFIG_CMD        type
              805149a0 e1 00 00 00     uint      E1h                     value
           805149a4 01 00 00 00 00  smart_lc                          [37]
                    00 00 00
              805149a4 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P01
              805149a8 00 00 00 00     uint      0h                      value
           805149ac 01 00 00 00 21  smart_lc                          [38]
                    00 00 00
              805149ac 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P02
              805149b0 21 00 00 00     uint      21h                     value
           805149b4 01 00 00 00 24  smart_lc                          [39]
                    00 00 00
              805149b4 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P03
              805149b8 24 00 00 00     uint      24h                     value
           805149bc 01 00 00 00 03  smart_lc                          [40]
                    00 00 00
              805149bc 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P04
              805149c0 03 00 00 00     uint      3h                      value
           805149c4 01 00 00 00 0f  smart_lc                          [41]
                    00 00 00
              805149c4 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P05
              805149c8 0f 00 00 00     uint      Fh                      value
           805149cc 01 00 00 00 05  smart_lc                          [42]
                    00 00 00
              805149cc 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P06
              805149d0 05 00 00 00     uint      5h                      value
           805149d4 01 00 00 00 38  smart_lc                          [43]
                    00 00 00
              805149d4 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P07
              805149d8 38 00 00 00     uint      38h                     value
           805149dc 01 00 00 00 32  smart_lc                          [44]
                    00 00 00
              805149dc 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P08
              805149e0 32 00 00 00     uint      32h                     value
           805149e4 01 00 00 00 49  smart_lc                          [45]
                    00 00 00
              805149e4 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P09
              805149e8 49 00 00 00     uint      49h                     value
           805149ec 01 00 00 00 00  smart_lc                          [46]
                    00 00 00
              805149ec 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P10
              805149f0 00 00 00 00     uint      0h                      value
           805149f4 01 00 00 00 09  smart_lc                          [47]
                    00 00 00
              805149f4 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P11
              805149f8 09 00 00 00     uint      9h                      value
           805149fc 01 00 00 00 08  smart_lc                          [48]
                    00 00 00
              805149fc 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P12
              80514a00 08 00 00 00     uint      8h                      value
           80514a04 01 00 00 00 32  smart_lc                          [49]
                    00 00 00
              80514a04 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P13
              80514a08 32 00 00 00     uint      32h                     value
           80514a0c 01 00 00 00 35  smart_lc                          [50]
                    00 00 00
              80514a0c 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P14
              80514a10 35 00 00 00     uint      35h                     value
           80514a14 01 00 00 00 0f  smart_lc                          [51]
                    00 00 00
              80514a14 01 00 00 00     smart_co  SMART_CONFIG_DATA       type          //P15
              80514a18 0f 00 00 00     uint      Fh                      value
           80514a1c 00 00 00 00 11  smart_lc                          [52]
                    00 00 00
              80514a1c 00 00 00 00     smart_co  SMART_CONFIG_CMD        type          //Exit Sleep
              80514a20 11 00 00 00     uint      11h                     value
           80514a24 02 00 00 00 c0  smart_lc                          [53]
                    d4 01 00
              80514a24 02 00 00 00     smart_co  SMART_CONFIG_UDELAY     type
              80514a28 c0 d4 01 00     uint      1D4C0h                  value
           80514a2c 00 00 00 00 29  smart_lc                          [54]
                    00 00 00
              80514a2c 00 00 00 00     smart_co  SMART_CONFIG_CMD        type          //Display On
              80514a30 29 00 00 00     uint      29h                     value
           80514a34 02 00 00 00 20  smart_lc                          [55]
                    4e 00 00
              80514a34 02 00 00 00     smart_co  SMART_CONFIG_UDELAY     type
              80514a38 20 4e 00 00     uint      4E20h                   value
        80514a3c 00              ??         00h
        80514a3d 00              ??         00h
        80514a3e 00              ??         00h
        80514a3f 00              ??         00h

(backlight stuff in another post)
« Last Edit: June 20, 2021, 05:28:33 PM by dconrad »
Logged

Offline dconrad

  • Developer
  • Member
  • *
  • Posts: 120
Re: Beginning steps in kernel disassembly and analysis
« Reply #20 on: June 20, 2021, 05:08:26 PM »
Backlight stuff:

platform_pwm_backlight_data:
Code: [Select]
                             backlight_data
        80514850 00 00 00        platform
                 00 ff 00
                 00 00 78
           80514850 00 00 00 00     int       0h                      pwm_id                            XREF[1]:     80514648(*) 
           80514854 ff 00 00 00     uint      FFh                     max_brightness
           80514858 78 00 00 00     uint      78h                     dft_brightness
           8051485c 00 00 00 00     uint      0h                      lth_brightness
           80514860 30 75 00 00     uint      7530h                   pwm_period_ns
           80514864 00 00 00 00     addr      00000000                *levels
           80514868 1c 94 01 80     addr      backlight_init          (*init)
           8051486c b0 93 01 80     addr      backlight_notify        (*notify)
           80514870 00 00 00 00     addr      00000000                (*notify_aft
           80514874 b8 93 01 80     addr      backlight_exit          (*exit)
        80514878 00              ??         00h
        80514879 00              ??         00h
        8051487a 00              ??         00h
        8051487b 00              ??         00h

backlight_exit() - I'm fairly sure it's just a gpio_free() call:
Code: [Select]
void backlight_exit(void)

{
  gpio_free(0x59);
  return;
}

backlight_notify() - I think the fact this is empty is possibly just a good data point to ID the controller:
Code: [Select]

undefined4 backlight_notify(undefined4 param_1,undefined4 param_2)

{
  return param_2;
}

and backlight_init() - I'm only like 75% sure the functions I've ID'd within backlight_init() are correct, so take it with a grain of salt and all:
Code: [Select]
int backlight_init(void)

{
  int iVar1;
 
  iVar1 = gpio_request(0x2e,s_lcd_power_804b8db4);
  if (iVar1 == 0) {
    FUN_801f92f0(0x2e,1);
    iVar1 = gpio_request(0x2d,s_lcd_rst_804b8dc0);
    if (iVar1 == 0) {
      FUN_801f92f0(0x2d,1);
      iVar1 = gpio_request(0x59,s_BL_PWR_804b8dc8);
      if (iVar1 == 0) {
        jz_gpio_set_func(0x59,0);
      }
    }
  }
  return iVar1;
}
« Last Edit: June 20, 2021, 05:10:34 PM by dconrad »
Logged

Offline dconrad

  • Developer
  • Member
  • *
  • Posts: 120
Re: Beginning steps in kernel disassembly and analysis
« Reply #21 on: June 20, 2021, 07:54:43 PM »
I think I have might have the jzmmc_platform_data correctly set up here, or at least... it fits in the space:

Code: [Select]
                             jzmmc_platform_data_80511180                    XREF[1]:     8057287c(*) 
        80511180 02 00 00        jzmmc_pl
                 00 00 00
                 30 00 07
           80511180 02 00           ushort    2h                      removal                           XREF[1]:     8057287c(*) 
           80511182 00 00           ushort    0h                      sdio_clk
           80511184 00 00 30 00     uint      300000h                 ocr_avail
           80511188 07 00 00 00     uint      7h                      capacity
           8051118c 00 00 00 00     uint      0h                      pm_flags
           80511190 00 6c dc 02     uint      2DC6C00h                max_freq
           80511194 00 00 00 00     addr      00000000                *recovery_info
           80511198 b0 11 51 80     addr      card_gpio_805111b0      *gpio         =
           8051119c 00 00 00 00     uint      0h                      pio_mode
           805111a0 00 00 00 00     int       0h                      (*private_in
           805111a4 00 00 00 00     uint      0h                      type
        805111a8 00              ??         00h
        805111a9 00              ??         00h
        805111aa 00              ??         00h
        805111ab 00              ??         00h
        805111ac 00              ??         00h
        805111ad 00              ??         00h
        805111ae 00              ??         00h
        805111af 00              ??         00h
                             card_gpio_805111b0                              XREF[1]:     80511198(*) 
        805111b0 ff ff ff        card_gpio
                 ff 2b 00
                 00 00 2a
           805111b0 ff ff ff ff     jzmmc_pin                         wp                                XREF[1]:     80511198(*) 
              805111b0 ff ff           short     FFFFh                   num                               XREF[1]:     80511198(*) 
              805111b2 ff ff           short     FFFFh                   enable_level
           805111b4 2b 00 00 00     jzmmc_pin                         cd
              805111b4 2b 00           short     2Bh                     num
              805111b6 00 00           short     0h                      enable_level
           805111b8 2a 00 01 00     jzmmc_pin                         pwr
              805111b8 2a 00           short     2Ah                     num
              805111ba 01 00           short     1h                      enable_level
           805111bc ff ff ff ff     jzmmc_pin                         rst
              805111bc ff ff           short     FFFFh                   num
              805111be ff ff           short     FFFFh                   enable_level

per this enum

Code: [Select]
enum {
DONTCARE = 0,
NONREMOVABLE,
REMOVABLE,
MANUAL,
};

the removable value of 2h makes sense.
« Last Edit: June 20, 2021, 07:56:53 PM by dconrad »
Logged

Offline amachronic

  • Developer
  • Member
  • *
  • Posts: 261
Re: Beginning steps in kernel disassembly and analysis
« Reply #22 on: June 22, 2021, 09:13:14 AM »
All that stuff you've got looks sensible and usable. LCD command set looks like MIPI standard so you just copy the initialization commands into rockbox and for sleep mode you can use sleep in/out commands like the M3K does. Get a look at those two lcd_initial functions too:
Code: [Select]
           805147f0 a8 94 01 80 d4  lcd_call                          lcd_callback
                    93 01 80 00 00
                    00 00 00 00 00
              805147f0 a8 94 01 80     addr      800194a8                *lcd_initial
              805147f4 d4 93 01 80     addr      800193d4                *lcd_initial
that may be where you find the power up sequence. Though it seems the backlight code is doing a bit of it too.

FYI, I pulled up the Q1 kernel and the GPIO key data is pointed to from inside the device struct. In the Q1's case the pointer is 104 bytes from the start of the struct, and as it happens the key table got placed right at the end of the device struct. Worth a shot checking if it's the same in your kernel. Here's mine:
Code: [Select]
                             struct gpio_keys_button_ARRAY_806d0c48          XREF[1]:     806d0cf8(*) 
        806d0c48 67 00 00        struct g
                 00 35 00
                 00 00 00
           806d0c48 67 00 00 00 35  struct g                          [0]                               XREF[1]:     806d0cf8(*) 
                    00 00 00 00 00
                    00 00 54 bf 63
              806d0c48 67 00 00 00     uint      67h                     code                              XREF[1]:     806d0cf8(*) 
              806d0c4c 35 00 00 00     int       35h                     gpio
              806d0c50 00 00 00 00     int       0h                      active_low
              806d0c54 54 bf 63 80     char *    s_prev_key_8063bf54     desc          = "prev key"
              806d0c58 00 00 00 00     uint      0h                      type
              806d0c5c 00 00 00 00     int       0h                      wakeup
              806d0c60 0a 00 00 00     int       Ah                      wakeup_event
              806d0c64 00 00 00 00     int       0h                      debounce_int
              806d0c68 00 00 00 00     bool      FALSE                   can_disable
              806d0c6c 00 00 00 00     int       0h                      value
              806d0c70 00 00 00 00     uint      0h                      irq
           806d0c74 6c 00 00 00 36  struct g                          [1]
                    00 00 00 00 00
                    00 00 60 bf 63
              806d0c74 6c 00 00 00     uint      6Ch                     code
              806d0c78 36 00 00 00     int       36h                     gpio
              806d0c7c 00 00 00 00     int       0h                      active_low
              806d0c80 60 bf 63 80     char *    s_next_key_8063bf60     desc          = "next key"
              806d0c84 00 00 00 00     uint      0h                      type
              806d0c88 00 00 00 00     int       0h                      wakeup
              806d0c8c 0a 00 00 00     int       Ah                      wakeup_event
              806d0c90 00 00 00 00     int       0h                      debounce_int
              806d0c94 00 00 00 00     bool      FALSE                   can_disable
              806d0c98 00 00 00 00     int       0h                      value
              806d0c9c 00 00 00 00     uint      0h                      irq
           806d0ca0 8b 00 00 00 3c  struct g                          [2]
                    00 00 00 00 00
                    00 00 6c bf 63
              806d0ca0 8b 00 00 00     uint      8Bh                     code
              806d0ca4 3c 00 00 00     int       3Ch                     gpio
              806d0ca8 00 00 00 00     int       0h                      active_low
              806d0cac 6c bf 63 80     char *    s_menu_key_8063bf6c     desc          = "menu key"
              806d0cb0 00 00 00 00     uint      0h                      type
              806d0cb4 00 00 00 00     int       0h                      wakeup
              806d0cb8 0a 00 00 00     int       Ah                      wakeup_event
              806d0cbc 00 00 00 00     int       0h                      debounce_int
              806d0cc0 00 00 00 00     bool      FALSE                   can_disable
              806d0cc4 00 00 00 00     int       0h                      value
              806d0cc8 00 00 00 00     uint      0h                      irq
           806d0ccc 74 00 00 00 3f  struct g                          [3]
                    00 00 00 00 00
                    00 00 78 bf 63
              806d0ccc 74 00 00 00     uint      74h                     code
              806d0cd0 3f 00 00 00     int       3Fh                     gpio
              806d0cd4 00 00 00 00     int       0h                      active_low
              806d0cd8 78 bf 63 80     char *    s_power_key_8063bf78    desc          = "power key"
              806d0cdc 00 00 00 00     uint      0h                      type
              806d0ce0 01 00 00 00     int       1h                      wakeup
              806d0ce4 0a 00 00 00     int       Ah                      wakeup_event
              806d0ce8 00 00 00 00     int       0h                      debounce_int
              806d0cec 00 00 00 00     bool      FALSE                   can_disable
              806d0cf0 00 00 00 00     int       0h                      value
              806d0cf4 00 00 00 00     uint      0h                      irq
        806d0cf8 48 0c 6d        struct g /* <---- !!! this is what the device struct points to */
                 80 04 00
                 00 00 00
           806d0cf8 48 0c 6d 80     struct g  struct gpio_keys_butto  buttons       =
           806d0cfc 04 00 00 00     int       4h                      nbuttons
           806d0d00 00 00 00 00     uint      0h                      poll_interval
           806d0d04 01 00 00 00     uint:1    1h                      rep
           806d0d08 00 00 00 00     addr      00000000                enable
           806d0d0c 00 00 00 00     addr      00000000                disable
           806d0d10 00 00 00 00     char *    00000000                name
Logged

Offline dconrad

  • Developer
  • Member
  • *
  • Posts: 120
Re: Beginning steps in kernel disassembly and analysis
« Reply #23 on: June 22, 2021, 10:20:11 PM »
Quote from: amachronic on June 22, 2021, 09:13:14 AM
All that stuff you've got looks sensible and usable. LCD command set looks like MIPI standard so you just copy the initialization commands into rockbox and for sleep mode you can use sleep in/out commands like the M3K does. Get a look at those two lcd_initial functions too:
Code: [Select]
           805147f0 a8 94 01 80 d4  lcd_call                          lcd_callback
                    93 01 80 00 00
                    00 00 00 00 00
              805147f0 a8 94 01 80     addr      800194a8                *lcd_initial
              805147f4 d4 93 01 80     addr      800193d4                *lcd_initial
that may be where you find the power up sequence. Though it seems the backlight code is doing a bit of it too.

Good to hear it looks like I've got good code so far. Here's lcd_initialize_begin():

Code: [Select]
undefined4 lcd_initialize_begin(void)

{
  int iVar1;
 
  if (_DAT_805a2290 == 0) {
    gpio_direction_output(0x2e,1);
    iVar1 = 0x14;
    while (iVar1 != 0) {
      FUN_801e69e0(1000);
      iVar1 = iVar1 + -1;
    }
    gpio_direction_output(0x2d,1);
    iVar1 = 0xb;
    while (iVar1 = iVar1 + -1, iVar1 != 0) {
      FUN_801e69e0(1000);
    }
    _DAT_805a2290 = 1;
    return 0;
  }
  return 0;
}

And lcd_initialize_end():

Code: [Select]
undefined4 lcd_initialize_end(void)

{
  if (_DAT_805a2290 != 0) {
    gpio_direction_output(0x2e,0);
    gpio_direction_output(0x2d,0);
    _DAT_805a2290 = 0;
  }
  return 0;
}

I don't quite follow why there is an initialize_begin and initialize_end, it looks like they're just setting pins 0x2e and 0x2d high, and then turning around and setting them low again. Do you know when the _begin and _end functions are run?

I did a quick look to see if I could find an example function to try and figure out what FUN_801e69e0() is, but no luck so far. I suspect it's just a delay function?

Quote
FYI, I pulled up the Q1 kernel and the GPIO key data is pointed to from inside the device struct. In the Q1's case the pointer is 104 bytes from the start of the struct, and as it happens the key table got placed right at the end of the device struct. Worth a shot checking if it's the same in your kernel. Here's mine:
Code: [Select]
                             struct gpio_keys_button_ARRAY_806d0c48          XREF[1]:     806d0cf8(*) 
        806d0c48 67 00 00        struct g
                 00 35 00
                 00 00 00
           806d0c48 67 00 00 00 35  struct g                          [0]                               XREF[1]:     806d0cf8(*) 
                    00 00 00 00 00
                    00 00 54 bf 63
              806d0c48 67 00 00 00     uint      67h                     code                              XREF[1]:     806d0cf8(*) 
              806d0c4c 35 00 00 00     int       35h                     gpio
              806d0c50 00 00 00 00     int       0h                      active_low
              806d0c54 54 bf 63 80     char *    s_prev_key_8063bf54     desc          = "prev key"
              806d0c58 00 00 00 00     uint      0h                      type
              806d0c5c 00 00 00 00     int       0h                      wakeup
              806d0c60 0a 00 00 00     int       Ah                      wakeup_event
              806d0c64 00 00 00 00     int       0h                      debounce_int
              806d0c68 00 00 00 00     bool      FALSE                   can_disable
              806d0c6c 00 00 00 00     int       0h                      value
              806d0c70 00 00 00 00     uint      0h                      irq
           806d0c74 6c 00 00 00 36  struct g                          [1]
                    00 00 00 00 00
                    00 00 60 bf 63
              806d0c74 6c 00 00 00     uint      6Ch                     code
              806d0c78 36 00 00 00     int       36h                     gpio
              806d0c7c 00 00 00 00     int       0h                      active_low
              806d0c80 60 bf 63 80     char *    s_next_key_8063bf60     desc          = "next key"
              806d0c84 00 00 00 00     uint      0h                      type
              806d0c88 00 00 00 00     int       0h                      wakeup
              806d0c8c 0a 00 00 00     int       Ah                      wakeup_event
              806d0c90 00 00 00 00     int       0h                      debounce_int
              806d0c94 00 00 00 00     bool      FALSE                   can_disable
              806d0c98 00 00 00 00     int       0h                      value
              806d0c9c 00 00 00 00     uint      0h                      irq
           806d0ca0 8b 00 00 00 3c  struct g                          [2]
                    00 00 00 00 00
                    00 00 6c bf 63
              806d0ca0 8b 00 00 00     uint      8Bh                     code
              806d0ca4 3c 00 00 00     int       3Ch                     gpio
              806d0ca8 00 00 00 00     int       0h                      active_low
              806d0cac 6c bf 63 80     char *    s_menu_key_8063bf6c     desc          = "menu key"
              806d0cb0 00 00 00 00     uint      0h                      type
              806d0cb4 00 00 00 00     int       0h                      wakeup
              806d0cb8 0a 00 00 00     int       Ah                      wakeup_event
              806d0cbc 00 00 00 00     int       0h                      debounce_int
              806d0cc0 00 00 00 00     bool      FALSE                   can_disable
              806d0cc4 00 00 00 00     int       0h                      value
              806d0cc8 00 00 00 00     uint      0h                      irq
           806d0ccc 74 00 00 00 3f  struct g                          [3]
                    00 00 00 00 00
                    00 00 78 bf 63
              806d0ccc 74 00 00 00     uint      74h                     code
              806d0cd0 3f 00 00 00     int       3Fh                     gpio
              806d0cd4 00 00 00 00     int       0h                      active_low
              806d0cd8 78 bf 63 80     char *    s_power_key_8063bf78    desc          = "power key"
              806d0cdc 00 00 00 00     uint      0h                      type
              806d0ce0 01 00 00 00     int       1h                      wakeup
              806d0ce4 0a 00 00 00     int       Ah                      wakeup_event
              806d0ce8 00 00 00 00     int       0h                      debounce_int
              806d0cec 00 00 00 00     bool      FALSE                   can_disable
              806d0cf0 00 00 00 00     int       0h                      value
              806d0cf4 00 00 00 00     uint      0h                      irq
        806d0cf8 48 0c 6d        struct g /* <---- !!! this is what the device struct points to */
                 80 04 00
                 00 00 00
           806d0cf8 48 0c 6d 80     struct g  struct gpio_keys_butto  buttons       =
           806d0cfc 04 00 00 00     int       4h                      nbuttons
           806d0d00 00 00 00 00     uint      0h                      poll_interval
           806d0d04 01 00 00 00     uint:1    1h                      rep
           806d0d08 00 00 00 00     addr      00000000                enable
           806d0d0c 00 00 00 00     addr      00000000                disable
           806d0d10 00 00 00 00     char *    00000000                name

It sure does look like I have the same thing here:

Code: [Select]
        8050ff40 00              ??         00h
        8050ff41 00              ??         00h
        8050ff42 00              ??         00h
        8050ff43 00              ??         00h
        8050ff44 00              ??         00h
        8050ff45 00              ??         00h
        8050ff46 00              ??         00h
        8050ff47 00              ??         00h
                             gpio_keys_struct_ARRAY_8050ff48[4].active_low   XREF[1,69]:  805100a8(*),
                             gpio_keys_struct_ARRAY_8050ff48                              FUN_80063548:8006354c(*),
                                                                                          FUN_8008aeb0:8008aee4(*),
                                                                                          FUN_800a0864:800a0c6c(*),
                                                                                          FUN_800b20b8:800b1e04(*),
                                                                                          FUN_800b20b8:800b1e08(*),
                                                                                          FUN_800b20b8:800b1e10(*),
                                                                                          FUN_801c1c40:801c1c5c(*),
                                                                                          FUN_8021ad04:8021ad1c(*),
                                                                                          FUN_8021ad2c:8021ad44(*),
                                                                                          FUN_803488b8:8034895c(*),
                                                                                          FUN_80373478:80373478(*),
                                                                                          FUN_80373498:80373498(*),
                                                                                          FUN_80392634:80392664(*),
                                                                                          FUN_803c9a90:803c9ab0(*),
                                                                                          FUN_803d3900:803d3908(*),
                                                                                          FUN_80551ef4:80551f38(*),
                                                                                          FUN_80551ef4:805521b4(*),
                                                                                          FUN_8056a2fc:8056a340(*),
                                                                                          FUN_8056bed4:8056bef8(*) 
        8050ff48 a4 00 00        gpio_key
                 00 10 00
                 00 00 01
           8050ff48 a4 00 00 00 10  gpio_key                          [0]                               XREF[1]:     805100a8(*) 
                    00 00 00 01 00
                    00 00 e4 73 4b
              8050ff48 a4 00 00 00     uint      A4h                     code                              XREF[1]:     805100a8(*) 
              8050ff4c 10 00 00 00     int       10h                     gpio
              8050ff50 01 00 00 00     int       1h                      active_low
              8050ff54 e4 73 4b 80     char *    s_play_key_804b73e4     desc          = "play key"
              8050ff58 01 00 00 00     uint      1h                      type
              8050ff5c 00 00 00 00     int       0h                      wakeup
              8050ff60 00 00 00 00     int       0h                      wakeup_event
              8050ff64 00 00 00 00     int       0h                      debounce_int
              8050ff68 00 00 00 00     bool      FALSE                   can_disable
              8050ff6c 00 00 00 00     int       0h                      value
              8050ff70 00 00 00 00     uint      0h                      irq
           8050ff74 8b 00 00 00 3c  gpio_key                          [1]
                    00 00 00 01 00
                    00 00 f0 73 4b
              8050ff74 8b 00 00 00     uint      8Bh                     code
              8050ff78 3c 00 00 00     int       3Ch                     gpio
              8050ff7c 01 00 00 00     int       1h                      active_low
              8050ff80 f0 73 4b 80     char *    s_menu_key_804b73f0     desc          = "menu key"
              8050ff84 01 00 00 00     uint      1h                      type
              8050ff88 00 00 00 00     int       0h                      wakeup
              8050ff8c 00 00 00 00     int       0h                      wakeup_event
              8050ff90 00 00 00 00     int       0h                      debounce_int
              8050ff94 00 00 00 00     bool      FALSE                   can_disable
              8050ff98 00 00 00 00     int       0h                      value
              8050ff9c 00 00 00 00     uint      0h                      irq
           8050ffa0 9e 00 00 00 65  gpio_key                          [2]
                    00 00 00 01 00
                    00 00 fc 73 4b
              8050ffa0 9e 00 00 00     uint      9Eh                     code
              8050ffa4 65 00 00 00     int       65h                     gpio
              8050ffa8 01 00 00 00     int       1h                      active_low
              8050ffac fc 73 4b 80     char *    s_back_key_804b73fc     desc          = "back key"
              8050ffb0 01 00 00 00     uint      1h                      type
              8050ffb4 00 00 00 00     int       0h                      wakeup
              8050ffb8 00 00 00 00     int       0h                      wakeup_event
              8050ffbc 00 00 00 00     int       0h                      debounce_int
              8050ffc0 00 00 00 00     bool      FALSE                   can_disable
              8050ffc4 00 00 00 00     int       0h                      value
              8050ffc8 00 00 00 00     uint      0h                      irq
           8050ffcc a3 00 00 00 64  gpio_key                          [3]
                    00 00 00 01 00
                    00 00 08 74 4b
              8050ffcc a3 00 00 00     uint      A3h                     code
              8050ffd0 64 00 00 00     int       64h                     gpio
              8050ffd4 01 00 00 00     int       1h                      active_low
              8050ffd8 08 74 4b 80     char *    s_next_key_804b7408     desc          = "next key"
              8050ffdc 01 00 00 00     uint      1h                      type
              8050ffe0 00 00 00 00     int       0h                      wakeup
              8050ffe4 0a 00 00 00     int       Ah                      wakeup_event
              8050ffe8 00 00 00 00     int       0h                      debounce_int
              8050ffec 00 00 00 00     bool      FALSE                   can_disable
              8050fff0 00 00 00 00     int       0h                      value
              8050fff4 00 00 00 00     uint      0h                      irq
           8050fff8 a5 00 00 00 58  gpio_key                          [4]                               XREF[0,69]:  FUN_800289b4:80028dec(*),
                    00 00 00 01 00                                                                                   FUN_80063548:8006354c(*),
                    00 00 14 74 4b                                                                                   FUN_8008aeb0:8008aee4(*),
                                                                                                                     FUN_800a0864:800a0c6c(*),
                                                                                                                     FUN_800b20b8:800b1e04(*),
                                                                                                                     FUN_800b20b8:800b1e08(*),
                                                                                                                     FUN_800b20b8:800b1e10(*),
                                                                                                                     FUN_801c1c40:801c1c5c(*),
                                                                                                                     FUN_8021ad04:8021ad1c(*),
                                                                                                                     FUN_8021ad2c:8021ad44(*),
                                                                                                                     FUN_803488b8:8034895c(*),
                                                                                                                     FUN_80373478:80373478(*),
                                                                                                                     FUN_80373498:80373498(*),
                                                                                                                     FUN_80392634:80392664(*),
                                                                                                                     FUN_803c9a90:803c9ab0(*),
                                                                                                                     FUN_803d3900:803d3908(*),
                                                                                                                     FUN_80551ef4:80551f38(*),
                                                                                                                     FUN_80551ef4:805521b4(*),
                                                                                                                     FUN_8056a2fc:8056a340(*),
                                                                                                                     FUN_8056bed4:8056bef8(*) 
              8050fff8 a5 00 00 00     uint      A5h                     code
              8050fffc 58 00 00 00     int       58h                     gpio
              80510000 01 00 00 00     int       1h                      active_low                        XREF[69]:    FUN_800289b4:80028dec(*),
                                                                                                                        FUN_80063548:8006354c(*),
                                                                                                                        FUN_8008aeb0:8008aee4(*),
                                                                                                                        FUN_800a0864:800a0c6c(*),
                                                                                                                        FUN_800b20b8:800b1e04(*),
                                                                                                                        FUN_800b20b8:800b1e08(*),
                                                                                                                        FUN_800b20b8:800b1e10(*),
                                                                                                                        FUN_801c1c40:801c1c5c(*),
                                                                                                                        FUN_8021ad04:8021ad1c(*),
                                                                                                                        FUN_8021ad2c:8021ad44(*),
                                                                                                                        FUN_803488b8:8034895c(*),
                                                                                                                        FUN_80373478:80373478(*),
                                                                                                                        FUN_80373498:80373498(*),
                                                                                                                        FUN_80392634:80392664(*),
                                                                                                                        FUN_803c9a90:803c9ab0(*),
                                                                                                                        FUN_803d3900:803d3908(*),
                                                                                                                        FUN_80551ef4:80551f38(*),
                                                                                                                        FUN_80551ef4:805521b4(*),
                                                                                                                        FUN_80558aa8:80558b3c(*),
                                                                                                                        FUN_8056a2fc:8056a340(*), [more]
              80510004 14 74 4b 80     char *    s_prev_key_804b7414     desc          = "prev key"
              80510008 01 00 00 00     uint      1h                      type
              8051000c 00 00 00 00     int       0h                      wakeup
              80510010 0a 00 00 00     int       Ah                      wakeup_event
              80510014 00 00 00 00     int       0h                      debounce_int
              80510018 00 00 00 00     bool      FALSE                   can_disable
              8051001c 00 00 00 00     int       0h                      value
              80510020 00 00 00 00     uint      0h                      irq
           80510024 72 00 00 00 13  gpio_key                          [5]
                    00 00 00 01 00
                    00 00 20 74 4b
              80510024 72 00 00 00     uint      72h                     code
              80510028 13 00 00 00     int       13h                     gpio
              8051002c 01 00 00 00     int       1h                      active_low
              80510030 20 74 4b 80     char *    s_volum_down_key_804b7  desc          = "volum down key"
              80510034 01 00 00 00     uint      1h                      type
              80510038 00 00 00 00     int       0h                      wakeup
              8051003c 00 00 00 00     int       0h                      wakeup_event
              80510040 00 00 00 00     int       0h                      debounce_int
              80510044 00 00 00 00     bool      FALSE                   can_disable
              80510048 00 00 00 00     int       0h                      value
              8051004c 00 00 00 00     uint      0h                      irq
           80510050 73 00 00 00 11  gpio_key                          [6]
                    00 00 00 01 00
                    00 00 30 74 4b
              80510050 73 00 00 00     uint      73h                     code
              80510054 11 00 00 00     int       11h                     gpio
              80510058 01 00 00 00     int       1h                      active_low
              8051005c 30 74 4b 80     char *    s_volum_up_key_804b7430 desc          = "volum up key"
              80510060 01 00 00 00     uint      1h                      type
              80510064 00 00 00 00     int       0h                      wakeup
              80510068 00 00 00 00     int       0h                      wakeup_event
              8051006c 00 00 00 00     int       0h                      debounce_int
              80510070 00 00 00 00     bool      FALSE                   can_disable
              80510074 00 00 00 00     int       0h                      value
              80510078 00 00 00 00     uint      0h                      irq
           8051007c 74 00 00 00 27  gpio_key                          [7]
                    00 00 00 01 00
                    00 00 40 74 4b
              8051007c 74 00 00 00     uint      74h                     code
              80510080 27 00 00 00     int       27h                     gpio
              80510084 01 00 00 00     int       1h                      active_low
              80510088 40 74 4b 80     char *    s_backlight_key_804b7440 desc          = "backlight key"
              8051008c 00 00 00 00     uint      0h                      type
              80510090 01 00 00 00     int       1h                      wakeup
              80510094 00 00 00 00     int       0h                      wakeup_event
              80510098 00 00 00 00     int       0h                      debounce_int
              8051009c 00 00 00 00     bool      FALSE                   can_disable
              805100a0 00 00 00 00     int       0h                      value
              805100a4 00 00 00 00     uint      0h                      irq
                             nbuttons (805100a8+4)                           XREF[1]:     8050fe08(*) 
                             poll_interval (805100a8+8)
                             gpio_summary_struct_805100a8
        805100a8 48 ff 50        gpio_sum
                 80 08 00
                 00 00 00
           805100a8 48 ff 50 80     addr      gpio_keys_struct_ARRAY  field_0x0     =                   XREF[1]:     8050fe08(*) 
           805100ac 08 00 00 00     int       8h                      nbuttons
           805100b0 00 00 00 00     uint      0h                      poll_interval
           805100b4 00 00 00 00     uint:1    0h                      rep
           805100b8 00 00 00 00     addr      00000000                enable
           805100bc 00 00 00 00     addr      00000000                disable
           805100c0 00 00 00 00     char *    00000000                name
        805100c4 00              ??         00h
        805100c5 00              ??         00h
        805100c6 00              ??         00h
        805100c7 00              ??         00h
        805100c8 00              ??         00h
        805100c9 00              ??         00h
        805100ca 00              ??         00h
        805100cb 00              ??         00h

I also found some miscellaneous gpio values by searching for the known gpio functions, but that can go in another post (our power went out a little bit ago, don't want to lose my progress...)
Logged

Offline dconrad

  • Developer
  • Member
  • *
  • Posts: 120
Re: Beginning steps in kernel disassembly and analysis
« Reply #24 on: June 22, 2021, 11:11:36 PM »
In the same vein, here's some ring key structs built from arch/mips/xburst/soc-x1000/chip-x1000/idriver/common/sa_keypad_ring.h. A lot (not all) of this idriver stuff seems to be applicable:

Code: [Select]
                             ring_keys_platform_data_8050fd38                XREF[1]:     8050f830(*) 
        8050fd38 68 fd 50        ring_key
                 80 02 00
                 00 00 00
           8050fd38 68 fd 50 80     addr      ring_keys_button_8050f  *buttons      =                   XREF[1]:     8050f830(*) 
           8050fd3c 02 00 00 00     int       2h                      nbuttons
           8050fd40 00 00 00 00     uint      0h                      poll_interval
           8050fd44 00 00 00 00     uint:1    0h                      rep:1
           8050fd48 64 00 00 00     uint      64h                     timer_debounce
           8050fd4c 37 00 00 00     int       37h                     ring1_gpio
           8050fd50 38 00 00 00     int       38h                     ring2_gpio
           8050fd54 00 00 00 00     addr      00000000                *enable
           8050fd58 00 00 00 00     addr      00000000                *disable
           8050fd5c 00 00 00 00     char *    00000000                *name
                             DAT_8050fd60                                    XREF[1]:     8050fd2c(*) 
        8050fd60 00              ??         00h
        8050fd61 00              ??         00h
        8050fd62 00              ??         00h
        8050fd63 00              ??         00h
        8050fd64 84              ??         84h                                              ?  ->  804b7384
        8050fd65 73              ??         73h    s
        8050fd66 4b              ??         4Bh    K
        8050fd67 80              ??         80h
                             ring_keys_button_8050fd68                       XREF[1]:     8050fd38(*) 
        8050fd68 69 00 00        ring_key
                 00 c0 73
                 4b 80 02
           8050fd68 69 00 00 00     uint      69h                     code                              XREF[1]:     8050fd38(*) 
           8050fd6c c0 73 4b 80     char *    s_ring_left_804b73c0    *desc         = "ring left"
           8050fd70 02 00 00 00     int       2h                      direction
           8050fd74 00 00 00 00     int       0h                      wakeup
           8050fd78 00 00 00 00     bool      FALSE                   can_disable
        8050fd7c 6a 00 00        ring_key
                 00 cc 73
                 4b 80 01
           8050fd7c 6a 00 00 00     uint      6Ah                     code
           8050fd80 cc 73 4b 80     char *    s_ring_right_804b73cc   *desc         = "ring right"
           8050fd84 01 00 00 00     int       1h                      direction
           8050fd88 00 00 00 00     int       0h                      wakeup
           8050fd8c 00 00 00 00     bool      FALSE                   can_disable
                             DAT_8050fd90                                    XREF[1]:     FUN_802c2dd4:802c2fcc(*) 
        8050fd90 39              ??         39h    9
        8050fd91 00              ??         00h
        8050fd92 01              ??         01h
        8050fd93 00              ??         00h
Logged

Offline dconrad

  • Developer
  • Member
  • *
  • Posts: 120
Re: Beginning steps in kernel disassembly and analysis
« Reply #25 on: June 22, 2021, 11:30:28 PM »
In no particular order, here's a small assortment of things I think I've ID'd:

Bluetooth Power Init:

Code: [Select]
int power_init(void)

{
  int iVar1;
 
  iVar1 = gpio_request(0x53,s_bt_reg_on_804b7610);
  if (iVar1 == 0) {
    gpio_direction_output(0x53,0);
  }
  return iVar1;
}

RTC init (though I imagine it's identical to the m3k and q1:

Code: [Select]
void rtc32k_init(void)

{
  int iVar1;
 
  _DAT_805a2280 = 0;
  iVar1 = gpio_request(0x3a,s_rtc32k_804b8ce0);
  if (iVar1 == 0) {
    _DAT_805a2284 = 1;
  }
  else {
    pr_notice(s_[Error]_request_rtc32k_gpio_fail_804b8ce8);
  }
  return;
}

snd_[something]_probe():

Code: [Select]
int snd_x_probe(int param_1)

{
  int iVar1;
 
  DAT_805454c0 = param_1 + 0x10;
  iVar1 = FUN_8034e318();
  if (iVar1 != 0) {
    dev_err(param_1 + 0x10,s_snd_soc_register_card_failed_%d_804fb778,iVar1);
  }
  iVar1 = gpio_request(0x28,s_HP_Mute_804fb79c);
  if (iVar1 == 0) {
    gpio_direction_output(0x28,0);
  }
  iVar1 = gpio_request(0x29,s_LO_Power_804fb7a4);
  if (iVar1 == 0) {
    gpio_direction_output(0x29,0);
  }
  iVar1 = gpio_request(0x2c,s_DAC_Mute_804fb7b0);
  if (iVar1 == 0) {
    gpio_direction_output(0x2c,0);
  }
  iVar1 = gpio_request(0x26,s_Analog_power_804fb7bc);
  if (iVar1 == 0) {
    gpio_direction_output(0x26,0);
  }
  iVar1 = gpio_request(0x25,s_out_sel_804fb7cc);
  if (iVar1 == 0) {
    gpio_direction_output(0x25,0);
  }
  iVar1 = gpio_request(0x2f,s_out_mute_804fb7d4);
  if (iVar1 == 0) {
    gpio_direction_output(0x2f,1);
  }
  iVar1 = gpio_request(0x35,s_spdif_en_804fb7e0);
  if (iVar1 == 0) {
    gpio_direction_output(0x35,0);
  }
  return iVar1;
}

And the fact that apparently we have jzmmc_v1.2:

Code: [Select]
                             s_jzmmc_v1.2_804b8c6c                           XREF[1]:     80513d10(*) 
        804b8c6c 6a 7a 6d        ds         "jzmmc_v1.2"
                 6d 63 5f
                 76 31 2e
Logged

Offline amachronic

  • Developer
  • Member
  • *
  • Posts: 261
Re: Beginning steps in kernel disassembly and analysis
« Reply #26 on: June 23, 2021, 03:59:06 PM »
Your snd_x_probe has got to be the DAC/amp driver. But you probably guessed that already :).

The "ring keys" confused me... but I looked up a review and it seems this player uses a rotating wheel -- right? -- so that'd be a rotary encoder. You've got all button GPIOs. The menu key is the one you hold to enter USB boot mode (due to it being on GPIO B28, see x1000 manual secs 27.1 and 19.3.2). The LCD looks straightforward. The current Rockbox driver should work, although I'm not 100% certain how the 24 bit depth is handled because I never tested it. That might require some trial and error if it doesn't work the first try, since the x1000 manual is next to useless when it comes to pixel formats, what gets sent on the bus and why.

By the way, lcd_initialize_begin/end get called to power the panel on and off. Not sure exactly where and when they are called but their purpose seems clear enough.

I think you have pretty much everything you need to do a port. The pin labels seem clear enough that you can just guess where they go just based on the chip datasheets. Well, except for spdif_en. I can't make heads or tails of that. There's nothing SPDIF-related on this player, is there?

Oh, and did you find out the i2c bus layout yet? it's in board_base_init, those two calls near the end. What i2c chips are you expecting anyway? AXP192 is there, so aside from that is it just the DAC?
Logged

Offline dconrad

  • Developer
  • Member
  • *
  • Posts: 120
Re: Beginning steps in kernel disassembly and analysis
« Reply #27 on: June 23, 2021, 04:38:51 PM »
Quote from: amachronic on June 23, 2021, 03:59:06 PM
Your snd_x_probe has got to be the DAC/amp driver. But you probably guessed that already :).

The "ring keys" confused me... but I looked up a review and it seems this player uses a rotating wheel -- right? -- so that'd be a rotary encoder. You've got all button GPIOs. The menu key is the one you hold to enter USB boot mode (due to it being on GPIO B28, see x1000 manual secs 27.1 and 19.3.2). The LCD looks straightforward. The current Rockbox driver should work, although I'm not 100% certain how the 24 bit depth is handled because I never tested it. That might require some trial and error if it doesn't work the first try, since the x1000 manual is next to useless when it comes to pixel formats, what gets sent on the bus and why.

By the way, lcd_initialize_begin/end get called to power the panel on and off. Not sure exactly where and when they are called but their purpose seems clear enough.

I think you have pretty much everything you need to do a port. The pin labels seem clear enough that you can just guess where they go just based on the chip datasheets. Well, except for spdif_en. I can't make heads or tails of that. There's nothing SPDIF-related on this player, is there?

Oh, and did you find out the i2c bus layout yet? it's in board_base_init, those two calls near the end. What i2c chips are you expecting anyway? AXP192 is there, so aside from that is it just the DAC?

Yeah, the ring keys are the wheel, sorry I probably should have mentioned that!

It looks to me like the PCM5102A is only configured through discrete pins, and doesn't actually have any sort of serial configuration interface. It's "dumb" - just feed it I2S data and it does DAC things.

I wasn't sure if maybe lcd_initialize_begin/end were called one after another for some reason - lcd_initialize_end seems like a weird way to say "power off".

I do still need to try to get some info out of the I2C section - I haven't gotten that far yet. I think the AXP192 might be the only I2C device, unless the bluetooth controller is hooked up via I2C.

I was just starting to make a list of stuff to see what we have and how much more info is needed - I haven't really been keeping track while I've been digging for info. Although I suppose a lot of stuff could be glossed over in favor of just getting something to work first.

Quote
spdif

Yeah, I have no idea what that's about. Bluetooth maybe? I don't think there's an S/PDIF out on this...
« Last Edit: June 23, 2021, 04:41:32 PM by dconrad »
Logged

Offline dconrad

  • Developer
  • Member
  • *
  • Posts: 120
Re: Beginning steps in kernel disassembly and analysis
« Reply #28 on: June 23, 2021, 04:48:07 PM »
Maybe you could comment on whether these are X1000 standard / dedicated hw connections? I don't think I need to find pin number information for:

Flash
LCD controller data
I2C (do need to know bus/address)
SD Card
Logged

Offline amachronic

  • Developer
  • Member
  • *
  • Posts: 261
Re: Beginning steps in kernel disassembly and analysis
« Reply #29 on: June 23, 2021, 06:50:49 PM »
Yep, all the interface pins are set in stone. There's no need to track any of those down, they're in the X1000 datasheet. You're right about the DAC, I had assumed it's I2C but after looking at the datasheet it is in fact "dumb pins." That kinda works out in your favor since there's less to twiddle with to get audio going.

I was looking over all the stuff you posted and everything important should be here. There might be some audio related pins missing, but it's hard to tell at a glance. LCD and buttons are the 2 biggest target-specific drivers, ironically. GPIOs are the biggest platform dependent thing when it comes to other drivers. Your flash is the same chip used in the M3K so it's supported already. The AXP192 is probably on I2C bus#2 and its address is fixed; so if that's the only I2C device, it's not really necessary to seek out that info.
Code: [Select]
LCD
---
24 bpp
8 bit bus
320x240
80 fps

power on
---
- PWR -> 1
- wait 20 ms
- RST -> 1
- wait 12 ms

power off
---
- PWR -> 0
- RST -> 0

backlight
---------
pwm0
30,000 ns period

gpios
-----
0x10 play key
0x11 volume up key
0x13 volume down key
0x25 out sel
0x26 analog power
0x27 backlight key
0x28 hp mute
0x29 lo power
0x2a msc pwr
0x2b msc cd
0x2c dac mute
0x2d lcd rst
0x2e lcd power
0x2f out mute
0x35 spdif en
0x37 ring1
0x38 ring2
0x3a rtc32k
0x3c menu key
0x53 bt reg on
0x58 prev key
0x59 BL PWR
0x64 next key
0x65 back key
It would be useful to find the AXP192 interrupt GPIO, but the Rockbox AXP driver can't use it yet. Headphone detection is usually wired to the AXP and I was planning to attach that to an interrupt instead of polling every 1/2 second like it currently does, but that's hardly super-important.

For the time being if you want to try running any code on your actual player you'll have to copy the M3K's SPL and monkey patch it until it works... the support is there for 32M memory size but it's totally untested and may be broken. There's another patch you need to do in order to USB boot Rockbox. Basically you just have to add these lines from the Q1 patch in order to initialize the system clocks when you directly boot rockbox.bin over USB.

The current early boot situation is far from ideal, and pretty hard to understand in its current form (even for me, and I wrote it, lol). I'm in the middle of rewriting all the X1000 NAND code, and then I have to refactor the SPL stuff to allow for code re-use between the M3K and Q1. But anyhow, if you have trouble getting rockbox to boot, whenever you decide to do it, then let me know.
Logged

  • Print
Pages: 1 [2] 3
« previous next »
+  Rockbox Technical Forums
|-+  Rockbox Development
| |-+  Starting Development and Compiling
| | |-+  Beginning steps in kernel disassembly and analysis
 

  • SMF 2.0.19 | SMF © 2021, Simple Machines
  • Rockbox Privacy Policy
  • XHTML
  • RSS
  • WAP2

Page created in 0.036 seconds with 17 queries.