diff options
-rw-r--r-- | samsung-ipc/devices/galaxys2/galaxys2.c | 4 | ||||
-rw-r--r-- | samsung-ipc/devices/i9300/i9300.c | 104 | ||||
-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/devices/n5100/n5100.c | 4 | ||||
-rw-r--r-- | samsung-ipc/devices/n7100/n7100.c | 4 | ||||
-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 | 126 | ||||
-rw-r--r-- | samsung-ipc/modems/xmm626/os_partitions.h | 70 | ||||
-rw-r--r-- | samsung-ipc/modems/xmm626/xmm626_hsic.c | 4 | ||||
-rw-r--r-- | samsung-ipc/modems/xmm626/xmm626_hsic.h | 4 |
13 files changed, 286 insertions, 48 deletions
diff --git a/samsung-ipc/devices/galaxys2/galaxys2.c b/samsung-ipc/devices/galaxys2/galaxys2.c index cdfe20c..e9e7278 100644 --- a/samsung-ipc/devices/galaxys2/galaxys2.c +++ b/samsung-ipc/devices/galaxys2/galaxys2.c @@ -140,7 +140,7 @@ int galaxys2_boot(struct ipc_client *client) p = (unsigned char *) modem_image_data + GALAXYS2_SEC_START_OFFSET; - rc = xmm626_hsic_sec_start_send(client, modem_boot_fd, (void *) p, + rc = xmm626_hsic_start_load_os(client, modem_boot_fd, (void *) p, GALAXYS2_SEC_START_SIZE); if (rc < 0) { ipc_client_log(client, "Sending XMM626 HSIC SEC start failed"); @@ -165,7 +165,7 @@ int galaxys2_boot(struct ipc_client *client) } ipc_client_log(client, "Sent XMM626 HSIC nv_data"); - rc = xmm626_hsic_sec_end_send(client, modem_boot_fd); + rc = xmm626_hsic_stop_load_os(client, modem_boot_fd); if (rc < 0) { ipc_client_log(client, "Sending XMM626 HSIC SEC end failed"); goto error; diff --git a/samsung-ipc/devices/i9300/i9300.c b/samsung-ipc/devices/i9300/i9300.c index 85709a8..7956c05 100644 --- a/samsung-ipc/devices/i9300/i9300.c +++ b/samsung-ipc/devices/i9300/i9300.c @@ -27,6 +27,7 @@ #include "ipc.h" #include "devices/i9300/i9300.h" +#include "modems/xmm626/os_partitions.h" #include "modems/xmm626/xmm626.h" #include "modems/xmm626/xmm626_hsic.h" #include "modems/xmm626/xmm626_kernel_smdk4412.h" @@ -34,6 +35,7 @@ int i9300_boot(struct ipc_client *client) { void *modem_image_data = NULL; + size_t modem_image_data_size = 0; // TODO int modem_image_fd = -1; int modem_boot_fd = -1; int modem_link_fd = -1; @@ -54,6 +56,7 @@ int i9300_boot(struct ipc_client *client) modem_image_data = mmap(0, I9300_MODEM_IMAGE_SIZE, PROT_READ, MAP_SHARED, modem_image_fd, 0); + //TODO: modem_image_data_size if (modem_image_data == NULL || modem_image_data == (void *) 0xffffffff) { ipc_client_log(client, @@ -100,25 +103,20 @@ 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_subpartition(client, MODEM_OS_PARTITION_PSIRAM, + modem_boot_fd, + modem_image_data, + modem_image_data_size); + if (rc < 0) goto error; - } - ipc_client_log(client, "Sent XMM626 HSIC PSI"); - p = (unsigned char *) modem_image_data + I9300_EBL_OFFSET; + rc = xmm626_load_os_subpartition(client, MODEM_OS_PARTITION_EBL, + modem_boot_fd, + modem_image_data, + modem_image_data_size); - 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"); + 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 +126,29 @@ 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_subpartition(client, MODEM_OS_PARTITION_SECPACK, + modem_boot_fd, + modem_image_data, + modem_image_data_size); + 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_subpartition(client, MODEM_OS_PARTITION_MAIN, + modem_boot_fd, + modem_image_data, + modem_image_data_size); + 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_subpartition(client, MODEM_OS_PARTITION_NV, + modem_boot_fd, + modem_image_data, + modem_image_data_size); + if (rc < 0) goto error; - } - ipc_client_log(client, "Sent XMM626 HSIC nv_data"); - rc = xmm626_hsic_sec_end_send(client, modem_boot_fd); + /* TODO: convert to load start/stop */ + rc = xmm626_hsic_stop_load_os(client, modem_boot_fd); if (rc < 0) { ipc_client_log(client, "Sending XMM626 HSIC SEC end failed"); goto error; @@ -387,6 +380,37 @@ int i9300_data_destroy(__attribute__((unused)) struct ipc_client *client, return 0; } +struct ipc_client_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 +454,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, + .subpartitions_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 fc767e0..ef2d1f3 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/devices/n5100/n5100.c b/samsung-ipc/devices/n5100/n5100.c index 0abe896..5e040dd 100644 --- a/samsung-ipc/devices/n5100/n5100.c +++ b/samsung-ipc/devices/n5100/n5100.c @@ -131,7 +131,7 @@ int n5100_boot(struct ipc_client *client) p = (unsigned char *) modem_image_data + N5100_SEC_START_OFFSET; - rc = xmm626_hsic_sec_start_send(client, modem_boot_fd, (void *) p, + rc = xmm626_hsic_start_load_os(client, modem_boot_fd, (void *) p, N5100_SEC_START_SIZE); if (rc < 0) { ipc_client_log(client, "Sending XMM626 HSIC SEC start failed"); @@ -156,7 +156,7 @@ int n5100_boot(struct ipc_client *client) } ipc_client_log(client, "Sent XMM626 HSIC nv_data"); - rc = xmm626_hsic_sec_end_send(client, modem_boot_fd); + rc = xmm626_hsic_stop_load_os(client, modem_boot_fd); if (rc < 0) { ipc_client_log(client, "Sending XMM626 HSIC SEC end failed"); goto error; diff --git a/samsung-ipc/devices/n7100/n7100.c b/samsung-ipc/devices/n7100/n7100.c index d5091a2..77cc473 100644 --- a/samsung-ipc/devices/n7100/n7100.c +++ b/samsung-ipc/devices/n7100/n7100.c @@ -130,7 +130,7 @@ int n7100_boot(struct ipc_client *client) p = (unsigned char *) modem_image_data + N7100_SEC_START_OFFSET; - rc = xmm626_hsic_sec_start_send(client, modem_boot_fd, (void *) p, + rc = xmm626_hsic_start_load_os(client, modem_boot_fd, (void *) p, N7100_SEC_START_SIZE); if (rc < 0) { ipc_client_log(client, "Sending XMM626 HSIC SEC start failed"); @@ -155,7 +155,7 @@ int n7100_boot(struct ipc_client *client) } ipc_client_log(client, "Sent XMM626 HSIC nv_data"); - rc = xmm626_hsic_sec_end_send(client, modem_boot_fd); + rc = xmm626_hsic_stop_load_os(client, modem_boot_fd); if (rc < 0) { ipc_client_log(client, "Sending XMM626 HSIC SEC end failed"); goto error; diff --git a/samsung-ipc/ipc.c b/samsung-ipc/ipc.c index c116fbb..b64f9d6 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..04aa1a4 --- /dev/null +++ b/samsung-ipc/modems/xmm626/os_partitions.c @@ -0,0 +1,126 @@ +/* + * 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" + +int xmm626_load_os_subpartition(struct ipc_client *client, + enum ipc_client_modem_os_partition type, int fd, + void *data, size_t data_size) +{ + int rc; + + switch (partition->type) { + case MODEM_OS_PARTITION_PSIRAM: + // TODO: MIPI/HSIC + return xmm626_psi_send(client, fd, + data, + data_size); + case MODEM_OS_PARTITION_EBL: + // TODO: MIPI/HSIC + return xmm626_hsic_ebl_send(client, fd, data, data_size); + + case MODEM_OS_PARTITION_MAIN: + rc = xmm626_send_main_partition(client, device_fd, data, + data_size); + case MODEM_OS_PARTITION_SECPACK: + /* TODO */ + break; + case MODEM_OS_PARTITION_NV: + rc = xmm626_nv_data_send(client, device_fd); + } + + if (rc < 0) + ipc_client_log( + client, + "Loading %s partition into the XMM626 modem failed", + modem_os_subpartition(type)); + else + ipc_client_log( + client, + "Loading %s partition into the XMM626 modem failed", + modem_os_subpartition(type)); + + return rc; +} + + +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..c1b5a74 --- /dev/null +++ b/samsung-ipc/modems/xmm626/os_partitions.h @@ -0,0 +1,70 @@ +/* + * 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 ipc_client_modem_os_subpartition_type { + 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, +}; + +#define ipc_client_modem_os_subpartition_string(subpartition) #subpartition + /* #if subpartition > MODEM_OS_PARTITION_NV \ */ + /* #error "Unknown modem_os_subpartition" \ */ + /* #else \ */ + /* #subpartition \ */ + /* #endif \ */ + +struct ipc_client_modem_os_subpartition { + const enum ipc_client_modem_os_subpartition_type type; + void *data; + const size_t offset; + const size_t size; +}; + +struct ipc_client_modem_os_partition_specs { + char* path; + size_t size; + struct ipc_client_modem_os_subpartition *subpartitions_specs[]; +}; + +int xmm626_load_os_subpartition(struct ipc_client *client, + enum ipc_client_modem_os_subpartition_type type, int fd, + void *data, size_t data_size); + +#endif /* XMM626_OS_PARTITIONS */ diff --git a/samsung-ipc/modems/xmm626/xmm626_hsic.c b/samsung-ipc/modems/xmm626/xmm626_hsic.c index 6e7126c..696f232 100644 --- a/samsung-ipc/modems/xmm626/xmm626_hsic.c +++ b/samsung-ipc/modems/xmm626/xmm626_hsic.c @@ -493,7 +493,7 @@ complete: return rc; } -int xmm626_hsic_sec_start_send(struct ipc_client *client, int device_fd, +int xmm626_hsic_start_load_os(struct ipc_client *client, int device_fd, const void *sec_data, size_t sec_size) { int rc; @@ -512,7 +512,7 @@ int xmm626_hsic_sec_start_send(struct ipc_client *client, int device_fd, return 0; } -int xmm626_hsic_sec_end_send(struct ipc_client *client, int device_fd) +int xmm626_hsic_stop_load_os(struct ipc_client *client, int device_fd) { unsigned short sec_data; size_t sec_size; diff --git a/samsung-ipc/modems/xmm626/xmm626_hsic.h b/samsung-ipc/modems/xmm626/xmm626_hsic.h index 6385cdc..845612f 100644 --- a/samsung-ipc/modems/xmm626/xmm626_hsic.h +++ b/samsung-ipc/modems/xmm626/xmm626_hsic.h @@ -56,9 +56,9 @@ int xmm626_hsic_ebl_send(struct ipc_client *client, int device_fd, const void *ebl_data, size_t ebl_size); int xmm626_hsic_port_config_send(struct ipc_client *client, int device_fd); -int xmm626_hsic_sec_start_send(struct ipc_client *client, int device_fd, +int xmm626_hsic_start_load_os(struct ipc_client *client, int device_fd, const void *sec_data, size_t sec_size); -int xmm626_hsic_sec_end_send(struct ipc_client *client, int device_fd); +int xmm626_hsic_stop_load_os(struct ipc_client *client, int device_fd); int xmm626_hsic_firmware_send(struct ipc_client *client, int device_fd, const void *firmware_data, size_t firmware_size); int xmm626_hsic_nv_data_send(struct ipc_client *client, int device_fd); |