diff options
author | Alexander Tarasikov <alexander.tarasikov@gmail.com> | 2012-07-02 12:55:22 +0400 |
---|---|---|
committer | Paul Kocialkowski <contact@paulk.fr> | 2012-07-04 17:53:02 +0200 |
commit | 2454f7265a17afa73273dc09019adb90f77c0007 (patch) | |
tree | f0b6ea5be3baa2332a33d604f97fbfe616b042b2 /samsung-ipc/device | |
parent | 3ee91dd1a20083d571718e2ee07570ac2c8cfe7c (diff) | |
download | external_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.h | 2 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/fwloader_i9100.c | 18 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/fwloader_i9250.c | 193 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/io_helpers.c | 21 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/log.c | 1 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/modemctl_common.c | 47 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/modemctl_common.h | 19 |
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__ |