diff options
Diffstat (limited to 'samsung-ipc/device/xmm6260/fwloader_i9250.c')
-rw-r--r-- | samsung-ipc/device/xmm6260/fwloader_i9250.c | 193 |
1 files changed, 71 insertions, 122 deletions
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) { |