diff options
author | Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org> | 2020-07-16 17:49:35 +0200 |
---|---|---|
committer | Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org> | 2020-07-16 23:21:38 +0200 |
commit | ad8c4b6aca3dcd8376c18ada456936e0074f8c7a (patch) | |
tree | bc38fac149710a7e9743b052805353ca91ab3ec0 | |
parent | f4f26a72c7eacdc4c6617170fad01b1160f2b209 (diff) | |
download | hardware_replicant_libsamsung-ipc-patches-todo/modem-abstraction-modem-partitions.tar.gz hardware_replicant_libsamsung-ipc-patches-todo/modem-abstraction-modem-partitions.tar.bz2 hardware_replicant_libsamsung-ipc-patches-todo/modem-abstraction-modem-partitions.zip |
[WIP] Add os partitionspatches-todo/modem-abstraction-modem-partitions
This is a test to see if we can make an abstraction for the modem
OS partition loading.
The concept behind that is pretty easy to understand:
- There is a modem OS partition
- This has has sub-partitions
- The sub-partitions need to be loaded in the modem
Given that:
- The loading code of some functions like xmm626_*_psi_load
is very similar between the MIPI and HSIC functions (the only
difference is that it uses a MIPI vs HSIC load function behind
the hood).
- We now know the partition names
- The concept is trivial to understand
It would be a good idea to get that part merged first.
It will also enable to cleanup a lot the device codes at the same
time, and we could merge part of our other abstraction for the modem
as we need a mipi/hsic abstraction for sending the data to the modem.
Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
-rw-r--r-- | samsung-ipc/devices/i9300/i9300.c | 119 | ||||
-rw-r--r-- | samsung-ipc/devices/i9300/i9300.h | 3 | ||||
-rw-r--r-- | samsung-ipc/devices/ipc_devices.c | 1 | ||||
-rw-r--r-- | samsung-ipc/devices/ipc_devices.h | 1 | ||||
-rw-r--r-- | samsung-ipc/ipc.c | 6 | ||||
-rw-r--r-- | samsung-ipc/ipc.h | 3 | ||||
-rw-r--r-- | samsung-ipc/modems/xmm626/os_partitions.c | 215 | ||||
-rw-r--r-- | samsung-ipc/modems/xmm626/os_partitions.h | 58 |
8 files changed, 342 insertions, 64 deletions
diff --git a/samsung-ipc/devices/i9300/i9300.c b/samsung-ipc/devices/i9300/i9300.c index 19137de..051439f 100644 --- a/samsung-ipc/devices/i9300/i9300.c +++ b/samsung-ipc/devices/i9300/i9300.c @@ -34,10 +34,9 @@ int i9300_boot(struct ipc_client *client) { void *modem_image_data = NULL; - int modem_image_fd = -1; int modem_boot_fd = -1; + int modem_image_fd = -1; int modem_link_fd = -1; - unsigned char *p; int rc; if (client == NULL) @@ -45,30 +44,9 @@ int i9300_boot(struct ipc_client *client) ipc_client_log(client, "Starting i9300 modem boot"); - modem_image_fd = open(I9300_MODEM_IMAGE_DEVICE, O_RDONLY); - if (modem_image_fd < 0) { - ipc_client_log(client, "Opening modem image device failed"); - goto error; - } - ipc_client_log(client, "Opened modem image device"); - - modem_image_data = mmap(0, I9300_MODEM_IMAGE_SIZE, PROT_READ, - MAP_SHARED, modem_image_fd, 0); - if (modem_image_data == NULL || - modem_image_data == (void *) 0xffffffff) { - ipc_client_log(client, - "Mapping modem image data to memory failed"); - goto error; - } - ipc_client_log(client, "Mapped modem image data to memory"); - - modem_boot_fd = open(XMM626_SEC_MODEM_BOOT0_DEVICE, - O_RDWR | O_NOCTTY | O_NONBLOCK); - if (modem_boot_fd < 0) { - ipc_client_log(client, "Opening modem boot device failed"); + rc = xmm626_open(client); + if (rc < 0) goto error; - } - ipc_client_log(client, "Opened modem boot device"); modem_link_fd = open(XMM626_SEC_MODEM_LINK_PM_DEVICE, O_RDWR); if (modem_link_fd < 0) { @@ -100,25 +78,15 @@ int i9300_boot(struct ipc_client *client) } ipc_client_log(client, "Waited for link connected"); - p = (unsigned char *) modem_image_data + I9300_PSI_OFFSET; - - rc = xmm626_hsic_psi_send(client, modem_boot_fd, (void *) p, - I9300_PSI_SIZE); - if (rc < 0) { - ipc_client_log(client, "Sending XMM626 HSIC PSI failed"); + rc = xmm626_load_os_partition(client, MODEM_OS_PARTITION_PSIRAM, + modem_boot_fd); + if (rc < 0) goto error; - } - ipc_client_log(client, "Sent XMM626 HSIC PSI"); - p = (unsigned char *) modem_image_data + I9300_EBL_OFFSET; - - rc = xmm626_hsic_ebl_send(client, modem_boot_fd, (void *) p, - I9300_EBL_SIZE); - if (rc < 0) { - ipc_client_log(client, "Sending XMM626 HSIC EBL failed"); + rc = xmm626_load_os_partition(client, MODEM_OS_PARTITION_EBL, + modem_boot_fd); + if (rc < 0) goto error; - } - ipc_client_log(client, "Sent XMM626 HSIC EBL"); rc = xmm626_hsic_port_config_send(client, modem_boot_fd); if (rc < 0) { @@ -128,34 +96,22 @@ int i9300_boot(struct ipc_client *client) } ipc_client_log(client, "Sent XMM626 HSIC port config"); - p = (unsigned char *) modem_image_data + I9300_SEC_START_OFFSET; - - rc = xmm626_hsic_sec_start_send(client, modem_boot_fd, (void *) p, - I9300_SEC_START_SIZE); - if (rc < 0) { - ipc_client_log(client, "Sending XMM626 HSIC SEC start failed"); + rc = xmm626_load_os_partition(client, MODEM_OS_PARTITION_SECPACK, + modem_boot_fd); + if (rc < 0) goto error; - } - ipc_client_log(client, "Sent XMM626 HSIC SEC start"); - - p = (unsigned char *) modem_image_data + I9300_FIRMWARE_OFFSET; - rc = xmm626_hsic_firmware_send(client, modem_boot_fd, (void *) p, - I9300_FIRMWARE_SIZE); - if (rc < 0) { - ipc_client_log(client, "Sending XMM626 HSIC firmware failed"); + rc = xmm626_load_os_partition(client, MODEM_OS_PARTITION_MAIN, + modem_boot_fd); + if (rc < 0) goto error; - } - ipc_client_log(client, "Sent XMM626 HSIC firmware"); - rc = xmm626_hsic_nv_data_send(client, modem_boot_fd); - if (rc < 0) { - ipc_client_log(client, "Sending XMM626 HSIC nv_data failed"); + rc = xmm626_load_os_partition(client, MODEM_OS_PARTITION_NV, + modem_boot_fd); + if (rc < 0) goto error; - } - ipc_client_log(client, "Sent XMM626 HSIC nv_data"); - rc = xmm626_hsic_sec_end_send(client, modem_boot_fd); + rc = xmm626_load_end(client, modem_boot_fd); if (rc < 0) { ipc_client_log(client, "Sending XMM626 HSIC SEC end failed"); goto error; @@ -387,6 +343,37 @@ int i9300_data_destroy(__attribute__((unused)) struct ipc_client *client, return 0; } +struct modem_os_subpartition i9300_modem_os_subpartitions_specs[] = { + { + .type = MODEM_OS_PARTITION_PSIRAM, + .offset = 0x1000, + .size = 0xE000, + }, + { + .type = MODEM_OS_PARTITION_EBL, + .offset = 0xF000, + .size = 0x19000, + }, + { + .type = MODEM_OS_PARTITION_MAIN, + .offset = 0x28000, + .size = 0x9D7800, + }, + { + .type = MODEM_OS_PARTITION_SECPACK, + .offset = 0x9FF800, + .size = 0x800, + }, + { + .type = MODEM_OS_PARTITION_NV, + .offset = 0xA00000, + .size = 0x200000, + }, + { + /* Sentinel */ + }, +} + struct ipc_client_ops i9300_fmt_ops = { .boot = i9300_boot, .send = xmm626_kernel_smdk4412_fmt_send, @@ -430,3 +417,9 @@ struct ipc_client_nv_data_specs i9300_nv_data_specs = { .nv_data_size = XMM626_NV_DATA_SIZE, .nv_data_chunk_size = XMM626_NV_DATA_CHUNK_SIZE, }; + +struct ipc_client_modem_os_partition_specs i9300_modem_os_partition_specs = { + .path = I9300_MODEM_IMAGE_DEVICE, + .size = I9300_MODEM_IMAGE_SIZE, + .subpartition_specs = i9300_modem_os_subpartitions_specs, +}; diff --git a/samsung-ipc/devices/i9300/i9300.h b/samsung-ipc/devices/i9300/i9300.h index 2cd011d..52cf17e 100644 --- a/samsung-ipc/devices/i9300/i9300.h +++ b/samsung-ipc/devices/i9300/i9300.h @@ -43,5 +43,6 @@ extern struct ipc_client_ops i9300_rfs_ops; extern struct ipc_client_handlers i9300_handlers; extern struct ipc_client_gprs_specs i9300_gprs_specs; extern struct ipc_client_nv_data_specs i9300_nv_data_specs; - +extern struct ipc_client_modem_os_partition_specs i9300_modem_os_partition_specs; + #endif /* __I9300_H__ */ diff --git a/samsung-ipc/devices/ipc_devices.c b/samsung-ipc/devices/ipc_devices.c index c94d030..db78e85 100644 --- a/samsung-ipc/devices/ipc_devices.c +++ b/samsung-ipc/devices/ipc_devices.c @@ -132,6 +132,7 @@ struct ipc_device_desc ipc_devices[] = { .handlers = &i9300_handlers, .gprs_specs = &i9300_gprs_specs, .nv_data_specs = &i9300_nv_data_specs, + .modem_os_partition_specs = &i9300_modem_os_partition_specs, }, { .name = "n7100", diff --git a/samsung-ipc/devices/ipc_devices.h b/samsung-ipc/devices/ipc_devices.h index 176607c..bdcbba6 100644 --- a/samsung-ipc/devices/ipc_devices.h +++ b/samsung-ipc/devices/ipc_devices.h @@ -42,6 +42,7 @@ struct ipc_device_desc { struct ipc_client_handlers *handlers; struct ipc_client_gprs_specs *gprs_specs; struct ipc_client_nv_data_specs *nv_data_specs; + struct ipc_client_modem_os_partition_specs *modem_os_partition_specs; }; extern struct ipc_device_desc ipc_devices[]; diff --git a/samsung-ipc/ipc.c b/samsung-ipc/ipc.c index 48c0450..7daf978 100644 --- a/samsung-ipc/ipc.c +++ b/samsung-ipc/ipc.c @@ -215,6 +215,12 @@ static struct ipc_client *ipc_transport_client_create(int type) client->gprs_specs = ipc_devices[device_index].gprs_specs; client->nv_data_specs = ipc_devices[device_index].nv_data_specs; + /* Not all devices currently implement that + * TODO: Remove the check when implemented + */ + if (ipc_devices[device_index].modem_os_partition_specs) + client->modem_os_partition_specs = ipc_devices[device_index].modem_os_partition_specs; + /* Handlers can be modified */ client->handlers = (struct ipc_client_handlers *) calloc( 1, sizeof(struct ipc_client_handlers)); diff --git a/samsung-ipc/ipc.h b/samsung-ipc/ipc.h index 1cfa757..724569f 100644 --- a/samsung-ipc/ipc.h +++ b/samsung-ipc/ipc.h @@ -23,6 +23,8 @@ #include <samsung-ipc.h> +#include "modems/xmm626/os_partitions.h" + #ifndef __IPC_H__ #define __IPC_H__ @@ -98,6 +100,7 @@ struct ipc_client { struct ipc_client_handlers *handlers; struct ipc_client_gprs_specs *gprs_specs; struct ipc_client_nv_data_specs *nv_data_specs; + struct ipc_client_modem_os_partition_specs *modem_os_partition_specs; }; /* diff --git a/samsung-ipc/modems/xmm626/os_partitions.c b/samsung-ipc/modems/xmm626/os_partitions.c new file mode 100644 index 0000000..1f2e949 --- /dev/null +++ b/samsung-ipc/modems/xmm626/os_partitions.c @@ -0,0 +1,215 @@ +/* + * This file is part of libsamsung-ipc. + * + * Copyright (C) 2012 Alexander Tarasikov <alexander.tarasikov@gmail.com> + * Copyright (C) 2013-2014 Paul Kocialkowski <contact@paulk.fr> + * + * Based on the incomplete C++ implementation which is: + * Copyright (C) 2012 Sergey Gridasov <grindars@gmail.com> + * + * libsamsung-ipc is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * libsamsung-ipc is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> + +#include "ipc.h" +#include "modems/modem.h" +#include "modems/xmm626/os_partitions.h" +#include "modems/xmm626/xmm626.h" + +struct xmm2626_os_partitions_pdata pdata { + int fd; + void *data; +}; + +// TODO +extern struct modem_os_partition i9300_modem_os_partitions; +int os_partition_match(struct ipc_client *client, + struct modem_os_partition *partition[]) +{ + +} + +// todo: move in specific helper file +char *block_device_dirs[] = { + "/dev/disk", + "/dev/block/", +} + +int try_path(char* partition) +{ + // for path in block_device_dirs + // try if exists + // return if exists +} + +int get_modem_partition_file() +{ + // TODO: write a generic function to get multiple block device prefix + // and use it here + return I9300_MODEM_IMAGE_DEVICE; +} + +int xmm626_modem_os_partition_fd(struct ipc_client *client) +{ + /* TODO */ +// return client->[...]->pdata->fd; +} + +int xmm626_modem_os_partition_open(struct ipc_client *client) +{ + char* partition_file = client->modem_os_partition_specs->path; + size_t partition_size = client->modem_os_partition_specs->size; + + pdata->fd = open(partition_file, O_RDONLY); + if (pdata->fd < 0) { + ipc_client_log(client, "Opening modem image device failed"); + goto error; + } + ipc_client_log(client, "Opened modem image device"); + + pdata->data = mmap(0, partition_size, PROT_READ, MAP_SHARED, pdata->fd, + 0); + if (pdata->data == NULL || pdata->data == (void *) 0xffffffff) { + ipc_client_log(client, + "Mapping modem image data to memory failed"); + goto error; + } + ipc_client_log(client, "Mapped modem image data to memory"); + + pdata->fd = open(XMM626_SEC_MODEM_BOOT0_DEVICE, + O_RDWR | O_NOCTTY | O_NONBLOCK); + if (pdata->fd < 0) { + ipc_client_log(client, "Opening modem boot device failed"); + goto error; + } + ipc_client_log(client, "Opened modem boot device"); + +error: + rc = -1; + +complete: + if (pdata->data != NULL) + munmap(modem_image_data, partition_size); + + if (pdata->fd >= 0) + close(pdata->fd); + + return rc; + +} + +int xmm626_modem_os_partition_close(struct ipc_client *client, + struct xmm2626_os_partitions_pdata *pdata) +{ + if (pdata->fd >= 0) + return close(pdata_fd); + + return 0; +} + +int xmm626_load_os_subpartition(struct ipc_client *client, + enum modem_os_partition type) +{ + // TODO: get partition data + // struct modem_os_partition *partition + // TODO match partition data + + //TODO: some checks + // if ff == 0 + + switch (partition->type) { + case MODEM_OS_PARTITION_PSIRAM: + // TODO: MIPI/HSIC + return xmm626_psi_send(client, pdata->fd, + pdata->data, + psiram_size); + case MODEM_OS_PARTITION_EBL: + // TODO: MIPI/HSIC + int xmm626_hsic_ebl_send(client, int device_fd, + const void *ebl_data, size_t ebl_size); + + case MODEM_OS_PARTITION_MAIN: + return xmm626_send_main_partition(client, device_fd, + partition->data, + partition->size); + case MODEM_OS_PARTITION_SECPACK: + // TODO: MIPI/HSIC + return xmm626_hsic_sec_end_send(client, device_fd); + + case MODEM_OS_PARTITION_NV: + return xmm626_nv_data_send(client, device_fd); + } + + //ipc_client_log(client, "Loading %s partition into the XMM626 modem failed"); + //or + //ipc_client_log(client, "Loading %s partition into the XMM626 modem failed"); +} + + +int xmm626_send_main_partition(struct ipc_client *client, int device_fd, + const void *firmware_data, size_t firmware_size) +{ + int rc; + + if (client == NULL || device_fd < 0 || firmware_data == NULL || + firmware_size == 0) { + return -1; + } + + rc = modem_data_send(client, device_fd, firmware_data, firmware_size, + XMM626_FIRMWARE_ADDRESS); + if (rc < 0) + return -1; + + return 0; +} + +int xmm626_nv_data_send(struct ipc_client *client, int device_fd) +{ + void *nv_data = NULL; + size_t nv_size; + int rc; + + if (client == NULL || device_fd < 0) + return -1; + + nv_size = ipc_client_nv_data_size(client); + if (nv_size == 0) + return -1; + + nv_data = ipc_nv_data_load(client); + if (nv_data == NULL) { + ipc_client_log(client, "Loading nv_data failed"); + goto error; + } + ipc_client_log(client, "Loaded nv_data"); + + rc = modem_data_send(client, device_fd, nv_data, nv_size, + XMM626_NV_DATA_ADDRESS); + if (rc < 0) + goto error; + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + if (nv_data != NULL) + free(nv_data); + + return rc; +} diff --git a/samsung-ipc/modems/xmm626/os_partitions.h b/samsung-ipc/modems/xmm626/os_partitions.h new file mode 100644 index 0000000..6166200 --- /dev/null +++ b/samsung-ipc/modems/xmm626/os_partitions.h @@ -0,0 +1,58 @@ +/* + * This file is part of libsamsung-ipc. + * + * Copyright (C) 2013-2014 Paul Kocialkowski <contact@paulk.fr> + * Copyright (C) 2020 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org> + * + * libsamsung-ipc is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * libsamsung-ipc is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef XMM626_OS_PARTITIONS +#define XMM626_OS_PARTITIONS + +/* Current function/partition mapping + * TODO: migrate functions + * +-----------------+-----------+ + * | Function | Partition | + * +-----------------+-----------+ + * | psi | PSIRAM | + * | ebl | EBL | + * | firmware | MAIN | + * | sec_start | SECPACK | + * | device specific | NV | + * +-----------------+-----------+ + */ +enum modem_os_partition { + MODEM_OS_PARTITION_HEADER = 0, + MODEM_OS_PARTITION_PSIRAM, + MODEM_OS_PARTITION_EBL, + MODEM_OS_PARTITION_MAIN, + MODEM_OS_PARTITION_SECPACK, + MODEM_OS_PARTITION_NV, +}; + +struct ipc_client_modem_os_subpartition { + const enum modem_os_partition type; + void *data; + const size_t offset; + const size_t size; +}; + +struct ipc_client_os_partition_specs { + char* path; + size_t size; + struct ipc_client_modem_os_subpartition *subpartitions_specs[]; +}; + +#endif /* XMM626_OS_PARTITIONS */ |