aboutsummaryrefslogtreecommitdiffstats
path: root/samsung-ipc/device
diff options
context:
space:
mode:
authorAlexander Tarasikov <alexander.tarasikov@gmail.com>2012-07-02 12:55:22 +0400
committerPaul Kocialkowski <contact@paulk.fr>2012-07-04 17:53:02 +0200
commit2454f7265a17afa73273dc09019adb90f77c0007 (patch)
treef0b6ea5be3baa2332a33d604f97fbfe616b042b2 /samsung-ipc/device
parent3ee91dd1a20083d571718e2ee07570ac2c8cfe7c (diff)
downloadexternal_libsamsung-ipc-2454f7265a17afa73273dc09019adb90f77c0007.zip
external_libsamsung-ipc-2454f7265a17afa73273dc09019adb90f77c0007.tar.gz
external_libsamsung-ipc-2454f7265a17afa73273dc09019adb90f77c0007.tar.bz2
Update firmware loader to the latest version, fix makefiles for
maguro/galaxys2
Diffstat (limited to 'samsung-ipc/device')
-rw-r--r--samsung-ipc/device/xmm6260/common.h2
-rw-r--r--samsung-ipc/device/xmm6260/fwloader_i9100.c18
-rw-r--r--samsung-ipc/device/xmm6260/fwloader_i9250.c193
-rw-r--r--samsung-ipc/device/xmm6260/io_helpers.c21
-rw-r--r--samsung-ipc/device/xmm6260/log.c1
-rw-r--r--samsung-ipc/device/xmm6260/modemctl_common.c47
-rw-r--r--samsung-ipc/device/xmm6260/modemctl_common.h19
7 files changed, 156 insertions, 145 deletions
diff --git a/samsung-ipc/device/xmm6260/common.h b/samsung-ipc/device/xmm6260/common.h
index 9b5e66a..db8c8c7 100644
--- a/samsung-ipc/device/xmm6260/common.h
+++ b/samsung-ipc/device/xmm6260/common.h
@@ -45,6 +45,4 @@
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-#define DEBUG 1
-
#endif //__COMMON_H__
diff --git a/samsung-ipc/device/xmm6260/fwloader_i9100.c b/samsung-ipc/device/xmm6260/fwloader_i9100.c
index b083610..2af85ac 100644
--- a/samsung-ipc/device/xmm6260/fwloader_i9100.c
+++ b/samsung-ipc/device/xmm6260/fwloader_i9100.c
@@ -133,22 +133,6 @@ typedef struct {
uint32_t data_size;
} __attribute__((packed)) bootloader_cmd_t;
-/*
- * Bootloader protocol
- */
-static 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;
-}
-
static int send_image(fwloader_context *ctx, enum xmm6260_image type) {
int ret;
@@ -662,7 +646,7 @@ int boot_modem_i9100(void) {
goto fail;
}
- ctx.boot_fd = open(BOOT_DEV, O_RDWR);
+ ctx.boot_fd = open(BOOT_DEV, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (ctx.boot_fd < 0) {
_e("failed to open boot device");
goto fail;
diff --git a/samsung-ipc/device/xmm6260/fwloader_i9250.c b/samsung-ipc/device/xmm6260/fwloader_i9250.c
index 23cfd42..e5e48be 100644
--- a/samsung-ipc/device/xmm6260/fwloader_i9250.c
+++ b/samsung-ipc/device/xmm6260/fwloader_i9250.c
@@ -22,8 +22,67 @@
#include "modemctl_common.h"
/*
- * I9250 specific implementation
+ * i9250 (Galaxy Nexus) board-specific code
*/
+#define I9250_RADIO_IMAGE "/dev/block/platform/omap/omap_hsmmc.0/by-name/radio"
+#define I9250_SECOND_BOOT_DEV "/dev/umts_boot1"
+
+#define I9250_BOOT_LAST_MARKER 0x0030ffff
+#define I9250_BOOT_REPLY_MAX 20
+
+#define I9250_GENERAL_ACK "\x02\x00\x00\x00"
+
+#define I9250_PSI_START_MAGIC "\xff\xf0\x00\x30"
+#define I9250_PSI_CMD_EXEC "\x08\x00\x00\x00"
+#define I9250_PSI_EXEC_DATA "\x00\x00\x00\x00\x02\x00\x02\x00"
+#define I9250_PSI_READY_ACK "\x00\xaa\x00\x00"
+
+#define I9250_EBL_IMG_ACK_MAGIC "\x51\xa5\x00\x00"
+#define I9250_EBL_HDR_ACK_MAGIC "\xcc\xcc\x00\x00"
+
+#define I9250_MPS_IMAGE_PATH "/factory/imei/mps_code.dat"
+#define I9250_MPS_LOAD_ADDR 0x61080000
+#define I9250_MPS_LENGTH 3
+
+#define SEC_DOWNLOAD_CHUNK 0xdfc2
+#define SEC_DOWNLOAD_DELAY_US (500 * 1000)
+
+ #define FW_LOAD_ADDR 0x60300000
+#define NVDATA_LOAD_ADDR 0x60e80000
+
+#define BL_END_MAGIC "\x00\x00"
+#define BL_END_MAGIC_LEN 2
+
+#define BL_RESET_MAGIC "\x01\x10\x11\x00"
+#define BL_RESET_MAGIC_LEN 4
+
+typedef struct {
+ uint32_t total_size;
+ uint16_t hdr_magic;
+ uint16_t cmd;
+ uint16_t data_size;
+} __attribute__((packed)) bootloader_cmd_hdr_t;
+
+#define DECLARE_BOOT_CMD_HEADER(name, code, size) \
+bootloader_cmd_hdr_t name = {\
+ .total_size = size + 10,\
+ .hdr_magic = 2,\
+ .cmd = code,\
+ .data_size = size,\
+}
+
+typedef struct {
+ uint16_t checksum;
+ uint16_t tail_magic;
+ uint8_t unknown[2];
+} __attribute__((packed)) bootloader_cmd_tail_t;
+
+#define DECLARE_BOOT_TAIL_HEADER(name, checksum) \
+bootloader_cmd_tail_t name = {\
+ .checksum = checksum,\
+ .tail_magic = 3,\
+ .unknown = "\xea\xea",\
+}
/*
* Locations of the firmware components in the Samsung firmware
@@ -89,38 +148,6 @@ struct {
},
};
-typedef struct {
- uint8_t magic;
- uint16_t length;
- uint8_t padding;
-} __attribute__((packed)) psi_header_t;
-
-typedef struct {
- uint8_t data[76];
-} __attribute__((packed)) boot_info_t;
-
-typedef struct {
- uint16_t check;
- uint16_t cmd;
- uint32_t data_size;
-} __attribute__((packed)) bootloader_cmd_t;
-
-/*
- * Bootloader protocol
- */
-static 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;
-}
-
static int reboot_modem_i9250(fwloader_context *ctx, bool hard) {
int ret;
@@ -170,47 +197,6 @@ fail:
return ret;
}
-/*
- * i9250 (Galaxy Nexus) board-specific code
- */
-
-#define I9250_RADIO_IMAGE "/dev/block/platform/omap/omap_hsmmc.0/by-name/radio"
-#define I9250_SECOND_BOOT_DEV "/dev/umts_boot1"
-
-#define I9250_BOOT_LAST_MARKER 0x0030ffff
-#define I9250_BOOT_REPLY_MAX 20
-
-#define I9250_GENERAL_ACK "\x02\x00\x00\x00"
-
-#define I9250_PSI_START_MAGIC "\xff\xf0\x00\x30"
-#define I9250_PSI_CMD_EXEC "\x08\x00\x00\x00"
-#define I9250_PSI_EXEC_DATA "\x00\x00\x00\x00\x02\x00\x02\x00"
-#define I9250_PSI_READY_ACK "\x00\xaa\x00\x00"
-
-#define I9250_EBL_IMG_ACK_MAGIC "\x51\xa5\x00\x00"
-#define I9250_EBL_HDR_ACK_MAGIC "\xcc\xcc\x00\x00"
-
-#define I9250_MPS_IMAGE_PATH "/factory/imei/mps_code.dat"
-#define I9250_MPS_LOAD_ADDR 0x61080000
-#define I9250_MPS_LENGTH 3
-
-#define SEC_DOWNLOAD_CHUNK 0xdfc2
-#define SEC_DOWNLOAD_DELAY_US (500 * 1000)
-
-/* same for i9100 and i9250? */
-
-#define FW_LOAD_ADDR 0x60300000
-#define NVDATA_LOAD_ADDR 0x60e80000
-
-#define BL_END_MAGIC "\x00\x00"
-#define BL_END_MAGIC_LEN 2
-
-#define BL_RESET_MAGIC "\x01\x10\x11\x00"
-#define BL_RESET_MAGIC_LEN 4
-
-#define POST_BOOT_TIMEOUT_US (1000 * 1000)
-
-
static int send_image_i9250(fwloader_context *ctx, enum xmm6260_image type) {
int ret;
@@ -291,7 +277,7 @@ static int send_PSI_i9250(fwloader_context *ctx) {
"\x02\x00\x00\x00",
"\x01\xdd\x00\x00",
};
-
+
int i;
for (i = 0; i < ARRAY_SIZE(expected_acks); i++) {
ret = expect_data(ctx->boot_fd, expected_acks[i], 4);
@@ -366,34 +352,6 @@ fail:
return ret;
}
-typedef struct {
- uint32_t total_size;
- uint16_t hdr_magic;
- uint16_t cmd;
- uint16_t data_size;
-} __attribute__((packed)) bootloader_cmd_hdr_t;
-
-#define DECLARE_BOOT_CMD_HEADER(name, code, size) \
-bootloader_cmd_hdr_t name = {\
- .total_size = size + 10,\
- .hdr_magic = 2,\
- .cmd = code,\
- .data_size = size,\
-}
-
-typedef struct {
- uint16_t checksum;
- uint16_t tail_magic;
- uint8_t unknown[2];
-} __attribute__((packed)) bootloader_cmd_tail_t;
-
-#define DECLARE_BOOT_TAIL_HEADER(name, checksum) \
-bootloader_cmd_tail_t name = {\
- .checksum = checksum,\
- .tail_magic = 3,\
- .unknown = "\xea\xea",\
-}
-
static int bootloader_cmd(fwloader_context *ctx,
enum xmm6260_boot_cmd cmd, void *data, size_t data_size)
{
@@ -407,10 +365,9 @@ static int bootloader_cmd(fwloader_context *ctx,
uint16_t checksum = (data_size & 0xffff) + cmd_code;
unsigned char *ptr = (unsigned char*)data;
-
- size_t c;
- for (c = 0; c < data_size; c++) {
- checksum += ptr[c];
+ size_t i;
+ for (i = 0; i < data_size; i++) {
+ checksum += ptr[i];
}
DECLARE_BOOT_CMD_HEADER(header, cmd_code, data_size);
@@ -462,7 +419,7 @@ static int bootloader_cmd(fwloader_context *ctx,
goto done_or_fail;
}
- if (ack_length + 4> cmd_buffer_size) {
+ if (ack_length + 4 > cmd_buffer_size) {
free(cmd_data);
cmd_data = NULL;
cmd_data = malloc(ack_length + 4);
@@ -473,8 +430,6 @@ static int bootloader_cmd(fwloader_context *ctx,
}
memset(cmd_data, 0, ack_length);
memcpy(cmd_data, &ack_length, 4);
-
- int i;
for (i = 0; i < (ack_length + 3) / 4; i++) {
if ((ret = receive(ctx->boot_fd, cmd_data + ((i + 1) << 2), 4)) < 0) {
_e("failed to receive ack chunk");
@@ -530,8 +485,7 @@ static int ack_BootInfo_i9250(fwloader_context *ctx) {
size_t boot_chunk = 4;
size_t boot_chunk_count = (boot_info_length + boot_chunk - 1) / boot_chunk;
-
- int i;
+ int i;
for (i = 0; i < boot_chunk_count; i++) {
ret = receive(ctx->boot_fd, boot_info + (i * boot_chunk), boot_chunk);
if (ret < 0) {
@@ -725,7 +679,7 @@ int boot_modem_i9250(void) {
goto fail;
}
- ctx.boot_fd = open(BOOT_DEV, O_RDWR);
+ ctx.boot_fd = open(BOOT_DEV, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (ctx.boot_fd < 0) {
_e("failed to open boot device");
goto fail;
@@ -801,7 +755,7 @@ int boot_modem_i9250(void) {
}
close(ctx.boot_fd);
- ctx.boot_fd = open(I9250_SECOND_BOOT_DEV, O_RDWR);
+ ctx.boot_fd = open(I9250_SECOND_BOOT_DEV, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (ctx.boot_fd < 0) {
_e("failed to open " I9250_SECOND_BOOT_DEV " control device");
goto fail;
@@ -854,17 +808,12 @@ int boot_modem_i9250(void) {
_d("Secure Image download complete");
}
- usleep(POST_BOOT_TIMEOUT_US);
-
- if ((ret = reboot_modem_i9250(&ctx, false))) {
- _e("failed to soft reset modem");
+ if ((ret = modemctl_wait_modem_online(&ctx))) {
+ _e("failed to wait for modem to become online");
goto fail;
}
- else {
- _d("modem soft reset done");
- }
- _i("online");
+ _i("modem online");
fail:
if (ctx.radio_data != MAP_FAILED) {
diff --git a/samsung-ipc/device/xmm6260/io_helpers.c b/samsung-ipc/device/xmm6260/io_helpers.c
index 9ecdb43..d1fffe2 100644
--- a/samsung-ipc/device/xmm6260/io_helpers.c
+++ b/samsung-ipc/device/xmm6260/io_helpers.c
@@ -48,6 +48,8 @@ int c_ioctl(int fd, unsigned long code, void* data) {
}
int read_select(int fd, unsigned timeout) {
+ int ret = 0;
+
struct timeval tv = {
tv.tv_sec = timeout / 1000,
tv.tv_usec = 1000 * (timeout % 1000),
@@ -57,17 +59,30 @@ int read_select(int fd, unsigned timeout) {
FD_ZERO(&read_set);
FD_SET(fd, &read_set);
- return select(fd + 1, &read_set, 0, 0, &tv);
+ 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 receive(int fd, void *buf, size_t size) {
int ret;
if ((ret = read_select(fd, DEFAULT_TIMEOUT)) < 1) {
- _e("%s: failed to select the fd %d", __func__, fd);
+ _e("failed to select the fd %d", fd);
return ret;
}
else {
- _d("%s: selected %d fds for fd=%d", __func__, ret, fd);
+ _d("selected %d fds for fd=%d", ret, fd);
}
return read(fd, buf, size);
diff --git a/samsung-ipc/device/xmm6260/log.c b/samsung-ipc/device/xmm6260/log.c
index e5d14e0..c467d0e 100644
--- a/samsung-ipc/device/xmm6260/log.c
+++ b/samsung-ipc/device/xmm6260/log.c
@@ -33,7 +33,6 @@ void hexdump(void* data, size_t size) {
size_t len = size < DUMP_SIZE ? size : DUMP_SIZE;
memset(__hd_buf, 0, sizeof(__hd_buf));
-
int i;
for (i = 0; i < len; i++) {
snprintf(__hd_buf + i * 3, 4, "%02x ", _data[i]);
diff --git a/samsung-ipc/device/xmm6260/modemctl_common.c b/samsung-ipc/device/xmm6260/modemctl_common.c
index 90fd5fe..755e2be 100644
--- a/samsung-ipc/device/xmm6260/modemctl_common.c
+++ b/samsung-ipc/device/xmm6260/modemctl_common.c
@@ -95,6 +95,40 @@ fail:
return ret;
}
+int modemctl_wait_modem_online(fwloader_context *ctx) {
+ int ret;
+
+ struct timeval tv_start = {};
+ struct timeval tv_end = {};
+
+ gettimeofday(&tv_start, 0);;
+
+ //link wakeup timeout in milliseconds
+ long diff = 0;
+
+ do {
+ ret = c_ioctl(ctx->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(fwloader_context *ctx, bool enabled) {
if (enabled) {
return c_ioctl(ctx->boot_fd, IOCTL_MODEM_ON, 0);
@@ -114,3 +148,16 @@ int modemctl_modem_boot_power(fwloader_context *ctx, bool enabled) {
}
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;
+}
+
diff --git a/samsung-ipc/device/xmm6260/modemctl_common.h b/samsung-ipc/device/xmm6260/modemctl_common.h
index 8817d94..2f0d770 100644
--- a/samsung-ipc/device/xmm6260/modemctl_common.h
+++ b/samsung-ipc/device/xmm6260/modemctl_common.h
@@ -110,6 +110,15 @@ int modemctl_link_set_enabled(fwloader_context *ctx, bool enabled);
int modemctl_wait_link_ready(fwloader_context *ctx);
/*
+ * @brief Poll the modem until it gets online or times out
+ *
+ * @param ctx [in] firmware loader context
+ * @return Negative value indicating error code
+ * @return ioctl call result
+ */
+int modemctl_wait_modem_online(fwloader_context *ctx);
+
+/*
* @brief Sets the modem power
*
* @param ctx [in] firmware loader context
@@ -145,4 +154,14 @@ int boot_modem_i9100(void);
*/
int boot_modem_i9250(void);
+/*
+ * @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__