Project

General

Profile

Issue #2234

Issue #1954: Add support for the I9300 modem

ipc-modem doesn't call with the replicant 11 kernel

Added by Denis 'GNUtoo' Carikli 6 months ago. Updated 3 months ago.

Status:
New
Priority:
Normal
Category:
Telephony and mobile data
Target version:
Start date:
03/17/2021
Due date:
% Done:

0%

Estimated time:
Resolution:
Device:
Galaxy S 3 (I9300)
Grant:
Porting Replicant to Android 9 (NLnet Foundation)
Type of work:
Any programming languages (scripts, C, etc), C programming, Unknown

Files

ipc-modem-gnulinux.log (3.78 KB) ipc-modem-gnulinux.log Denis 'GNUtoo' Carikli, 03/17/2021 02:52 PM
ipc-modem-replicant.log (29.5 KB) ipc-modem-replicant.log Denis 'GNUtoo' Carikli, 03/18/2021 02:42 PM
gpio-smdk4412.txt (3.6 KB) gpio-smdk4412.txt Denis 'GNUtoo' Carikli, 03/25/2021 01:34 PM
gpio-replicant-11-kernel.txt (6.68 KB) gpio-replicant-11-kernel.txt Denis 'GNUtoo' Carikli, 03/25/2021 01:54 PM
#1

Updated by Denis 'GNUtoo' Carikli 6 months ago

  • Type of work Any programming languages (scripts, C, etc), C programming added

I've moved that bug here as this way I'll be able to upload logs here

#2

Updated by Denis 'GNUtoo' Carikli 6 months ago

On GNU/Linux I run the following Makefile (with xxxxxxxxxx replaced by my phone number):

.PHONY: all
all:
    test -f /efs/nv_data.bin || mount /dev/disk/by-partlabel/EFS /efs/
    make -C libsamsung-ipc install
    ipc-modem --debug --call xxxxxxxxxx start

#5

Updated by Denis 'GNUtoo' Carikli 6 months ago

On Replicant I did the following:

modem.sh off # it then rebooted
ipc-modem --debug --call XXXXXXXXXX start

In both cases I tried to make ipc-modem be the first program that boots the modem after the device boot.

#6

Updated by Denis 'GNUtoo' Carikli 6 months ago

In the case of Replicant 6, the modem is booted somehow, then IPC_SMS_DEVICE_READY is received, then it proced to set the modem to normal/full power:

void modem_response_sms(struct ipc_client *client, struct ipc_message *resp)
{
        switch (resp->command) {
        case IPC_SMS_DEVICE_READY:
                if (state ==  MODEM_STATE_LPM) {
                        printf("[4] " 
                               "Modem is ready, requesting normal power mode" 
                               "\n");
                        modem_exec_power_normal(client);
                } else if (state == MODEM_STATE_SIM_OK) {
                        printf("[5] Modem is fully ready\n");
                        modem_set_sms_device_ready(client);
                }
                break;
        }
}

With the Replicant 11 kernel (under GNU/Linux) IPC_SMS_DEVICE_READY is not received.

#7

Updated by Victor Shilin 6 months ago

Denis 'GNUtoo' Carikli, by any chance, did anyone test the modem on the original dev branch of the kernel / libsamsung-ipc by Simon Shields?
(https://github.com/fourkbomb/linux/commits/modem and https://github.com/fourkbomb/android_external_libsamsung-ipc/commit/7009453083f1b769f6c2a2dc31bc2f9a8a2d3c36).
I don't currently have a Linux distro installed on my devices, just was curious if any of this is worth checking.

#8

Updated by Denis 'GNUtoo' Carikli 6 months ago

Denis 'GNUtoo' Carikli, by any chance, did anyone test the modem on the original dev branch of the kernel / libsamsung-ipc by Simon Shields?
(https://github.com/fourkbomb/linux/commits/modem and https://github.com/fourkbomb/android_external_libsamsung-ipc/commit/7009453083f1b769f6c2a2dc31bc2f9a8a2d3c36).
I don't currently have a Linux distro installed on my devices, just was curious if any of this is worth checking.

It's definitely worth checking, I've made so many change since then, including some changes on the GPIOs API.

I also plan to check that. I've already started looking into the differences GPIO wise.

#9

Updated by Denis 'GNUtoo' Carikli 6 months ago

I will also look into the state after booting the modem and document it below.

It is also being updated as tests and implementations progress.

Type Kernel Comments
SMDK 4412 Replicant 11
Name definition State after modem boot Name definition State after modem boot
dummy function Link LDO Enable? TODO: find the real imeplementation
GPIO CP_ON out low cp-on out low
CP_RST out high cp-reset out high
RESET_REQ_N out high reset-req? out high
PDA_ACTIVE out high pda-active out high
PHONE_ACTIVE out high phone-active in high IRQ
LINK_ACTIVE out high link-active out high
HOSTWAKE out high link-hostwake in high IRQ implementation WIP, replaced with sleep
SLAVEWAKE out low link-slavewake out high
AP_DUMP_INT EXYNOS4212_GPJ0(1) out low ap-dump out low
CP_DUMP_INT in low cp-dump in low
SUS_REQ EXYNOS4212_GPM2(4) out low suspend-req out high
Reverse Bias clear Find what it is used for
Reverse Bias restore Find what it is used for
#11

Updated by Denis 'GNUtoo' Carikli 6 months ago

  • File gpio-replicant-11-kernel.txt added
#12

Updated by Denis 'GNUtoo' Carikli 6 months ago

  • File deleted (gpio-replicant-11-kernel.txt)
#14

Updated by Denis 'GNUtoo' Carikli 6 months ago

For some reasons setting suspend-req to low fails, it become high during the modem boot process (like around the last modem power on).

That's even with the gpiohack driver modified to never set it high.

Even forcing it to low from userspace make it stay high at the end.

Even modifying the dts with:

- PIN_SLP(gpm2-4, INPUT, DOWN)
+ PIN_SLP(gpm2-4, OUTPUT, DOWN)

produces the same result.

Instead on Replicant 6 it indeed stays low during/after the modem boot...

#15

Updated by Denis 'GNUtoo' Carikli 6 months ago

For the modem branch of forkbomb, it doesn't build and I got the same error after rebasing it on v4.16.18:

  HOSTCC  scripts/selinux/genheaders/genheaders
In file included from scripts/selinux/genheaders/genheaders.c:19:
./security/selinux/include/classmap.h:247:2: error: #error New address family defined, please update secclass_map.
  247 | #error New address family defined, please update secclass_map.
      |  ^~~~~
make[3]: *** [scripts/Makefile.host:90: scripts/selinux/genheaders/genheaders] Error 1
make[3]: Target '__build' not remade because of errors.
make[2]: *** [scripts/Makefile.build:583: scripts/selinux/genheaders] Error 2
  HOSTCC  scripts/selinux/mdp/mdp
In file included from scripts/selinux/mdp/mdp.c:49:
./security/selinux/include/classmap.h:247:2: error: #error New address family defined, please update secclass_map.
  247 | #error New address family defined, please update secclass_map.
      |  ^~~~~
make[3]: *** [scripts/Makefile.host:90: scripts/selinux/mdp/mdp] Error 1
make[3]: Target '__build' not remade because of errors.
make[2]: *** [scripts/Makefile.build:583: scripts/selinux/mdp] Error 2
make[2]: Target '__build' not remade because of errors.
make[1]: *** [scripts/Makefile.build:583: scripts/selinux] Error 2
  HOSTCC  scripts/kallsyms

I'll also try to look into it, probably disabling selinux would fix that. Since I've a device with GNU/Linux that should be easy to run.

#16

Updated by Denis 'GNUtoo' Carikli 6 months ago

And I've also that error:

  HOSTLD  scripts/dtc/dtc
/usr/bin/ld: scripts/dtc/dtc-parser.tab.o:(.bss+0x4): multiple definition of `yylloc'; scripts/dtc/dtc-lexer.lex.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status

This looks harder to fix. Though builds works with the Replicant kernel, so maybe using the host dtc compiler or updating it in Linux or rebasing would fix it.

#17

Updated by Denis 'GNUtoo' Carikli 5 months ago

Ah I didn't notice before but

- PIN_SLP(gpm2-4, INPUT, DOWN)
+ PIN_SLP(gpm2-4, OUTPUT, DOWN)

didn't compile.

OUTPUT isn't valid, it's rather something like OUT0, OUT1, etc.

#18

Updated by Denis 'GNUtoo' Carikli 4 months ago

Changing PIN_SLP doesn't seem to change anything.

Also I've tried to change the state (high->low or low->high) of that GPIO both in userspace and in the kernel in both kernel (smdk and replicant-11) and it didn't change anything in /sys/kernel/debug/gpio.

I've also tried to compile the ubuntu 3.18 kernel from ChronoMonoChrome and so far I identified the commit that broke compilation: e33a814e772c scripts/dtc: Remove redundant YYLOC global declaration, but the issue is that it depends on e039139be8c2 scripts/dtc: generate lexer and parser during build instead of shipping which then depends on other commits. So I've not yet manage to backport that to 3.18.

I'll also try to find the oldest forkbomb kernel / modem branch and backport theses fixes there to try that.

In the meantime I've also started to work on the libsamsung-ipc part to move the GPIOs handling there (at least temporarily) to have a common code between the smdk i9300 driver and the one that works with the replicant 11 kernel, and I've been experimenting a bit with a driver model like the one in Linux while I was at it, in order to have more similar code between the two libsamsung-ipc device drivers.

Also after disabling the aat1290 dts node I've found that the following makes the flash blink once (in Parabola, with the Replicant 11 kernel):

gpioset gpj1 2=0
gpioset gpj1 1=0
gpioset gpj1 1=1

So I'll be able to test code to change GPIO status, dump their status (and possibly the pinmux status as well) more easily with that.

#19

Updated by Denis 'GNUtoo' Carikli 4 months ago

With the following commits:

We got:

ipc-modem --debug --call=XXXXXXXXXX start
[I] Debug enabled
[I] Got call number!
[0] Starting modem on FMT client
[D] Starting n7100 modem boot
[D] Opened modem image device
[D] Mapped modem image data to memory
[D] Turned the modem off
0
0
[D] Turned the modem on
[D] Opened modem boot device
[D] Wrote ATAT in ASCII
[D] Read chip id (0x16)
[D] Wrote PSI header
[D] Wrote PSI, CRC is 0xc8
[D] Wrote PSI CRC (0xc8)
[D] Read PSI CRC ACK
[D] Read PSI ACK
[D] Sent XMM626 HSIC PSI
[D] Wrote EBL size
[D] Wrote EBL, CRC is 0xb5
[D] Wrote EBL CRC (0xb5)
[D] Sent XMM626 HSIC EBL
[D] Read port config
[D] Sent XMM626 HSIC port config
[D] Sent XMM626 HSIC SEC start
[D] Sent XMM626 HSIC firmware
[D] Checked nv_data path
[D] Checked nv_data md5 path
[D] Calculated nv_data md5: 50e04bd1ae13445977f3aec356ada08d
[D] Read nv_data md5: 50e04bd1ae13445977f3aec356ada08d
[D] Checked nv_data backup path
[D] Loaded nv_data
[D] Sent XMM626 HSIC nv_data
[D] Sent XMM626 HSIC SEC end
[D] Sent XMM626 HSIC HW reset
[D] Waiting for host wake failed
[D] Waited for host wake
[D] Waited for link connected
[D] (null) completed succesfully
/dev/umts_ipc: -1 2
/dev/umts_ipc: -1 19
/dev/umts_ipc: -1 19
/dev/umts_ipc: -1 19
/dev/umts_ipc: -1 19
/dev/umts_ipc: -1 19
/dev/umts_ipc: -1 19
/dev/umts_ipc: -1 19
[1] Starting modem_read_loop on FMT client
poll returns 1
[D] xmm626_sec_modem_fmt_recv: Received FMT message
[D] xmm626_sec_modem_fmt_recv: Message: aseq=0xff, command=IPC_PWR_PHONE_PWR_UP, type=IPC_TYPE_NOTI, size=0
[2] Phone is powered up (LPM)!
poll returns 1
[D] xmm626_sec_modem_fmt_recv: Received FMT message
[D] xmm626_sec_modem_fmt_recv: Message: aseq=0x00, command=IPC_MISC_ME_IMSI, type=IPC_TYPE_NOTI, size=16
[D] ================================= IPC FMT data =================================
[D] [0000]   XX XX XX XX XX XX XX XX  XX XX XX XX XX XX XX XX   XXXXXXXX XXXXXXXX

So no calls and the device is still in LPM mode...

Since forkbomb's 4.16 doesn't work out of the box we need to investigate more the pads and GPIOs.

I wonder if both code could work in a single kernel somehow.

Maybe it could be possible to backport the 4.16 modem stack to ChronoMonoChrome 3.18 kernel, or maybe I need to instead diff all the GPIO and pad configs at the hardware level.

#20

Updated by Denis 'GNUtoo' Carikli 4 months ago

When enabling /dev/(k)mem without any restrictions, with Parabola we can easily see the GPIOs changes:

# devmem2 0x11400260 w
/dev/mem opened.
Memory mapped at address 0xb6f56000.
Value at address 0x11400260 (0xb6f56260): 0x2000
# gpioset gpj1 1=1
# devmem2 0x11400260 w
/dev/mem opened.
Memory mapped at address 0xb6fea000.
Value at address 0x11400260 (0xb6fea260): 0x2010

And we can decode the value:

$ python
Python 3.9.4 (default, Apr 25 2021, 17:06:22) 
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> (0x2010 & 0b111111110000)  >> 4
1
>>> 

And in the Exynos 4412 manual we have:

GPJ1CON
  • Base Address: 0x1140_0000
  • Address = Base Address + 0x0260, Reset Value = 0x0000_0000
    Name Bit Type Description Reset Value
    [...]
    GPJ1CON1 [7:4] RW 0x0 = Input
    0x1 = Output
    [...]
    0x00

PS: it was edited short after to fix the table formating

#21

Updated by Denis 'GNUtoo' Carikli 3 months ago

I've finally managed to finish the test tool (by repurposing devmem2.c for the memory access).

Here's what I have on Replicant 6 when calling a number that didn't hangup nor pick up yet:

root@i9300:/ # exynos-gpio-tool modem                                                                               
dump_modem_gpio_infos: dump_gpio_infos: cp-on
dump_gpio_infos: gpl2[5]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: cd-reset
dump_gpio_infos: gpx3[2]: {
  GPIO_OUTPUT
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_PULLDOWN_DISABLE
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: cd-dump
dump_gpio_infos: gpx1[2]: {
  GPIO_INPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: phone-active
dump_gpio_infos: gpx1[6]: {
  0xf
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: reset-req
dump_gpio_infos: gpm3[3]: {
  GPIO_OUTPUT
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: pda-active
dump_gpio_infos: gpf1[6]: {
  GPIO_OUTPUT
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: link-active
dump_gpio_infos: gpf1[1]: {
  GPIO_OUTPUT
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: link-hostwake
dump_gpio_infos: gpx1[1]: {
  0xf
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: link-slavewake
dump_gpio_infos: gpx1[0]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: suspend-req
dump_gpio_infos: gpm2[4]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_PULLDOWN_DISABLE
  GPIO_DRIVE_1X
}

#22

Updated by Denis 'GNUtoo' Carikli 3 months ago

With GNU/Linux and a kernel based on forkbomb's source code we have:

dump_modem_gpio_infos: dump_gpio_infos: cp-on
dump_gpio_infos: gpl2[5]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: cd-reset
dump_gpio_infos: gpx3[2]: {
  GPIO_OUTPUT
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: cd-dump
dump_gpio_infos: gpx1[2]: {
  GPIO_INPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: phone-active
dump_gpio_infos: gpx1[6]: {
  0xf
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: reset-req
dump_gpio_infos: gpm3[3]: {
  GPIO_OUTPUT
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: pda-active
dump_gpio_infos: gpf1[6]: {
  GPIO_OUTPUT
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: link-active
dump_gpio_infos: gpf1[1]: {
  GPIO_OUTPUT
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: link-hostwake
dump_gpio_infos: gpx1[1]: {
  0xf
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: link-slavewake
dump_gpio_infos: gpx1[0]: {
  GPIO_OUTPUT
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}
dump_modem_gpio_infos: dump_gpio_infos: suspend-req
dump_gpio_infos: gpm2[4]: {
  GPIO_OUTPUT
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
}

#23

Updated by Denis 'GNUtoo' Carikli 3 months ago

I used meld between both captures and we have:
GPIO Replicant 6 Parabola
cd-reset GPIO_RESISTORS_PULLDOWN_DISABLE GPIO_RESISTORS_ENABLE_PULL_DOWN
link-slavewake GPIO_VALUE_LOW GPIO_VALUE_HIGH
suspend-req GPIO_VALUE_LOW GPIO_VALUE_HIGH
GPIO_RESISTORS_PULLDOWN_DISABLE GPIO_RESISTORS_ENABLE_PULL_DOWN

Note that I didn't implement yet dumping the sleep states of the pins.

#24

Updated by Denis 'GNUtoo' Carikli 3 months ago

With the modem disabled on Replicant 6.0 0004 rc5, adding a SIM and a battery and booting we have that:

dump_modem_gpio_infos: dump_gpio_infos: cp-on
dump_gpio_infos: gpl2[5]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: cp-reset
dump_gpio_infos: gpx3[2]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: ap-dump
dump_gpio_infos: gpj0[1]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: cp-dump
dump_gpio_infos: gpx1[2]: {
  GPIO_INPUT
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: phone-active
dump_gpio_infos: gpx1[6]: {
  0xf
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: reset-req
dump_gpio_infos: gpm3[3]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_HIGH
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: pda-active
dump_gpio_infos: gpf1[6]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: link-active
dump_gpio_infos: gpf1[1]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: link-hostwake
dump_gpio_infos: gpx1[1]: {
  0xf
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: link-slavewake
dump_gpio_infos: gpx1[0]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: suspend-req
dump_gpio_infos: gpm2[4]: {
  GPIO_OUTPUT
  GPIO_VALUE_HIGH
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}

Whereas on Parabola we have that:

dump_modem_gpio_infos: dump_gpio_infos: cp-on
dump_gpio_infos: gpl2[5]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_INPUT
  GPIO_RESISTORS_ENABLE_PULL_DOWN
}
dump_modem_gpio_infos: dump_gpio_infos: cp-reset
dump_gpio_infos: gpx3[2]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: ap-dump
dump_gpio_infos: gpj0[1]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_PREVIOUS_STATE
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: cp-dump
dump_gpio_infos: gpx1[2]: {
  GPIO_INPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: phone-active
dump_gpio_infos: gpx1[6]: {
  0xf
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: reset-req
dump_gpio_infos: gpm3[3]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_HIGH
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: pda-active
dump_gpio_infos: gpf1[6]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_INPUT
  GPIO_RESISTORS_ENABLE_PULL_DOWN
}
dump_modem_gpio_infos: dump_gpio_infos: link-active
dump_gpio_infos: gpf1[1]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_INPUT
  GPIO_RESISTORS_ENABLE_PULL_DOWN
}
dump_modem_gpio_infos: dump_gpio_infos: link-hostwake
dump_gpio_infos: gpx1[1]: {
  0xf
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: link-slavewake
dump_gpio_infos: gpx1[0]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}
dump_modem_gpio_infos: dump_gpio_infos: suspend-req
dump_gpio_infos: gpm2[4]: {
  GPIO_OUTPUT
  GPIO_VALUE_LOW
  GPIO_RESISTORS_ENABLE_PULL_DOWN
  GPIO_DRIVE_1X
  GPIO_POWER_DOWN_OUTPUT_LOW
  GPIO_RESISTORS_PULLUP_PULLDOWN_DISABLE
}

In the case of Replicant 6, the modem is then able to call, and in Parabola to boot and retrieve the imei.

#25

Updated by Denis 'GNUtoo' Carikli 3 months ago

The issue is that for some reason we can't change the gmp2-4:

[root@u-boot-i9300 ~]# devmem2 0x110002a4 w
/dev/mem opened.
Memory mapped at address 0xb6f8f000.
Value at address 0x110002A4 (0xb6f8f2a4): 0x3
[root@u-boot-i9300 ~]# devmem2 0x110002a4 w
/dev/mem opened.
Memory mapped at address 0xb6fd1000.
Value at address 0x110002A4 (0xb6fd12a4): 0x3
[root@u-boot-i9300 ~]# devmem2 0x110002a4 w 0x11
/dev/mem opened.
Memory mapped at address 0xb6fb2000.
Value at address 0x110002A4 (0xb6fb22a4): 0x3
Written 0x11; readback 0x3

0x11 is 0b10001, so it's the bit #4. and 0x110002a4 is GPM2DAT

#26

Updated by Denis 'GNUtoo' Carikli 3 months ago

I've the same issue with u-boot:

=> mw
mw - memory write (fill)

Usage:
mw [.b, .w, .l] address value [count]
=> md 
md - memory display

Usage:
md [.b, .w, .l] address [# of objects]
=> md.w 0x110002a4
110002a4: 0003 0000 0155 0000 0000 0000 0000 0000    ....U...........
110002b4: 0000 0000 0155 0000 0000 0000 0000 0000    ....U...........
110002c4: 0000 0000 5555 0000 0000 0000 0000 0000    ....UU..........
110002d4: 0000 0000 5555 0000 0000 0000 0000 0000    ....UU..........
110002e4: 0000 0000 5555 0000 0000 0000 0000 0000    ....UU..........
110002f4: 0000 0000 5555 0000 0000 0000 0000 0000    ....UU..........
11000304: 0030 0000 0000 0000 0000 0000 0000 0000    0...............
11000314: 0000 0000 0000 0000 0000 0000 0000 0000    ................
=> md.w 0x110002a4 1
110002a4: 0003                                       ..
=> mw.w 0x110002a4 0x11 1
=> md.w 0x110002a4 1     
110002a4: 0001                                       ..
=> 

#27

Updated by Denis 'GNUtoo' Carikli 3 months ago

I can change the pull-up configuration in u-boot to match the Replicant 6 one (pullup / pulldown disabled) though:

=> md.w 0x110002a8 1
110002a8: 0155                                       U.
=> mw.w 0x110002a8 0x55 1
=> md.w 0x110002a8 1     
110002a8: 0055                                       U.

But then it still doesn't let me change that GPIO to HIGH:
=> md.w 0x110002a4 1     
110002a4: 0001                                       ..
=> mw.w 0x110002a4 0x11 1
=> md.w 0x110002a4 1     
110002a4: 0001                                       ..
=> 

I should probably do tests with the nonfree bootloader as well:
  • I can boot Parabola in this configuration too
  • I can even execute code inside the nonfree bootloader through an exploit but the size of the code is quite limited
#28

Updated by Denis 'GNUtoo' Carikli 3 months ago

I've also dumped that GPIO in the stock bootloader in download mode.

To do that I've written a program that runs inside sboot when in download mode

$ make -C exploit
$ exploit/sboot_exploit.py \
  --shellcode shellcode/dump-exynos4412-modem-gpios.bin
  [+] Shellcode started
  [*] gpm2-4 INPUT
  [*] gpm2-4 LOW
  [+] Shellcode is done! Rebooting...
  INFO:root:Shellcode is done. Device should be restarting soon

In that mode we can see that the suspend-req GPIO is low and configured as input.

#29

Updated by Denis 'GNUtoo' Carikli 3 months ago

To summarize the suspend-req state, we have:

Device state Modem state Direction Value
s-boot download mode Off, not booted INPUT LOW
u-boot Off, not booted LOW
Replicant 6 Off, not booted OUTPUT HIGH
Parabola with u-boot Off, not booted OUTPUT LOW
Parabola with s-boot Off, not booted OUTPUT LOW

Also available in: Atom PDF