From 84cd42f10be74c0a60545c2035876e3beca644a3 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Thu, 5 Jul 2012 17:54:25 +0200 Subject: XMM6260: Split code into galaxys2, maguro and xmm2620 (shared code) devices * Moved maguro and galaxys2 loaders to proper folders * Renamed i9100 to galaxys2 and i9250 to maguro * Device-specific ops, handlers, gprs_specs and nv_data_specs on XMM2620 devices though most data/functions are still shared in xmm2620_ipc * Removed radio_parts from modemctl_io_data * Moved CRC calculate function to xmm2620_loader * Moved io_helpers functions to xmm2620_loader * Listed include headers in each file instead of using common.h * Prefixed remaining xmm2620 files Signed-off-by: Paul Kocialkowski --- Android.mk | 20 +-- samsung-ipc/Makefile.am | 19 +-- samsung-ipc/device/galaxys2/galaxys2_ipc.c | 63 +++++++++ samsung-ipc/device/galaxys2/galaxys2_loader.c | 135 ++++++++++--------- samsung-ipc/device/galaxys2/galaxys2_loader.h | 21 ++- samsung-ipc/device/maguro/maguro_ipc.c | 70 ++++++++++ samsung-ipc/device/maguro/maguro_loader.c | 126 ++++++++++-------- samsung-ipc/device/maguro/maguro_loader.h | 23 ++-- samsung-ipc/device/xmm6260/common.h | 48 ------- samsung-ipc/device/xmm6260/io_helpers.c | 80 ------------ samsung-ipc/device/xmm6260/io_helpers.h | 61 --------- samsung-ipc/device/xmm6260/modemctl.c | 170 ------------------------ samsung-ipc/device/xmm6260/modemctl.h | 174 ------------------------- samsung-ipc/device/xmm6260/xmm6260_ipc.c | 72 ++-------- samsung-ipc/device/xmm6260/xmm6260_ipc.h | 26 +++- samsung-ipc/device/xmm6260/xmm6260_loader.c | 112 ++++++++++++++++ samsung-ipc/device/xmm6260/xmm6260_loader.h | 104 +++++++++++++++ samsung-ipc/device/xmm6260/xmm6260_modemctl.c | 181 ++++++++++++++++++++++++++ samsung-ipc/device/xmm6260/xmm6260_modemctl.h | 123 +++++++++++++++++ samsung-ipc/ipc_devices.c | 31 +++-- samsung-ipc/ipc_devices.h | 25 ++-- 21 files changed, 918 insertions(+), 766 deletions(-) create mode 100644 samsung-ipc/device/galaxys2/galaxys2_ipc.c create mode 100644 samsung-ipc/device/maguro/maguro_ipc.c delete mode 100644 samsung-ipc/device/xmm6260/common.h delete mode 100644 samsung-ipc/device/xmm6260/io_helpers.c delete mode 100644 samsung-ipc/device/xmm6260/io_helpers.h delete mode 100644 samsung-ipc/device/xmm6260/modemctl.c delete mode 100644 samsung-ipc/device/xmm6260/modemctl.h create mode 100644 samsung-ipc/device/xmm6260/xmm6260_loader.c create mode 100644 samsung-ipc/device/xmm6260/xmm6260_loader.h create mode 100644 samsung-ipc/device/xmm6260/xmm6260_modemctl.c create mode 100644 samsung-ipc/device/xmm6260/xmm6260_modemctl.h diff --git a/Android.mk b/Android.mk index 353b240..6f907b6 100644 --- a/Android.mk +++ b/Android.mk @@ -7,7 +7,7 @@ include $(CLEAR_VARS) LOCAL_MODULE := libsamsung-ipc LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS += -Iexternal/openssl/include +LOCAL_C_INCLUDES := external/openssl/include LOCAL_LDFLAGS += -lcrypto ifeq ($(TARGET_DEVICE),crespo) @@ -16,6 +16,7 @@ ifeq ($(TARGET_DEVICE),crespo) endif ifeq ($(TARGET_DEVICE),galaxys2) + LOCAL_C_INCLUDES += $(LOCAL_PATH)/samsung-ipc/device/xmm6260/ LOCAL_CFLAGS += -DDEVICE_IPC_V4 samsung-ipc_device := galaxys2 endif @@ -35,6 +36,7 @@ ifeq ($(TARGET_DEVICE),h1) endif ifeq ($(TARGET_DEVICE),maguro) + LOCAL_C_INCLUDES += $(LOCAL_PATH)/samsung-ipc/device/xmm6260/ LOCAL_CFLAGS += -DDEVICE_IPC_V4 samsung-ipc_device := maguro endif @@ -58,17 +60,19 @@ samsung-ipc_files := \ samsung-ipc/device/h1/h1_ipc.c \ samsung-ipc/device/crespo/crespo_ipc.c \ samsung-ipc/device/aries/aries_ipc.c \ - samsung-ipc/device/xmm6260/fwloader_i9100.c \ - samsung-ipc/device/xmm6260/fwloader_i9250.c \ - samsung-ipc/device/xmm6260/io_helpers.c \ - samsung-ipc/device/xmm6260/modemctl_common.c \ - samsung-ipc/device/xmm6260/xmm6260_ipc.c + samsung-ipc/device/xmm6260/xmm6260_loader.c \ + samsung-ipc/device/xmm6260/xmm6260_modemctl.c \ + samsung-ipc/device/xmm6260/xmm6260_ipc.c \ + samsung-ipc/device/galaxys2/galaxys2_loader.c \ + samsung-ipc/device/galaxys2/galaxys2_ipc.c \ + samsung-ipc/device/maguro/maguro_loader.c \ + samsung-ipc/device/maguro/maguro_ipc.c LOCAL_SRC_FILES := $(samsung-ipc_files) LOCAL_CFLAGS += -DIPC_DEVICE_EXPLICIT=\"$(samsung-ipc_device)\" LOCAL_SHARED_LIBRARIES := libutils -LOCAL_C_INCLUDES := $(LOCAL_PATH)/include \ +LOCAL_C_INCLUDES += $(LOCAL_PATH)/include \ $(LOCAL_PATH)/samsung-ipc include $(BUILD_STATIC_LIBRARY) @@ -120,7 +124,7 @@ LOCAL_SRC_FILES := $(modemctrl_files) LOCAL_STATIC_LIBRARIES := libsamsung-ipc LOCAL_SHARED_LIBRARIES := libutils -LOCAL_C_INCLUDES := $(LOCAL_PATH)/include +LOCAL_C_INCLUDES += $(LOCAL_PATH)/include include $(BUILD_EXECUTABLE) diff --git a/samsung-ipc/Makefile.am b/samsung-ipc/Makefile.am index af15e61..b9e9b09 100644 --- a/samsung-ipc/Makefile.am +++ b/samsung-ipc/Makefile.am @@ -3,6 +3,7 @@ NULL = AM_CFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/samsung-ipc \ + -I$(top_srcdir)/samsung-ipc/device/xmm6260 \ $(OPENSSL_CFLAGS) \ $(NULL) @@ -36,16 +37,18 @@ libsamsung_ipc_la_SOURCES = \ device/aries/phonet.h \ device/crespo/crespo_modem_ctl.h \ device/crespo/crespo_ipc.h \ - device/xmm6260/common.h \ - device/xmm6260/fwloader_i9100.c \ - device/xmm6260/fwloader_i9250.c \ - device/xmm6260/io_helpers.c \ - device/xmm6260/io_helpers.h \ - device/xmm6260/modem_prj.h \ - device/xmm6260/modemctl_common.c \ - device/xmm6260/modemctl_common.h \ + device/xmm6260/xmm6260_loader.c \ + device/xmm6260/xmm6260_loader.h \ + device/xmm6260/xmm6260_modemctl.c \ + device/xmm6260/xmm6260_modemctl.h \ device/xmm6260/xmm6260_ipc.c \ device/xmm6260/xmm6260_ipc.h \ + device/galaxys2/galaxys2_loader.c \ + device/galaxys2/galaxys2_loader.h \ + device/galaxys2/galaxys2_ipc.c \ + device/maguro/maguro_loader.c \ + device/maguro/maguro_loader.h \ + device/maguro/maguro_ipc.c \ $(NULL) AM_CFLAGS += -DDEVICE_IPC_V4 diff --git a/samsung-ipc/device/galaxys2/galaxys2_ipc.c b/samsung-ipc/device/galaxys2/galaxys2_ipc.c new file mode 100644 index 0000000..7da84b7 --- /dev/null +++ b/samsung-ipc/device/galaxys2/galaxys2_ipc.c @@ -0,0 +1,63 @@ +/** + * This file is part of libsamsung-ipc. + * + * Copyright (C) 2012 Alexander Tarasikov + * Copyright (C) 2011 Paul Kocialkowski + * based on crespo IPC code which is: + * + * Copyright (C) 2011 Paul Kocialkowski + * Joerie de Gram + * Simon Busch + * + * 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 3 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 . + */ + +#include + +#include "ipc_private.h" + +#include "xmm6260_ipc.h" +#include "galaxys2_loader.h" + +struct ipc_ops galaxys2_fmt_ops = { + .send = xmm6260_ipc_fmt_client_send, + .recv = xmm6260_ipc_fmt_client_recv, + .bootstrap = galaxys2_modem_bootstrap, +}; + +struct ipc_ops galaxys2_rfs_ops = { + .send = xmm6260_ipc_rfs_client_send, + .recv = xmm6260_ipc_rfs_client_recv, + .bootstrap = NULL, +}; + +struct ipc_handlers galaxys2_default_handlers = { + .read = xmm6260_ipc_read, + .write = xmm6260_ipc_write, + .open = xmm6260_ipc_open, + .close = xmm6260_ipc_close, + .power_on = xmm6260_ipc_power_on, + .power_off = xmm6260_ipc_power_off, + .common_data = NULL, + .common_data_create = xmm6260_ipc_common_data_create, + .common_data_destroy = xmm6260_ipc_common_data_destroy, + .common_data_set_fd = xmm6260_ipc_common_data_set_fd, + .common_data_get_fd = xmm6260_ipc_common_data_get_fd, +}; + +struct ipc_gprs_specs galaxys2_gprs_specs = { + .gprs_get_iface = xmm6260_ipc_gprs_get_iface, + .gprs_get_capabilities = xmm6260_ipc_gprs_get_capabilities, +}; + diff --git a/samsung-ipc/device/galaxys2/galaxys2_loader.c b/samsung-ipc/device/galaxys2/galaxys2_loader.c index 0c6d80d..cb44e0a 100644 --- a/samsung-ipc/device/galaxys2/galaxys2_loader.c +++ b/samsung-ipc/device/galaxys2/galaxys2_loader.c @@ -1,6 +1,7 @@ /* - * Firmware loader for Samsung I9100 and I9250 + * Firmware loader for Samsung I9100 (galaxys2) * Copyright (C) 2012 Alexander Tarasikov + * Copyright (C) 2012 Paul Kocialkowski * * based on the incomplete C++ implementation which is * Copyright (C) 2012 Sergey Gridasov @@ -19,15 +20,38 @@ * along with this program. If not, see . */ -#include "modemctl_common.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +//for timeval +#include + +//for mmap +#include +#include + #include "ipc_private.h" -#include "fwloader_i9100.h" + +#include "galaxys2_loader.h" +#include "xmm6260_loader.h" +#include "xmm6260_modemctl.h" +#include "modem_prj.h" + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) /* * Locations of the firmware components in the Samsung firmware */ -struct xmm6260_radio_part i9100_radio_parts[] = { +struct xmm6260_radio_part galaxys2_radio_parts[] = { [PSI] = { .offset = 0, .length = 0xf000, @@ -50,7 +74,7 @@ struct xmm6260_radio_part i9100_radio_parts[] = { } }; -struct i9100_boot_cmd_desc i9100_boot_cmd_desc[] = { +struct galaxys2_boot_cmd_desc galaxys2_boot_cmd_desc[] = { [SetPortConf] = { .code = 0x86, .data_size = 0x800, @@ -83,25 +107,23 @@ struct i9100_boot_cmd_desc i9100_boot_cmd_desc[] = { } }; -static int i9100_send_image(struct ipc_client *client, +static int galaxys2_send_image(struct ipc_client *client, struct modemctl_io_data *io_data, enum xmm6260_image type) { int ret = -1; - if (type >= io_data->radio_parts_count) { + if (type >= ARRAY_SIZE(galaxys2_radio_parts)) { ipc_client_log(client, "Error: bad image type %x", type); goto fail; } - - size_t length = io_data->radio_parts[type].length; - size_t offset = io_data->radio_parts[type].offset; + size_t length = galaxys2_radio_parts[type].length; + size_t offset = galaxys2_radio_parts[type].offset; size_t start = offset; size_t end = length + start; //dump some image bytes ipc_client_log(client, "image start"); -// hexdump(io_data->radio_data + start, length); while (start < end) { ret = write(io_data->boot_fd, io_data->radio_data + start, end - start); @@ -112,7 +134,7 @@ static int i9100_send_image(struct ipc_client *client, start += ret; } - unsigned char crc = calculateCRC(io_data->radio_data, offset, length); + unsigned char crc = xmm6260_crc_calculate(io_data->radio_data, offset, length); if ((ret = write(io_data->boot_fd, &crc, 1)) < 1) { ipc_client_log(client, "failed to write CRC"); @@ -128,11 +150,11 @@ fail: return ret; } -static int i9100_send_psi(struct ipc_client *client, struct modemctl_io_data *io_data) +static int galaxys2_send_psi(struct ipc_client *client, struct modemctl_io_data *io_data) { - size_t length = i9100_radio_parts[PSI].length; + size_t length = galaxys2_radio_parts[PSI].length; - struct i9100_psi_header hdr = { + struct galaxys2_psi_header hdr = { .magic = XMM_PSI_MAGIC, .length = length, .padding = 0xff, @@ -144,7 +166,7 @@ static int i9100_send_psi(struct ipc_client *client, struct modemctl_io_data *io goto fail; } - if ((ret = i9100_send_image(client, io_data, PSI)) < 0) { + if ((ret = galaxys2_send_image(client, io_data, PSI)) < 0) { ipc_client_log(client, "Error: failed to send PSI image"); goto fail; } @@ -182,11 +204,11 @@ fail: return ret; } -static int i9100_send_ebl(struct ipc_client *client, struct modemctl_io_data *io_data) +static int galaxys2_send_ebl(struct ipc_client *client, struct modemctl_io_data *io_data) { int ret; int fd = io_data->boot_fd; - unsigned length = i9100_radio_parts[EBL].length; + unsigned length = galaxys2_radio_parts[EBL].length; if ((ret = write(fd, &length, sizeof(length))) < 0) { ipc_client_log(client, "Error: failed to write EBL length"); @@ -198,7 +220,7 @@ static int i9100_send_ebl(struct ipc_client *client, struct modemctl_io_data *io goto fail; } - if ((ret = i9100_send_image(client, io_data, EBL)) < 0) { + if ((ret = galaxys2_send_image(client, io_data, EBL)) < 0) { ipc_client_log(client, "Error: failed to send EBL image"); goto fail; } @@ -214,18 +236,18 @@ fail: return ret; } -static int i9100_boot_cmd(struct ipc_client *client, +static int galaxys2_boot_cmd(struct ipc_client *client, struct modemctl_io_data *io_data, enum xmm6260_boot_cmd cmd, void *data, size_t data_size) { int ret = 0; char *cmd_data = 0; - if (cmd >= ARRAY_SIZE(i9100_boot_cmd_desc)) { + if (cmd >= ARRAY_SIZE(galaxys2_boot_cmd_desc)) { ipc_client_log(client, "Error: bad command %x\n", cmd); goto done_or_fail; } - unsigned cmd_code = i9100_boot_cmd_desc[cmd].code; + unsigned cmd_code = galaxys2_boot_cmd_desc[cmd].code; uint16_t magic = (data_size & 0xffff) + cmd_code; unsigned char *ptr = (unsigned char*)data; @@ -234,13 +256,13 @@ static int i9100_boot_cmd(struct ipc_client *client, magic += ptr[i]; } - struct i9100_boot_cmd header = { + struct galaxys2_boot_cmd header = { .check = magic, .cmd = cmd_code, .data_size = data_size, }; - size_t cmd_size = i9100_boot_cmd_desc[cmd].data_size; + size_t cmd_size = galaxys2_boot_cmd_desc[cmd].data_size; size_t buf_size = cmd_size + sizeof(header); cmd_data = (char*)malloc(buf_size); @@ -264,12 +286,12 @@ static int i9100_boot_cmd(struct ipc_client *client, goto done_or_fail; } - if (!i9100_boot_cmd_desc[cmd].need_ack) { + if (!galaxys2_boot_cmd_desc[cmd].need_ack) { ret = 0; goto done_or_fail; } - struct i9100_boot_cmd ack = { + struct galaxys2_boot_cmd ack = { .check = 0, }; if ((ret = expect_read(io_data->boot_fd, &ack, sizeof(ack))) < 0) { @@ -309,11 +331,11 @@ done_or_fail: return ret; } -static int i9100_boot_info_ack(struct ipc_client *client, +static int galaxys2_boot_info_ack(struct ipc_client *client, struct modemctl_io_data *io_data) { int ret; - struct i9100_boot_info info; + struct galaxys2_boot_info info; if ((ret = expect_read(io_data->boot_fd, &info, sizeof(info))) != sizeof(info)) { ipc_client_log(client, "Error: failed to receive Boot Info ret=%d", ret); @@ -324,7 +346,7 @@ static int i9100_boot_info_ack(struct ipc_client *client, ipc_client_log(client, "received Boot Info"); } - if ((ret = i9100_boot_cmd(client, io_data, SetPortConf, &info, sizeof(info))) < 0) { + if ((ret = galaxys2_boot_cmd(client, io_data, SetPortConf, &info, sizeof(info))) < 0) { ipc_client_log(client, "Error: failed to send SetPortConf command"); goto fail; } @@ -338,7 +360,7 @@ fail: return ret; } -static int i9100_send_image_data(struct ipc_client *client, +static int galaxys2_send_image_data(struct ipc_client *client, struct modemctl_io_data *io_data, uint32_t addr, void *data, int data_len) { @@ -346,7 +368,7 @@ static int i9100_send_image_data(struct ipc_client *client, int count = 0; char *data_p = (char *) data; - if ((ret = i9100_boot_cmd(client, io_data, ReqFlashSetAddress, &addr, 4)) < 0) { + if ((ret = galaxys2_boot_cmd(client, io_data, ReqFlashSetAddress, &addr, 4)) < 0) { ipc_client_log(client, "Error: failed to send ReqFlashSetAddress"); goto fail; } @@ -358,7 +380,7 @@ static int i9100_send_image_data(struct ipc_client *client, int rest = data_len - count; int chunk = rest < SEC_DOWNLOAD_CHUNK ? rest : SEC_DOWNLOAD_CHUNK; - ret = i9100_boot_cmd(client, io_data, ReqFlashWriteBlock, data_p, chunk); + ret = galaxys2_boot_cmd(client, io_data, ReqFlashWriteBlock, data_p, chunk); if (ret < 0) { ipc_client_log(client, "Error: failed to send data chunk"); goto fail; @@ -374,30 +396,30 @@ fail: return ret; } -static int i9100_send_image_addr(struct ipc_client *client, +static int galaxys2_send_image_addr(struct ipc_client *client, struct modemctl_io_data *io_data, uint32_t addr, enum xmm6260_image type) { - uint32_t offset = i9100_radio_parts[type].offset; - uint32_t length = i9100_radio_parts[type].length; + uint32_t offset = galaxys2_radio_parts[type].offset; + uint32_t length = galaxys2_radio_parts[type].length; char *start = io_data->radio_data + offset; int ret = 0; - ret = i9100_send_image_data(client, io_data, addr, start, length); + ret = galaxys2_send_image_data(client, io_data, addr, start, length); return ret; } -static int i9100_send_secure_images(struct ipc_client *client, +static int galaxys2_send_secure_images(struct ipc_client *client, struct modemctl_io_data *io_data) { int ret = 0; - uint32_t sec_off = i9100_radio_parts[SECURE_IMAGE].offset; - uint32_t sec_len = i9100_radio_parts[SECURE_IMAGE].length; + uint32_t sec_off = galaxys2_radio_parts[SECURE_IMAGE].offset; + uint32_t sec_len = galaxys2_radio_parts[SECURE_IMAGE].length; void *sec_img = io_data->radio_data + sec_off; void *nv_data = NULL; - if ((ret = i9100_boot_cmd(client, io_data, ReqSecStart, sec_img, sec_len)) < 0) { + if ((ret = galaxys2_boot_cmd(client, io_data, ReqSecStart, sec_img, sec_len)) < 0) { ipc_client_log(client, "Error: failed to write ReqSecStart"); goto fail; } @@ -405,7 +427,7 @@ static int i9100_send_secure_images(struct ipc_client *client, ipc_client_log(client, "sent ReqSecStart"); } - if ((ret = i9100_send_image_addr(client, io_data, FW_LOAD_ADDR, FIRMWARE)) < 0) { + if ((ret = galaxys2_send_image_addr(client, io_data, FW_LOAD_ADDR, FIRMWARE)) < 0) { ipc_client_log(client, "Error: failed to send FIRMWARE image"); goto fail; } @@ -422,7 +444,7 @@ static int i9100_send_secure_images(struct ipc_client *client, goto fail; } - if ((ret = i9100_send_image_data(client, io_data, NVDATA_LOAD_ADDR, nv_data, 2 << 20)) < 0) { + if ((ret = galaxys2_send_image_data(client, io_data, NVDATA_LOAD_ADDR, nv_data, 2 << 20)) < 0) { ipc_client_log(client, "Error: failed to send NVDATA image"); goto fail; } @@ -432,7 +454,7 @@ static int i9100_send_secure_images(struct ipc_client *client, free(nv_data); - if ((ret = i9100_boot_cmd(client, io_data, ReqSecEnd, + if ((ret = galaxys2_boot_cmd(client, io_data, ReqSecEnd, BL_END_MAGIC, BL_END_MAGIC_LEN)) < 0) { ipc_client_log(client, "Error: failed to write ReqSecEnd"); @@ -442,7 +464,7 @@ static int i9100_send_secure_images(struct ipc_client *client, ipc_client_log(client, "sent ReqSecEnd"); } - ret = i9100_boot_cmd(client, io_data, ReqForceHwReset, + ret = galaxys2_boot_cmd(client, io_data, ReqForceHwReset, BL_RESET_MAGIC, BL_RESET_MAGIC_LEN); if (ret < 0) { ipc_client_log(client, "Error: failed to write ReqForceHwReset"); @@ -463,7 +485,7 @@ fail: /* * Power management */ -static int i9100_ehci_setpower(struct ipc_client *client, bool enabled) { +static int galaxys2_ehci_setpower(struct ipc_client *client, bool enabled) { int ret = -1; ipc_client_log(client, "%s: enabled=%d", __func__, enabled); @@ -496,7 +518,7 @@ fail: return ret; } -static int i9100_reboot_modem(struct ipc_client *client, +static int galaxys2_modem_reboot(struct ipc_client *client, struct modemctl_io_data *io_data, bool hard) { int ret; @@ -532,7 +554,7 @@ static int i9100_reboot_modem(struct ipc_client *client, ipc_client_log(client, "disabled I9100 HSIC link"); } - if ((ret = i9100_ehci_setpower(client, false)) < 0) { + if ((ret = galaxys2_ehci_setpower(client, false)) < 0) { ipc_client_log(client, "Error: failed to disable I9100 EHCI"); goto fail; } @@ -560,7 +582,7 @@ static int i9100_reboot_modem(struct ipc_client *client, ipc_client_log(client, "enabled I9100 HSIC link"); } - if ((ret = i9100_ehci_setpower(client, true)) < 0) { + if ((ret = galaxys2_ehci_setpower(client, true)) < 0) { ipc_client_log(client, "Error: failed to enable I9100 EHCI"); goto fail; } @@ -598,14 +620,11 @@ fail: return ret; } -int i9100_boot_modem(struct ipc_client *client) { +int galaxys2_modem_bootstrap(struct ipc_client *client) { int ret = 0; struct modemctl_io_data io_data; memset(&io_data, 0, sizeof(client, io_data)); - io_data.radio_parts = i9100_radio_parts; - io_data.radio_parts_count = ARRAY_SIZE(i9100_radio_parts); - io_data.radio_fd = open(RADIO_IMAGE, O_RDONLY); if (io_data.radio_fd < 0) { ipc_client_log(client, "Error: failed to open radio firmware"); @@ -645,7 +664,7 @@ int i9100_boot_modem(struct ipc_client *client) { ipc_client_log(client, "opened link device %s, fd=%d", LINK_PM, io_data.link_fd); } - if (i9100_reboot_modem(client, &io_data, true)) { + if (galaxys2_modem_reboot(client, &io_data, true)) { ipc_client_log(client, "Error: failed to hard reset modem"); goto fail; } @@ -675,7 +694,7 @@ int i9100_boot_modem(struct ipc_client *client) { } ipc_client_log(client, "receive ID: [%02x %02x]", buf[0], buf[1]); - if ((ret = i9100_send_psi(client, &io_data)) < 0) { + if ((ret = galaxys2_send_psi(client, &io_data)) < 0) { ipc_client_log(client, "Error: failed to upload PSI"); goto fail; } @@ -683,7 +702,7 @@ int i9100_boot_modem(struct ipc_client *client) { ipc_client_log(client, "PSI download complete"); } - if ((ret = i9100_send_ebl(client, &io_data)) < 0) { + if ((ret = galaxys2_send_ebl(client, &io_data)) < 0) { ipc_client_log(client, "Error: failed to upload EBL"); goto fail; } @@ -691,7 +710,7 @@ int i9100_boot_modem(struct ipc_client *client) { ipc_client_log(client, "EBL download complete"); } - if ((ret = i9100_boot_info_ack(client, &io_data)) < 0) { + if ((ret = galaxys2_boot_info_ack(client, &io_data)) < 0) { ipc_client_log(client, "Error: failed to receive Boot Info"); goto fail; } @@ -699,7 +718,7 @@ int i9100_boot_modem(struct ipc_client *client) { ipc_client_log(client, "Boot Info ACK done"); } - if ((ret = i9100_send_secure_images(client, &io_data)) < 0) { + if ((ret = galaxys2_send_secure_images(client, &io_data)) < 0) { ipc_client_log(client, "Error: failed to upload Secure Image"); goto fail; } @@ -709,7 +728,7 @@ int i9100_boot_modem(struct ipc_client *client) { usleep(POST_BOOT_TIMEOUT_US); - if ((ret = i9100_reboot_modem(client, &io_data, false))) { + if ((ret = galaxys2_modem_reboot(client, &io_data, false))) { ipc_client_log(client, "Error: failed to soft reset modem"); goto fail; } diff --git a/samsung-ipc/device/galaxys2/galaxys2_loader.h b/samsung-ipc/device/galaxys2/galaxys2_loader.h index 06dadd7..3bc6924 100644 --- a/samsung-ipc/device/galaxys2/galaxys2_loader.h +++ b/samsung-ipc/device/galaxys2/galaxys2_loader.h @@ -1,6 +1,7 @@ /* - * Firmware loader for Samsung I9100 and I9250 + * Firmware loader for Samsung I9100 (galaxys2) * Copyright (C) 2012 Alexander Tarasikov + * Copyright (C) 2012 Paul Kocialkowski * * based on the incomplete C++ implementation which is * Copyright (C) 2012 Sergey Gridasov @@ -19,8 +20,12 @@ * along with this program. If not, see . */ -#ifndef __FWLOADER_I9100_IPC_H__ -#define __FWLOADER_I9100_IPC_H__ +#include +#include +#include + +#ifndef __GALAXYS2_LOADER_H__ +#define __GALAXYS2_LOADER_H__ #define RADIO_IMAGE "/dev/block/mmcblk0p8" #define I9100_EHCI_PATH "/sys/devices/platform/s5p-ehci/ehci_power" @@ -48,28 +53,30 @@ #define FW_LOAD_ADDR 0x60300000 #define NVDATA_LOAD_ADDR 0x60e80000 -struct i9100_boot_cmd_desc { +struct galaxys2_boot_cmd_desc { unsigned code; size_t data_size; bool need_ack; }; -struct i9100_psi_header { +struct galaxys2_psi_header { uint8_t magic; uint16_t length; uint8_t padding; } __attribute__((packed)); -struct i9100_boot_info { +struct galaxys2_boot_info { uint8_t data[76]; } __attribute__((packed)); -struct i9100_boot_cmd { +struct galaxys2_boot_cmd { uint16_t check; uint16_t cmd; uint32_t data_size; } __attribute__((packed)); +int galaxys2_modem_bootstrap(struct ipc_client *client); + #endif // vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/maguro/maguro_ipc.c b/samsung-ipc/device/maguro/maguro_ipc.c new file mode 100644 index 0000000..fb4121d --- /dev/null +++ b/samsung-ipc/device/maguro/maguro_ipc.c @@ -0,0 +1,70 @@ +/** + * This file is part of libsamsung-ipc. + * + * Copyright (C) 2012 Alexander Tarasikov + * Copyright (C) 2011 Paul Kocialkowski + * based on crespo IPC code which is: + * + * Copyright (C) 2011 Paul Kocialkowski + * Joerie de Gram + * Simon Busch + * + * 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 3 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 . + */ + +#include + +#include "ipc_private.h" + +#include "xmm6260_ipc.h" +#include "maguro_loader.h" + +struct ipc_ops maguro_fmt_ops = { + .send = xmm6260_ipc_fmt_client_send, + .recv = xmm6260_ipc_fmt_client_recv, + .bootstrap = maguro_modem_bootstrap, +}; + +struct ipc_ops maguro_rfs_ops = { + .send = xmm6260_ipc_rfs_client_send, + .recv = xmm6260_ipc_rfs_client_recv, + .bootstrap = NULL, +}; + +struct ipc_handlers maguro_default_handlers = { + .read = xmm6260_ipc_read, + .write = xmm6260_ipc_write, + .open = xmm6260_ipc_open, + .close = xmm6260_ipc_close, + .power_on = xmm6260_ipc_power_on, + .power_off = xmm6260_ipc_power_off, + .common_data = NULL, + .common_data_create = xmm6260_ipc_common_data_create, + .common_data_destroy = xmm6260_ipc_common_data_destroy, + .common_data_set_fd = xmm6260_ipc_common_data_set_fd, + .common_data_get_fd = xmm6260_ipc_common_data_get_fd, +}; + +struct ipc_gprs_specs maguro_gprs_specs = { + .gprs_get_iface = xmm6260_ipc_gprs_get_iface, + .gprs_get_capabilities = xmm6260_ipc_gprs_get_capabilities, +}; + +struct ipc_nv_data_specs maguro_nv_data_specs = { + .nv_data_path = "/factory/nv_data.bin", + .nv_data_md5_path = "/factory/nv_data.bin.md5", + .nv_state_path = "/factory/.nv_state", + .nv_data_bak_path = "/factory/.nv_data.bak", + .nv_data_md5_bak_path = "/factory/.nv_data.bak.md5", +}; diff --git a/samsung-ipc/device/maguro/maguro_loader.c b/samsung-ipc/device/maguro/maguro_loader.c index 3ea973f..0bf757a 100644 --- a/samsung-ipc/device/maguro/maguro_loader.c +++ b/samsung-ipc/device/maguro/maguro_loader.c @@ -1,6 +1,7 @@ /* - * Firmware loader for Samsung I9100 and I9250 + * Firmware loader for Samsung I9250 (maguro) * Copyright (C) 2012 Alexander Tarasikov + * Copyright (C) 2012 Paul Kocialkowski * * based on the incomplete C++ implementation which is * Copyright (C) 2012 Sergey Gridasov @@ -19,15 +20,38 @@ * along with this program. If not, see . */ -#include "modemctl_common.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +//for timeval +#include + +//for mmap +#include +#include + #include "ipc_private.h" -#include "fwloader_i9250.h" + +#include "maguro_loader.h" +#include "xmm6260_loader.h" +#include "xmm6260_modemctl.h" +#include "modem_prj.h" + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) /* * Locations of the firmware components in the Samsung firmware */ -struct xmm6260_radio_part i9250_radio_parts[] = { +struct xmm6260_radio_part maguro_radio_parts[] = { [PSI] = { .offset = 0, .length = 0xf000, @@ -50,7 +74,7 @@ struct xmm6260_radio_part i9250_radio_parts[] = { } }; -struct i9250_boot_cmd_desc i9250_boot_cmd_desc[] = { +struct maguro_boot_cmd_desc maguro_boot_cmd_desc[] = { [SetPortConf] = { .code = 0x86, .long_tail = 1, @@ -76,23 +100,23 @@ struct i9250_boot_cmd_desc i9250_boot_cmd_desc[] = { }, }; -static int i9250_send_image(struct ipc_client *client, +static int maguro_send_image(struct ipc_client *client, struct modemctl_io_data *io_data, enum xmm6260_image type) { int ret = -1; - if (type >= ARRAY_SIZE(i9250_radio_parts)) { + if (type >= ARRAY_SIZE(maguro_radio_parts)) { ipc_client_log(client, "Error: bad image type %x", type); goto fail; } - size_t length = i9250_radio_parts[type].length; - size_t offset = i9250_radio_parts[type].offset; + size_t length = maguro_radio_parts[type].length; + size_t offset = maguro_radio_parts[type].offset; size_t start = offset; size_t end = length + start; - unsigned char crc = calculateCRC(io_data->radio_data, offset, length); + unsigned char crc = xmm6260_crc_calculate(io_data->radio_data, offset, length); //dump some image bytes ipc_client_log(client, "image start"); @@ -138,7 +162,7 @@ fail: return ret; } -static int i9250_send_psi(struct ipc_client *client, +static int maguro_send_psi(struct ipc_client *client, struct modemctl_io_data *io_data) { int ret = -1; @@ -148,7 +172,7 @@ static int i9250_send_psi(struct ipc_client *client, goto fail; } - if ((ret = i9250_send_image(client, io_data, PSI)) < 0) { + if ((ret = maguro_send_image(client, io_data, PSI)) < 0) { ipc_client_log(client, "Error: failed to send PSI image"); goto fail; } @@ -176,12 +200,12 @@ fail: return ret; } -static int i9250_send_ebl(struct ipc_client *client, +static int maguro_send_ebl(struct ipc_client *client, struct modemctl_io_data *io_data) { int ret; int fd = io_data->boot_fd; - unsigned length = i9250_radio_parts[EBL].length; + unsigned length = maguro_radio_parts[EBL].length; if ((ret = write(fd, "\x04\x00\x00\x00", 4)) != 4) { ipc_client_log(client, "Error: failed to write length of EBL length ('4') "); @@ -209,7 +233,7 @@ static int i9250_send_ebl(struct ipc_client *client, goto fail; } - if ((ret = i9250_send_image(client, io_data, EBL)) < 0) { + if ((ret = maguro_send_image(client, io_data, EBL)) < 0) { ipc_client_log(client, "Error: failed to send EBL image"); goto fail; } @@ -236,18 +260,18 @@ fail: return ret; } -static int i9250_boot_cmd(struct ipc_client *client, +static int maguro_boot_cmd(struct ipc_client *client, struct modemctl_io_data *io_data, enum xmm6260_boot_cmd cmd, void *data, size_t data_size) { int ret = 0; char *cmd_data = 0; - if (cmd >= ARRAY_SIZE(i9250_boot_cmd_desc)) { + if (cmd >= ARRAY_SIZE(maguro_boot_cmd_desc)) { ipc_client_log(client, "Error: bad command %x\n", cmd); goto done_or_fail; } - unsigned cmd_code = i9250_boot_cmd_desc[cmd].code; + unsigned cmd_code = maguro_boot_cmd_desc[cmd].code; uint16_t checksum = (data_size & 0xffff) + cmd_code; unsigned char *ptr = (unsigned char*)data; @@ -260,7 +284,7 @@ static int i9250_boot_cmd(struct ipc_client *client, DECLARE_BOOT_TAIL_HEADER(tail, checksum); size_t tail_size = sizeof(tail); - if (!i9250_boot_cmd_desc[cmd].long_tail) { + if (!maguro_boot_cmd_desc[cmd].long_tail) { tail_size -= 2; } @@ -289,7 +313,7 @@ static int i9250_boot_cmd(struct ipc_client *client, goto done_or_fail; } - if (i9250_boot_cmd_desc[cmd].no_ack) { + if (maguro_boot_cmd_desc[cmd].no_ack) { ipc_client_log(client, "not waiting for ACK"); goto done_or_fail; } @@ -320,9 +344,9 @@ static int i9250_boot_cmd(struct ipc_client *client, ipc_client_log(client, "received ack"); - struct i9250_boot_cmd_header *ack_hdr = (struct i9250_boot_cmd_header*)cmd_data; - struct i9250_boot_tail_header *ack_tail = (struct i9250_boot_tail_header*) - (cmd_data + ack_length + 4 - sizeof(struct i9250_boot_tail_header)); + struct maguro_boot_cmd_header *ack_hdr = (struct maguro_boot_cmd_header*)cmd_data; + struct maguro_boot_tail_header *ack_tail = (struct maguro_boot_tail_header*) + (cmd_data + ack_length + 4 - sizeof(struct maguro_boot_tail_header)); ipc_client_log(client, "ack code 0x%x checksum 0x%x", ack_hdr->cmd, ack_tail->checksum); if (ack_hdr->cmd != header.cmd) { @@ -342,7 +366,7 @@ done_or_fail: return ret; } -static int i9250_boot_info_ack(struct ipc_client *client, +static int maguro_boot_info_ack(struct ipc_client *client, struct modemctl_io_data *io_data) { int ret = -1; @@ -378,7 +402,7 @@ static int i9250_boot_info_ack(struct ipc_client *client, ipc_client_log(client, "received Boot Info"); - ret = i9250_boot_cmd(client, io_data, SetPortConf, boot_info, boot_info_length); + ret = maguro_boot_cmd(client, io_data, SetPortConf, boot_info, boot_info_length); if (ret < 0) { ipc_client_log(client, "Error: failed to send SetPortConf command"); goto fail; @@ -397,7 +421,7 @@ fail: return ret; } -static int i9250_send_image_data(struct ipc_client *client, +static int maguro_send_image_data(struct ipc_client *client, struct modemctl_io_data *io_data, uint32_t addr, void *data, int data_len) { @@ -405,7 +429,7 @@ static int i9250_send_image_data(struct ipc_client *client, int count = 0; char *data_p = (char *) data; - if ((ret = i9250_boot_cmd(client, io_data, ReqFlashSetAddress, &addr, 4)) < 0) { + if ((ret = maguro_boot_cmd(client, io_data, ReqFlashSetAddress, &addr, 4)) < 0) { ipc_client_log(client, "Error: failed to send ReqFlashSetAddress"); goto fail; } @@ -417,7 +441,7 @@ static int i9250_send_image_data(struct ipc_client *client, int rest = data_len - count; int chunk = rest < SEC_DOWNLOAD_CHUNK ? rest : SEC_DOWNLOAD_CHUNK; - ret = i9250_boot_cmd(client, io_data, ReqFlashWriteBlock, data_p, chunk); + ret = maguro_boot_cmd(client, io_data, ReqFlashWriteBlock, data_p, chunk); if (ret < 0) { ipc_client_log(client, "Error: failed to send data chunk"); goto fail; @@ -433,20 +457,20 @@ fail: return ret; } -static int i9250_send_image_addr(struct ipc_client *client, +static int maguro_send_image_addr(struct ipc_client *client, struct modemctl_io_data *io_data, uint32_t addr, enum xmm6260_image type) { - uint32_t offset = i9250_radio_parts[type].offset; - uint32_t length = i9250_radio_parts[type].length; + uint32_t offset = maguro_radio_parts[type].offset; + uint32_t length = maguro_radio_parts[type].length; char *start = io_data->radio_data + offset; int ret = 0; - ret = i9250_send_image_data(client, io_data, addr, start, length); + ret = maguro_send_image_data(client, io_data, addr, start, length); return ret; } -static int i9250_send_mps_data(struct ipc_client *client, +static int maguro_send_mps_data(struct ipc_client *client, struct modemctl_io_data *io_data) { int ret = 0; @@ -462,7 +486,7 @@ static int i9250_send_mps_data(struct ipc_client *client, read(mps_fd, mps_data, I9250_MPS_LENGTH); } - if ((ret = i9250_boot_cmd(client, io_data, ReqFlashSetAddress, &addr, 4)) < 0) { + if ((ret = maguro_boot_cmd(client, io_data, ReqFlashSetAddress, &addr, 4)) < 0) { ipc_client_log(client, "Error: failed to send ReqFlashSetAddress"); goto fail; } @@ -470,7 +494,7 @@ static int i9250_send_mps_data(struct ipc_client *client, ipc_client_log(client, "sent ReqFlashSetAddress"); } - if ((ret = i9250_boot_cmd(client, io_data, ReqFlashWriteBlock, + if ((ret = maguro_boot_cmd(client, io_data, ReqFlashWriteBlock, mps_data, I9250_MPS_LENGTH)) < 0) { ipc_client_log(client, "Error: failed to write MPS data to modem"); goto fail; @@ -485,17 +509,17 @@ fail: return ret; } -static int i9250_send_image_addrs(struct ipc_client *client, +static int maguro_send_image_addrs(struct ipc_client *client, struct modemctl_io_data *io_data) { int ret = 0; - uint32_t sec_off = i9250_radio_parts[SECURE_IMAGE].offset; - uint32_t sec_len = i9250_radio_parts[SECURE_IMAGE].length; + uint32_t sec_off = maguro_radio_parts[SECURE_IMAGE].offset; + uint32_t sec_len = maguro_radio_parts[SECURE_IMAGE].length; void *sec_img = io_data->radio_data + sec_off; void *nv_data = NULL; - if ((ret = i9250_boot_cmd(client, io_data, ReqSecStart, sec_img, sec_len)) < 0) { + if ((ret = maguro_boot_cmd(client, io_data, ReqSecStart, sec_img, sec_len)) < 0) { ipc_client_log(client, "Error: failed to write ReqSecStart"); goto fail; } @@ -503,7 +527,7 @@ static int i9250_send_image_addrs(struct ipc_client *client, ipc_client_log(client, "sent ReqSecStart"); } - if ((ret = i9250_send_image_addr(client, io_data, FW_LOAD_ADDR, FIRMWARE)) < 0) { + if ((ret = maguro_send_image_addr(client, io_data, FW_LOAD_ADDR, FIRMWARE)) < 0) { ipc_client_log(client, "Error: failed to send FIRMWARE image"); goto fail; } @@ -520,7 +544,7 @@ static int i9250_send_image_addrs(struct ipc_client *client, goto fail; } - if ((ret = i9250_send_image_data(client, io_data, NVDATA_LOAD_ADDR, nv_data, 2 << 20)) < 0) { + if ((ret = maguro_send_image_data(client, io_data, NVDATA_LOAD_ADDR, nv_data, 2 << 20)) < 0) { ipc_client_log(client, "Error: failed to send NVDATA image"); goto fail; } @@ -530,7 +554,7 @@ static int i9250_send_image_addrs(struct ipc_client *client, free(nv_data); - if ((ret = i9250_send_mps_data(client, io_data)) < 0) { + if ((ret = maguro_send_mps_data(client, io_data)) < 0) { ipc_client_log(client, "Error: failed to send MPS data"); goto fail; } @@ -538,7 +562,7 @@ static int i9250_send_image_addrs(struct ipc_client *client, ipc_client_log(client, "sent MPS data"); } - if ((ret = i9250_boot_cmd(client, io_data, ReqSecEnd, + if ((ret = maguro_boot_cmd(client, io_data, ReqSecEnd, BL_END_MAGIC, BL_END_MAGIC_LEN)) < 0) { ipc_client_log(client, "Error: failed to write ReqSecEnd"); @@ -548,7 +572,7 @@ static int i9250_send_image_addrs(struct ipc_client *client, ipc_client_log(client, "sent ReqSecEnd"); } - ret = i9250_boot_cmd(client, io_data, ReqForceHwReset, + ret = maguro_boot_cmd(client, io_data, ReqForceHwReset, BL_RESET_MAGIC, BL_RESET_MAGIC_LEN); if (ret < 0) { ipc_client_log(client, "Error: failed to write ReqForceHwReset"); @@ -562,7 +586,7 @@ fail: return ret; } -static int i9250_reboot_modem(struct ipc_client *client, +static int maguro_modem_reboot(struct ipc_client *client, struct modemctl_io_data *io_data, bool hard) { int ret; @@ -613,7 +637,7 @@ fail: return ret; } -int i9250_boot_modem(struct ipc_client *client) +int maguro_modem_bootstrap(struct ipc_client *client) { int ret = -1; struct modemctl_io_data io_data; @@ -649,7 +673,7 @@ int i9250_boot_modem(struct ipc_client *client) ipc_client_log(client, "opened boot device %s, fd=%d", BOOT_DEV, io_data.boot_fd); } - if (i9250_reboot_modem(client, &io_data, true) < 0) { + if (maguro_modem_reboot(client, &io_data, true) < 0) { ipc_client_log(client, "Error: failed to hard reset modem"); goto fail; } @@ -707,7 +731,7 @@ int i9250_boot_modem(struct ipc_client *client) ipc_client_log(client, "got bootloader id marker"); } - if ((ret = i9250_send_psi(client, &io_data)) < 0) { + if ((ret = maguro_send_psi(client, &io_data)) < 0) { ipc_client_log(client, "Error: failed to upload PSI"); goto fail; } @@ -745,7 +769,7 @@ int i9250_boot_modem(struct ipc_client *client) goto fail; } - if ((ret = i9250_send_ebl(client, &io_data)) < 0) { + if ((ret = maguro_send_ebl(client, &io_data)) < 0) { ipc_client_log(client, "Error: failed to upload EBL"); goto fail; } @@ -753,7 +777,7 @@ int i9250_boot_modem(struct ipc_client *client) ipc_client_log(client, "EBL download complete"); } - if ((ret = i9250_boot_info_ack(client, &io_data)) < 0) { + if ((ret = maguro_boot_info_ack(client, &io_data)) < 0) { ipc_client_log(client, "Error: failed to receive Boot Info"); goto fail; } @@ -761,7 +785,7 @@ int i9250_boot_modem(struct ipc_client *client) ipc_client_log(client, "Boot Info ACK done"); } - if ((ret = i9250_send_image_addrs(client, &io_data)) < 0) { + if ((ret = maguro_send_image_addrs(client, &io_data)) < 0) { ipc_client_log(client, "Error: failed to upload Secure Image"); goto fail; } diff --git a/samsung-ipc/device/maguro/maguro_loader.h b/samsung-ipc/device/maguro/maguro_loader.h index 7fa1782..7a47635 100644 --- a/samsung-ipc/device/maguro/maguro_loader.h +++ b/samsung-ipc/device/maguro/maguro_loader.h @@ -1,6 +1,7 @@ /* - * Firmware loader for Samsung I9100 and I9250 + * Firmware loader for Samsung I9250 (maguro) * Copyright (C) 2012 Alexander Tarasikov + * Copyright (C) 2012 Paul Kocialkowski * * based on the incomplete C++ implementation which is * Copyright (C) 2012 Sergey Gridasov @@ -19,8 +20,12 @@ * along with this program. If not, see . */ -#ifndef __FWLOADER_I9250_IPC_H__ -#define __FWLOADER_I9250_IPC_H__ +#include +#include +#include + +#ifndef __MAGURO_LOADER_H__ +#define __MAGURO_LOADER_H__ #define I9250_RADIO_IMAGE "/dev/block/platform/omap/omap_hsmmc.0/by-name/radio" #define I9250_SECOND_BOOT_DEV "/dev/umts_boot1" @@ -58,13 +63,13 @@ * on I9250, all commands need ACK and we do not need to * allocate a fixed size buffer */ -struct i9250_boot_cmd_desc { +struct maguro_boot_cmd_desc { unsigned code; bool long_tail; bool no_ack; }; -struct i9250_boot_cmd_header { +struct maguro_boot_cmd_header { uint32_t total_size; uint16_t hdr_magic; uint16_t cmd; @@ -72,26 +77,28 @@ struct i9250_boot_cmd_header { } __attribute__((packed)); #define DECLARE_BOOT_CMD_HEADER(name, code, size) \ -struct i9250_boot_cmd_header name = {\ +struct maguro_boot_cmd_header name = {\ .total_size = size + 10,\ .hdr_magic = 2,\ .cmd = code,\ .data_size = size,\ } -struct i9250_boot_tail_header { +struct maguro_boot_tail_header { uint16_t checksum; uint16_t tail_magic; uint8_t unknown[2]; } __attribute__((packed)); #define DECLARE_BOOT_TAIL_HEADER(name, checksum) \ -struct i9250_boot_tail_header name = {\ +struct maguro_boot_tail_header name = {\ .checksum = checksum,\ .tail_magic = 3,\ .unknown = "\xea\xea",\ } +int maguro_modem_bootstrap(struct ipc_client *client); + #endif // vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/xmm6260/common.h b/samsung-ipc/device/xmm6260/common.h deleted file mode 100644 index db8c8c7..0000000 --- a/samsung-ipc/device/xmm6260/common.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * common.h: common system headers includes and config defines - * This file is part of: - * - * Firmware loader for Samsung I9100 and I9250 - * Copyright (C) 2012 Alexander Tarasikov - * - * based on the incomplete C++ implementation which is - * Copyright (C) 2012 Sergey Gridasov - * - * This program 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 3 of the License, or - * (at your option) any later version. - * - * This program 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 this program. If not, see . - */ - -#ifndef __COMMON_H__ -#define __COMMON_H__ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -//for timeval -#include - -//for mmap -#include -#include - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) - -#endif //__COMMON_H__ diff --git a/samsung-ipc/device/xmm6260/io_helpers.c b/samsung-ipc/device/xmm6260/io_helpers.c deleted file mode 100644 index 0a38266..0000000 --- a/samsung-ipc/device/xmm6260/io_helpers.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * io_helpers.c - I/O helper functions for the firmware loader - * This file is part of: - * - * Firmware loader for Samsung I9100 and I9250 - * Copyright (C) 2012 Alexander Tarasikov - * - * based on the incomplete C++ implementation which is - * Copyright (C) 2012 Sergey Gridasov - * - * This program 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 3 of the License, or - * (at your option) any later version. - * - * This program 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 this program. If not, see . - */ - -#include "io_helpers.h" - -#define DEFAULT_TIMEOUT 50 - -int expect(int fd, unsigned timeout) { - int ret = 0; - - struct timeval tv = { - tv.tv_sec = timeout / 1000, - tv.tv_usec = 1000 * (timeout % 1000), - }; - - fd_set read_set; - FD_ZERO(&read_set); - FD_SET(fd, &read_set); - - ret = select(fd + 1, &read_set, 0, 0, &tv); - - if (ret < 0) { - // _e("failed to select the fd %d ret=%d: %s", fd, ret, strerror(errno)); - goto fail; - } - - if (ret < 1 || !FD_ISSET(fd, &read_set)) { - // _d("fd %d not in fd set", fd); - goto fail; - } - -fail: - return ret; -} - -int expect_read(int fd, void *buf, size_t size) { - int ret; - if ((ret = expect(fd, DEFAULT_TIMEOUT)) < 1) { - // _e("failed to select the fd %d", fd); - return ret; - } - - return read(fd, buf, size); -} - -int expect_data(int fd, void *data, size_t size) { - int ret; - char buf[size]; - if ((ret = expect_read(fd, buf, size)) != size) { - ret = -1; - // _e("failed to receive data"); - return ret; - } - ret = memcmp(buf, data, size); - - return ret; -} - -// vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/xmm6260/io_helpers.h b/samsung-ipc/device/xmm6260/io_helpers.h deleted file mode 100644 index f2ef717..0000000 --- a/samsung-ipc/device/xmm6260/io_helpers.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Firmware loader for Samsung I9100 and I9250 - * Copyright (C) 2012 Alexander Tarasikov - * - * based on the incomplete C++ implementation which is - * Copyright (C) 2012 Sergey Gridasov - * - * This program 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 3 of the License, or - * (at your option) any later version. - * - * This program 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 this program. If not, see . - */ - -#ifndef __IO_HELPERS_H__ -#define __IO_HELPERS_H__ - -#include "common.h" - -/* - * @brief Waits for fd to become available for reading - * - * @param fd [in] File descriptor of the socket - * @param timeout [in] Timeout in milliseconds - * @return Negative value indicating error code - * @return Available socket number - 1, as select() - */ -int expect(int fd, unsigned timeout); - -/* - * @brief Waits for data available and reads it to the buffer - * - * @param fd [in] File descriptor of the socket - * @param buf Buffer to hold data - * @param size [in] The number of bytes to read - * @return Negative value indicating error code - * @return The size of data received - */ -int expect_read(int fd, void *buf, size_t size); - -/* - * @brief Receives data and compares with the pattern in memory - * - * @param fd [in] File descriptor of the socket - * @param data [in] The pattern to compare to - * @param size [in] The length of data to read in bytes - * @return Negative value indicating error code - * @return Available socket number - 1, as select() - */ -int expect_data(int fd, void *data, size_t size); - -#endif //__IO_HELPERS_H__ - -// vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/xmm6260/modemctl.c b/samsung-ipc/device/xmm6260/modemctl.c deleted file mode 100644 index 489f9fe..0000000 --- a/samsung-ipc/device/xmm6260/modemctl.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Firmware loader for Samsung I9100 and I9250 - * Copyright (C) 2012 Alexander Tarasikov - * - * based on the incomplete C++ implementation which is - * Copyright (C) 2012 Sergey Gridasov - * - * This program 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 3 of the License, or - * (at your option) any later version. - * - * This program 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 this program. If not, see . - */ - -//modemctl shared code -#include "modemctl_common.h" - -/* - * modemctl generic functions - */ -int modemctl_link_set_active(struct ipc_client *client, - struct modemctl_io_data *io_data, bool enabled) { - unsigned status = enabled; - int ret; - unsigned long ioctl_code; - - ioctl_code = IOCTL_LINK_CONTROL_ACTIVE; - ret = ioctl(io_data->link_fd, ioctl_code, &status); - - if (ret < 0) { - ipc_client_log(client, "failed to set link active to %d", enabled); - goto fail; - } - - return 0; -fail: - return ret; -} - -int modemctl_link_set_enabled(struct ipc_client *client, - struct modemctl_io_data *io_data, bool enabled) { - unsigned status = enabled; - int ret; - unsigned long ioctl_code; - - ioctl_code = IOCTL_LINK_CONTROL_ENABLE; - ret = ioctl(io_data->link_fd, ioctl_code, &status); - - if (ret < 0) { - ipc_client_log(client, "failed to set link state to %d", enabled); - goto fail; - } - - return 0; -fail: - return ret; -} - -int modemctl_wait_link_ready(struct ipc_client *client, - struct modemctl_io_data *io_data) { - int ret; - - struct timeval tv_start = {}; - struct timeval tv_end = {}; - - gettimeofday(&tv_start, 0);; - - //link wakeup timeout in milliseconds - long diff = 0; - - do { - ret = ioctl(io_data->link_fd, IOCTL_LINK_CONNECTED, 0); - if (ret < 0) { - goto fail; - } - - if (ret == 1) { - return 0; - } - - usleep(LINK_POLL_DELAY_US); - gettimeofday(&tv_end, 0);; - - diff = (tv_end.tv_sec - tv_start.tv_sec) * 1000; - diff += (tv_end.tv_usec - tv_start.tv_usec) / 1000; - } while (diff < LINK_TIMEOUT_MS); - - ret = -ETIMEDOUT; - -fail: - return ret; -} - -int modemctl_wait_modem_online(struct ipc_client *client, - struct modemctl_io_data *io_data) { - int ret; - - struct timeval tv_start = {}; - struct timeval tv_end = {}; - - gettimeofday(&tv_start, 0);; - - //link wakeup timeout in milliseconds - long diff = 0; - - do { - ret = ioctl(io_data->boot_fd, IOCTL_MODEM_STATUS, 0); - if (ret < 0) { - goto fail; - } - - if (ret == STATE_ONLINE) { - return 0; - } - - usleep(LINK_POLL_DELAY_US); - gettimeofday(&tv_end, 0);; - - diff = (tv_end.tv_sec - tv_start.tv_sec) * 1000; - diff += (tv_end.tv_usec - tv_start.tv_usec) / 1000; - } while (diff < LINK_TIMEOUT_MS); - - ret = -ETIMEDOUT; - -fail: - return ret; -} - -int modemctl_modem_power(struct ipc_client *client, - struct modemctl_io_data *io_data, bool enabled) { - if (enabled) { - return ioctl(io_data->boot_fd, IOCTL_MODEM_ON, 0); - } - else { - return ioctl(io_data->boot_fd, IOCTL_MODEM_OFF, 0); - } - return -1; -} - -int modemctl_modem_boot_power(struct ipc_client *client, - struct modemctl_io_data *io_data, bool enabled) { - if (enabled) { - return ioctl(io_data->boot_fd, IOCTL_MODEM_BOOT_ON, 0); - } - else { - return ioctl(io_data->boot_fd, IOCTL_MODEM_BOOT_OFF, 0); - } - return -1; -} - -unsigned char calculateCRC(void* data, size_t offset, size_t length) -{ - unsigned char crc = 0; - unsigned char *ptr = (unsigned char*)(data + offset); - - while (length--) { - crc ^= *ptr++; - } - - return crc; -} - -// vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/xmm6260/modemctl.h b/samsung-ipc/device/xmm6260/modemctl.h deleted file mode 100644 index 87c9555..0000000 --- a/samsung-ipc/device/xmm6260/modemctl.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Firmware loader for Samsung I9100 and I9250 - * Copyright (C) 2012 Alexander Tarasikov - * - * based on the incomplete C++ implementation which is - * Copyright (C) 2012 Sergey Gridasov - * - * This program 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 3 of the License, or - * (at your option) any later version. - * - * This program 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 this program. If not, see . - */ - -#ifndef __MODEMCTL_COMMON_H__ -#define __MODEMCTL_COMMON_H__ - -#include - -#include "common.h" -#include "io_helpers.h" - -//Samsung IOCTLs -#include "modem_prj.h" - -#define MODEM_DEVICE(x) ("/dev/" #x) -#define LINK_PM MODEM_DEVICE(link_pm) -#define MODEM_DEV MODEM_DEVICE(modem_br) -#define BOOT_DEV MODEM_DEVICE(umts_boot0) -#define IPC_DEV MODEM_DEVICE(umts_ipc0) -#define RFS_DEV MODEM_DEVICE(umts_rfs0) - -#define LINK_POLL_DELAY_US (50 * 1000) -#define LINK_TIMEOUT_MS 2000 - -#define RADIO_MAP_SIZE (16 << 20) - -struct xmm6260_radio_part { - size_t offset; - size_t length; -}; - -/* - * Components of the Samsung XMM6260 firmware - */ -enum xmm6260_image { - PSI, - EBL, - SECURE_IMAGE, - FIRMWARE, - NVDATA, -}; - -/* - * Bootloader control interface definitions - */ - -enum xmm6260_boot_cmd { - SetPortConf, - - ReqSecStart, - ReqSecEnd, - ReqForceHwReset, - - ReqFlashSetAddress, - ReqFlashWriteBlock, -}; - -struct modemctl_io_data { - int link_fd; - int boot_fd; - - int radio_fd; - char *radio_data; - struct stat radio_stat; - - struct xmm6260_radio_part *radio_parts; - int radio_parts_count; -}; - -/* - * Function prototypes - */ - -/* - * @brief Activates the modem <-> cpu link data transfer - * - * @param client [in] ipc client - * @param io_data [in] modemctl-specific data - * @param enabled [in] whether to enable or disable link data transport - * @return Negative value indicating error code - * @return ioctl call result - */ -int modemctl_link_set_active(struct ipc_client *client, - struct modemctl_io_data *io_data, bool enabled); - -/* - * @brief Activates the modem <-> cpu link connection - * - * @param client [in] ipc client - * @param io_data [in] modemctl-specific data - * @param enabled [in] the state to set link to - * @return Negative value indicating error code - * @return ioctl call result - */ -int modemctl_link_set_enabled(struct ipc_client *client, - struct modemctl_io_data *io_data, bool enabled); - -/* - * @brief Poll the link until it gets ready or times out - * - * @param client [in] ipc client - * @param io_data [in] modemctl-specific data - * @return Negative value indicating error code - * @return ioctl call result - */ -int modemctl_wait_link_ready(struct ipc_client *client, - struct modemctl_io_data *io_data); - -/* - * @brief Poll the modem until it gets online or times out - * - * @param client [in] ipc client - * @param io_data [in] modemctl-specific data - * @return Negative value indicating error code - * @return ioctl call result - */ -int modemctl_wait_modem_online(struct ipc_client *client, - struct modemctl_io_data *io_data); - -/* - * @brief Sets the modem power - * - * @param client [in] ipc client - * @param io_data [in] modemctl-specific data - * @param enabled [in] whether to enable or disable modem power - * @return Negative value indicating error code - * @return ioctl call result - */ -int modemctl_modem_power(struct ipc_client *client, - struct modemctl_io_data *io_data, bool enabled); - -/* - * @brief Sets the modem bootloader power/UART configuration - * - * @param client [in] ipc client - * @param io_data [in] modemctl-specific data - * @param enabled [in] whether to enable or disable power - * @return Negative value indicating error code - * @return ioctl call result - */ -int modemctl_modem_boot_power(struct ipc_client *client, - struct modemctl_io_data *io_data, bool enabled); - -/* - * @brief Calculate the checksum for the XMM6260 bootloader protocol - * - * @param data [in] the data to calculate the checksum for - * @param offset [in] number of bytes to skip - * @param length [in] length of data in bytes - * @return checksum value - */ -unsigned char calculateCRC(void* data, size_t offset, size_t length); - -#endif //__MODEMCTL_COMMON_H__ - -// vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/xmm6260/xmm6260_ipc.c b/samsung-ipc/device/xmm6260/xmm6260_ipc.c index 0e17af5..7c84003 100644 --- a/samsung-ipc/device/xmm6260/xmm6260_ipc.c +++ b/samsung-ipc/device/xmm6260/xmm6260_ipc.c @@ -39,22 +39,14 @@ #include -#include "xmm6260_ipc.h" #include "ipc_private.h" -#include "modemctl_common.h" - -int i9100_modem_bootstrap(struct ipc_client *client) -{ - return i9100_boot_modem(client); -} - -int i9250_modem_bootstrap(struct ipc_client *client) -{ - return i9250_boot_modem(client); -} +#include "xmm6260_ipc.h" +#include "xmm6260_loader.h" +#include "xmm6260_modemctl.h" +#include "modem_prj.h" -int xmm6260_ipc_send(struct ipc_client *client, struct ipc_message_info *request) +int xmm6260_ipc_fmt_client_send(struct ipc_client *client, struct ipc_message_info *request) { struct ipc_header *hdr; unsigned char *frame; @@ -92,7 +84,7 @@ int xmm6260_ipc_send(struct ipc_client *client, struct ipc_message_info *request return 0; } -int xmm6260_ipc_recv(struct ipc_client *client, struct ipc_message_info *response) +int xmm6260_ipc_fmt_client_recv(struct ipc_client *client, struct ipc_message_info *response) { unsigned char buf[IPC_MAX_XFER] = {}; unsigned char *data; @@ -143,7 +135,7 @@ int xmm6260_ipc_recv(struct ipc_client *client, struct ipc_message_info *respons return 0; } -int xmm6260_rfs_recv(struct ipc_client *client, struct ipc_message_info *response) +int xmm6260_ipc_rfs_client_recv(struct ipc_client *client, struct ipc_message_info *response) { unsigned char buf[IPC_MAX_XFER] = {}; struct rfs_hdr header; @@ -213,7 +205,7 @@ int xmm6260_rfs_recv(struct ipc_client *client, struct ipc_message_info *respons return 0; } -int xmm6260_rfs_send(struct ipc_client *client, struct ipc_message_info *request) +int xmm6260_ipc_rfs_client_send(struct ipc_client *client, struct ipc_message_info *request) { struct rfs_hdr *header = NULL; char *data = NULL; @@ -347,7 +339,7 @@ int xmm6260_ipc_power_off(void *io_data) int xmm6260_ipc_gprs_get_iface(char **iface) { // TODO: depends on CID - asprintf(iface, "rmnet0"); + asprintf(iface, GPRS_IFACE); return 0; } @@ -416,50 +408,4 @@ int xmm6260_ipc_common_data_get_fd(void *io_data) return (int) *(common_data); } -struct ipc_ops xmm6260_i9100_fmt_ops = { - .send = xmm6260_ipc_send, - .recv = xmm6260_ipc_recv, - .bootstrap = i9100_modem_bootstrap, -}; - -struct ipc_ops xmm6260_i9250_fmt_ops = { - .send = xmm6260_ipc_send, - .recv = xmm6260_ipc_recv, - .bootstrap = i9250_modem_bootstrap, -}; - -struct ipc_ops xmm6260_rfs_ops = { - .send = xmm6260_rfs_send, - .recv = xmm6260_rfs_recv, - .bootstrap = NULL, -}; - -struct ipc_handlers xmm6260_default_handlers = { - .read = xmm6260_ipc_read, - .write = xmm6260_ipc_write, - .open = xmm6260_ipc_open, - .close = xmm6260_ipc_close, - .power_on = xmm6260_ipc_power_on, - .power_off = xmm6260_ipc_power_off, - .common_data = NULL, - .common_data_create = xmm6260_ipc_common_data_create, - .common_data_destroy = xmm6260_ipc_common_data_destroy, - .common_data_set_fd = xmm6260_ipc_common_data_set_fd, - .common_data_get_fd = xmm6260_ipc_common_data_get_fd, -}; - -struct ipc_gprs_specs xmm6260_gprs_specs = { - .gprs_get_iface = xmm6260_ipc_gprs_get_iface, - .gprs_get_capabilities = xmm6260_ipc_gprs_get_capabilities, -}; - - -struct ipc_nv_data_specs xmm6260_nv_data_specs = { - .nv_data_path = "/factory/nv_data.bin", - .nv_data_md5_path = "/factory/nv_data.bin.md5", - .nv_state_path = "/factory/.nv_state", - .nv_data_bak_path = "/factory/.nv_data.bak", - .nv_data_md5_bak_path = "/factory/.nv_data.bak.md5", -}; - // vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/xmm6260/xmm6260_ipc.h b/samsung-ipc/device/xmm6260/xmm6260_ipc.h index 06c8387..14a0cfb 100644 --- a/samsung-ipc/device/xmm6260/xmm6260_ipc.h +++ b/samsung-ipc/device/xmm6260/xmm6260_ipc.h @@ -2,9 +2,12 @@ * This file is part of libsamsung-ipc. * * Copyright (C) 2012 Alexander Tarasikov + * Copyright (C) 2011 Paul Kocialkowski * based on crespo IPC code which is: * * Copyright (C) 2011 Paul Kocialkowski + * Joerie de Gram + * Simon Busch * * 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 @@ -18,15 +21,13 @@ * * You should have received a copy of the GNU General Public License * along with libsamsung-ipc. If not, see . - * */ #ifndef __XMM6260_IPC_H__ #define __XMM6260_IPC_H__ -#define IPC_MAX_XFER 4096 - -extern struct ipc_handlers xmm6260_ipc_default_handlers; +#define IPC_MAX_XFER 4096 +#define GPRS_IFACE "rmnet0" struct rfs_hdr { uint32_t size; @@ -34,6 +35,23 @@ struct rfs_hdr { uint8_t id; } __attribute__ ((packed)); +int xmm6260_ipc_fmt_client_send(struct ipc_client *client, struct ipc_message_info *request); +int xmm6260_ipc_fmt_client_recv(struct ipc_client *client, struct ipc_message_info *response); +int xmm6260_ipc_rfs_client_recv(struct ipc_client *client, struct ipc_message_info *response); +int xmm6260_ipc_rfs_client_send(struct ipc_client *client, struct ipc_message_info *request); +int xmm6260_ipc_open(void *data, unsigned int size, void *io_data); +int xmm6260_ipc_close(void *data, unsigned int size, void *io_data); +int xmm6260_ipc_read(void *data, unsigned int size, void *io_data); +int xmm6260_ipc_write(void *data, unsigned int size, void *io_data); +int xmm6260_ipc_power_on(void *io_data); +int xmm6260_ipc_power_off(void *io_data); +int xmm6260_ipc_gprs_get_iface(char **iface); +int xmm6260_ipc_gprs_get_capabilities(struct ipc_client_gprs_capabilities *cap); +void *xmm6260_ipc_common_data_create(void); +int xmm6260_ipc_common_data_destroy(void *io_data); +int xmm6260_ipc_common_data_set_fd(void *io_data, int fd); +int xmm6260_ipc_common_data_get_fd(void *io_data); + #endif // vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/xmm6260/xmm6260_loader.c b/samsung-ipc/device/xmm6260/xmm6260_loader.c new file mode 100644 index 0000000..3c78891 --- /dev/null +++ b/samsung-ipc/device/xmm6260/xmm6260_loader.c @@ -0,0 +1,112 @@ +/* + * XMM6260 Firmware loader functions + * Copyright (C) 2012 Alexander Tarasikov + * Copyright (C) 2012 Paul Kocialkowski + * + * based on the incomplete C++ implementation which is + * Copyright (C) 2012 Sergey Gridasov + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +//for timeval +#include + +//for mmap +#include +#include + +#include "ipc_private.h" + +#include "xmm6260_loader.h" +#include "xmm6260_modemctl.h" +#include "modem_prj.h" + +unsigned char xmm6260_crc_calculate(void* data, size_t offset, size_t length) +{ + unsigned char crc = 0; + unsigned char *ptr = (unsigned char*)(data + offset); + + while (length--) { + crc ^= *ptr++; + } + + return crc; +} + +/* + * io helper functions + */ + +int expect(int fd, unsigned timeout) { + int ret = 0; + + struct timeval tv = { + tv.tv_sec = timeout / 1000, + tv.tv_usec = 1000 * (timeout % 1000), + }; + + fd_set read_set; + FD_ZERO(&read_set); + FD_SET(fd, &read_set); + + ret = select(fd + 1, &read_set, 0, 0, &tv); + + if (ret < 0) { + // _e("failed to select the fd %d ret=%d: %s", fd, ret, strerror(errno)); + goto fail; + } + + if (ret < 1 || !FD_ISSET(fd, &read_set)) { + // _d("fd %d not in fd set", fd); + goto fail; + } + +fail: + return ret; +} + +int expect_read(int fd, void *buf, size_t size) { + int ret; + if ((ret = expect(fd, DEFAULT_TIMEOUT)) < 1) { + // _e("failed to select the fd %d", fd); + return ret; + } + + return read(fd, buf, size); +} + +int expect_data(int fd, void *data, size_t size) { + int ret; + char buf[size]; + if ((ret = expect_read(fd, buf, size)) != size) { + ret = -1; + // _e("failed to receive data"); + return ret; + } + ret = memcmp(buf, data, size); + + return ret; +} diff --git a/samsung-ipc/device/xmm6260/xmm6260_loader.h b/samsung-ipc/device/xmm6260/xmm6260_loader.h new file mode 100644 index 0000000..b022645 --- /dev/null +++ b/samsung-ipc/device/xmm6260/xmm6260_loader.h @@ -0,0 +1,104 @@ +/* + * XMM6260 Firmware loader functions + * Copyright (C) 2012 Alexander Tarasikov + * Copyright (C) 2012 Paul Kocialkowski + * + * based on the incomplete C++ implementation which is + * Copyright (C) 2012 Sergey Gridasov + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifndef __XMM6260_LOADER_H__ +#define __XMM6260_LOADER_H__ + +#define RADIO_MAP_SIZE (16 << 20) +#define DEFAULT_TIMEOUT 50 + +/* + * Offset and length to describe a part of XMM6260 firmware + */ +struct xmm6260_radio_part { + size_t offset; + size_t length; +}; + +/* + * Components of the Samsung XMM6260 firmware + */ +enum xmm6260_image { + PSI, + EBL, + SECURE_IMAGE, + FIRMWARE, + NVDATA, +}; + +/* + * Bootloader control interface definitions + */ +enum xmm6260_boot_cmd { + SetPortConf, + + ReqSecStart, + ReqSecEnd, + ReqForceHwReset, + + ReqFlashSetAddress, + ReqFlashWriteBlock, +}; + +/* + * @brief Calculate the checksum for the XMM6260 bootloader protocol + * + * @param data [in] the data to calculate the checksum for + * @param offset [in] number of bytes to skip + * @param length [in] length of data in bytes + * @return checksum value + */ +unsigned char xmm6260_crc_calculate(void* data, size_t offset, size_t length); + +/* + * @brief Waits for fd to become available for reading + * + * @param fd [in] File descriptor of the socket + * @param timeout [in] Timeout in milliseconds + * @return Negative value indicating error code + * @return Available socket number - 1, as select() + */ +int expect(int fd, unsigned timeout); + +/* + * @brief Waits for data available and reads it to the buffer + * + * @param fd [in] File descriptor of the socket + * @param buf Buffer to hold data + * @param size [in] The number of bytes to read + * @return Negative value indicating error code + * @return The size of data received + */ +int expect_read(int fd, void *buf, size_t size); + +/* + * @brief Receives data and compares with the pattern in memory + * + * @param fd [in] File descriptor of the socket + * @param data [in] The pattern to compare to + * @param size [in] The length of data to read in bytes + * @return Negative value indicating error code + * @return Available socket number - 1, as select() + */ +int expect_data(int fd, void *data, size_t size); + +#endif diff --git a/samsung-ipc/device/xmm6260/xmm6260_modemctl.c b/samsung-ipc/device/xmm6260/xmm6260_modemctl.c new file mode 100644 index 0000000..a6f1fb6 --- /dev/null +++ b/samsung-ipc/device/xmm6260/xmm6260_modemctl.c @@ -0,0 +1,181 @@ +/* + * XMM6260 Modem Control functions + * Copyright (C) 2012 Alexander Tarasikov + * Copyright (C) 2012 Paul Kocialkowski + * + * based on the incomplete C++ implementation which is + * Copyright (C) 2012 Sergey Gridasov + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +//for timeval +#include + +//for mmap +#include +#include + +#include "ipc_private.h" + +#include "xmm6260_loader.h" +#include "xmm6260_modemctl.h" +#include "modem_prj.h" + +/* + * modemctl generic functions + */ + +int modemctl_link_set_active(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled) { + unsigned status = enabled; + int ret; + unsigned long ioctl_code; + + ioctl_code = IOCTL_LINK_CONTROL_ACTIVE; + ret = ioctl(io_data->link_fd, ioctl_code, &status); + + if (ret < 0) { + ipc_client_log(client, "failed to set link active to %d", enabled); + goto fail; + } + + return 0; +fail: + return ret; +} + +int modemctl_link_set_enabled(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled) { + unsigned status = enabled; + int ret; + unsigned long ioctl_code; + + ioctl_code = IOCTL_LINK_CONTROL_ENABLE; + ret = ioctl(io_data->link_fd, ioctl_code, &status); + + if (ret < 0) { + ipc_client_log(client, "failed to set link state to %d", enabled); + goto fail; + } + + return 0; +fail: + return ret; +} + +int modemctl_wait_link_ready(struct ipc_client *client, + struct modemctl_io_data *io_data) { + int ret; + + struct timeval tv_start = {}; + struct timeval tv_end = {}; + + gettimeofday(&tv_start, 0);; + + //link wakeup timeout in milliseconds + long diff = 0; + + do { + ret = ioctl(io_data->link_fd, IOCTL_LINK_CONNECTED, 0); + if (ret < 0) { + goto fail; + } + + if (ret == 1) { + return 0; + } + + usleep(LINK_POLL_DELAY_US); + gettimeofday(&tv_end, 0);; + + diff = (tv_end.tv_sec - tv_start.tv_sec) * 1000; + diff += (tv_end.tv_usec - tv_start.tv_usec) / 1000; + } while (diff < LINK_TIMEOUT_MS); + + ret = -ETIMEDOUT; + +fail: + return ret; +} + +int modemctl_wait_modem_online(struct ipc_client *client, + struct modemctl_io_data *io_data) { + int ret; + + struct timeval tv_start = {}; + struct timeval tv_end = {}; + + gettimeofday(&tv_start, 0);; + + //link wakeup timeout in milliseconds + long diff = 0; + + do { + ret = ioctl(io_data->boot_fd, IOCTL_MODEM_STATUS, 0); + if (ret < 0) { + goto fail; + } + + if (ret == STATE_ONLINE) { + return 0; + } + + usleep(LINK_POLL_DELAY_US); + gettimeofday(&tv_end, 0);; + + diff = (tv_end.tv_sec - tv_start.tv_sec) * 1000; + diff += (tv_end.tv_usec - tv_start.tv_usec) / 1000; + } while (diff < LINK_TIMEOUT_MS); + + ret = -ETIMEDOUT; + +fail: + return ret; +} + +int modemctl_modem_power(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled) { + if (enabled) { + return ioctl(io_data->boot_fd, IOCTL_MODEM_ON, 0); + } + else { + return ioctl(io_data->boot_fd, IOCTL_MODEM_OFF, 0); + } + return -1; +} + +int modemctl_modem_boot_power(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled) { + if (enabled) { + return ioctl(io_data->boot_fd, IOCTL_MODEM_BOOT_ON, 0); + } + else { + return ioctl(io_data->boot_fd, IOCTL_MODEM_BOOT_OFF, 0); + } + return -1; +} + +// vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/xmm6260/xmm6260_modemctl.h b/samsung-ipc/device/xmm6260/xmm6260_modemctl.h new file mode 100644 index 0000000..d71a13a --- /dev/null +++ b/samsung-ipc/device/xmm6260/xmm6260_modemctl.h @@ -0,0 +1,123 @@ +/* + * XMM6260 Modem Control functions + * Copyright (C) 2012 Alexander Tarasikov + * Copyright (C) 2012 Paul Kocialkowski + * + * based on the incomplete C++ implementation which is + * Copyright (C) 2012 Sergey Gridasov + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#ifndef __XMM6260_MODEMCTL_H__ +#define __XMM6260_MODEMCTL_H__ + +#include + +#define MODEM_DEVICE(x) ("/dev/" #x) +#define LINK_PM MODEM_DEVICE(link_pm) +#define MODEM_DEV MODEM_DEVICE(modem_br) +#define BOOT_DEV MODEM_DEVICE(umts_boot0) +#define IPC_DEV MODEM_DEVICE(umts_ipc0) +#define RFS_DEV MODEM_DEVICE(umts_rfs0) + +#define LINK_POLL_DELAY_US (50 * 1000) +#define LINK_TIMEOUT_MS 2000 + +struct modemctl_io_data { + int link_fd; + int boot_fd; + + int radio_fd; + char *radio_data; + struct stat radio_stat; +}; + +/* + * Function prototypes + */ + +/* + * @brief Activates the modem <-> cpu link data transfer + * + * @param client [in] ipc client + * @param io_data [in] modemctl-specific data + * @param enabled [in] whether to enable or disable link data transport + * @return Negative value indicating error code + * @return ioctl call result + */ +int modemctl_link_set_active(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled); + +/* + * @brief Activates the modem <-> cpu link connection + * + * @param client [in] ipc client + * @param io_data [in] modemctl-specific data + * @param enabled [in] the state to set link to + * @return Negative value indicating error code + * @return ioctl call result + */ +int modemctl_link_set_enabled(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled); + +/* + * @brief Poll the link until it gets ready or times out + * + * @param client [in] ipc client + * @param io_data [in] modemctl-specific data + * @return Negative value indicating error code + * @return ioctl call result + */ +int modemctl_wait_link_ready(struct ipc_client *client, + struct modemctl_io_data *io_data); + +/* + * @brief Poll the modem until it gets online or times out + * + * @param client [in] ipc client + * @param io_data [in] modemctl-specific data + * @return Negative value indicating error code + * @return ioctl call result + */ +int modemctl_wait_modem_online(struct ipc_client *client, + struct modemctl_io_data *io_data); + +/* + * @brief Sets the modem power + * + * @param client [in] ipc client + * @param io_data [in] modemctl-specific data + * @param enabled [in] whether to enable or disable modem power + * @return Negative value indicating error code + * @return ioctl call result + */ +int modemctl_modem_power(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled); + +/* + * @brief Sets the modem bootloader power/UART configuration + * + * @param client [in] ipc client + * @param io_data [in] modemctl-specific data + * @param enabled [in] whether to enable or disable power + * @return Negative value indicating error code + * @return ioctl call result + */ +int modemctl_modem_boot_power(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled); + +#endif + +// vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/ipc_devices.c b/samsung-ipc/ipc_devices.c index f686ba7..14c1ff6 100644 --- a/samsung-ipc/ipc_devices.c +++ b/samsung-ipc/ipc_devices.c @@ -18,13 +18,12 @@ * */ +#include + #include #include "ipc_devices.h" - struct ipc_gprs_specs *gprs_specs; - struct ipc_nv_data_specs *nv_data_specs; - struct ipc_device_desc ipc_devices[] = { { .name = "crespo", @@ -56,29 +55,29 @@ struct ipc_device_desc ipc_devices[] = { { .name = "galaxys2", .board_name = "i9100", - .fmt_ops = &xmm6260_i9100_fmt_ops, - .rfs_ops = &xmm6260_rfs_ops, - .handlers = &xmm6260_default_handlers, - .gprs_specs = &xmm6260_gprs_specs, + .fmt_ops = &galaxys2_fmt_ops, + .rfs_ops = &galaxys2_rfs_ops, + .handlers = &galaxys2_default_handlers, + .gprs_specs = &galaxys2_gprs_specs, .nv_data_specs = NULL, }, { .name = "galaxys2", .board_name = "smdk4210", - .fmt_ops = &xmm6260_i9100_fmt_ops, - .rfs_ops = &xmm6260_rfs_ops, - .handlers = &xmm6260_default_handlers, - .gprs_specs = &xmm6260_gprs_specs, + .fmt_ops = &galaxys2_fmt_ops, + .rfs_ops = &galaxys2_rfs_ops, + .handlers = &galaxys2_default_handlers, + .gprs_specs = &galaxys2_gprs_specs, .nv_data_specs = NULL, }, { .name = "maguro", .board_name = "tuna", - .fmt_ops = &xmm6260_i9250_fmt_ops, - .rfs_ops = &xmm6260_rfs_ops, - .handlers = &xmm6260_default_handlers, - .gprs_specs = &xmm6260_gprs_specs, - .nv_data_specs = &xmm6260_nv_data_specs, + .fmt_ops = &maguro_fmt_ops, + .rfs_ops = &maguro_rfs_ops, + .handlers = &maguro_default_handlers, + .gprs_specs = &maguro_gprs_specs, + .nv_data_specs = &maguro_nv_data_specs, } }; diff --git a/samsung-ipc/ipc_devices.h b/samsung-ipc/ipc_devices.h index a780c98..2325878 100644 --- a/samsung-ipc/ipc_devices.h +++ b/samsung-ipc/ipc_devices.h @@ -57,16 +57,21 @@ extern struct ipc_ops aries_rfs_ops; extern struct ipc_handlers aries_default_handlers; extern struct ipc_gprs_specs aries_gprs_specs; -// xmm6260 -// Galaxy S2 (I9100) -// Galaxy Nexus (I9250) - -extern struct ipc_handlers xmm6260_default_handlers; -extern struct ipc_ops xmm6260_rfs_ops; -extern struct ipc_ops xmm6260_i9100_fmt_ops; -extern struct ipc_ops xmm6260_i9250_fmt_ops; -extern struct ipc_gprs_specs xmm6260_gprs_specs; -extern struct ipc_gprs_specs xmm6260_nv_data_specs; +// galaxys2 + +extern struct ipc_ops galaxys2_fmt_ops; +extern struct ipc_ops galaxys2_fmt_ops; +extern struct ipc_ops galaxys2_rfs_ops; +extern struct ipc_handlers galaxys2_default_handlers; +extern struct ipc_gprs_specs galaxys2_gprs_specs; + +// maguro + +extern struct ipc_ops maguro_fmt_ops; +extern struct ipc_ops maguro_rfs_ops; +extern struct ipc_handlers maguro_default_handlers; +extern struct ipc_gprs_specs maguro_gprs_specs; +extern struct ipc_nv_data_specs maguro_nv_data_specs; #endif -- cgit v1.1