diff options
author | Paul Kocialkowski <contact@paulk.fr> | 2012-07-05 10:49:06 +0200 |
---|---|---|
committer | Paul Kocialkowski <contact@paulk.fr> | 2012-07-05 10:49:06 +0200 |
commit | ccbc15dc1a83935e4fc8d127151fe58fd8045769 (patch) | |
tree | 9fbbaea5227ace841962943120b7eac48b3cba7a | |
parent | c691ac240ec65a8b6f739fd3f273c4e5b7e00af7 (diff) | |
download | external_libsamsung-ipc-ccbc15dc1a83935e4fc8d127151fe58fd8045769.zip external_libsamsung-ipc-ccbc15dc1a83935e4fc8d127151fe58fd8045769.tar.gz external_libsamsung-ipc-ccbc15dc1a83935e4fc8d127151fe58fd8045769.tar.bz2 |
XMM6260: Fix code indent
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
-rw-r--r-- | samsung-ipc/device/xmm6260/fwloader_i9100.c | 1293 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/fwloader_i9100.h | 2 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/fwloader_i9250.c | 1410 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/fwloader_i9250.h | 2 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/io_helpers.c | 115 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/io_helpers.h | 2 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/log.c | 28 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/log.h | 20 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/modemctl_common.c | 177 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/modemctl_common.h | 36 |
10 files changed, 1551 insertions, 1534 deletions
diff --git a/samsung-ipc/device/xmm6260/fwloader_i9100.c b/samsung-ipc/device/xmm6260/fwloader_i9100.c index d42e426..dc0673b 100644 --- a/samsung-ipc/device/xmm6260/fwloader_i9100.c +++ b/samsung-ipc/device/xmm6260/fwloader_i9100.c @@ -27,455 +27,455 @@ * Locations of the firmware components in the Samsung firmware */ static struct xmm6260_offset { - size_t offset; - size_t length; + size_t offset; + size_t length; } i9100_radio_parts[] = { - [PSI] = { - .offset = 0, - .length = 0xf000, - }, - [EBL] = { - .offset = 0xf000, - .length = 0x19000, - }, - [SECURE_IMAGE] = { - .offset = 0x9ff800, - .length = 0x800, - }, - [FIRMWARE] = { - .offset = 0x28000, - .length = 0x9d8000, - }, - [NVDATA] = { - .offset = 0xa00000, - .length = 2 << 20, - } + [PSI] = { + .offset = 0, + .length = 0xf000, + }, + [EBL] = { + .offset = 0xf000, + .length = 0x19000, + }, + [SECURE_IMAGE] = { + .offset = 0x9ff800, + .length = 0x800, + }, + [FIRMWARE] = { + .offset = 0x28000, + .length = 0x9d8000, + }, + [NVDATA] = { + .offset = 0xa00000, + .length = 2 << 20, + } }; struct { - unsigned code; - size_t data_size; - bool need_ack; + unsigned code; + size_t data_size; + bool need_ack; } i9100_boot_cmd_desc[] = { - [SetPortConf] = { - .code = 0x86, - .data_size = 0x800, - .need_ack = 1, - }, - [ReqSecStart] = { - .code = 0x204, - .data_size = 0x4000, - .need_ack = 1, - }, - [ReqSecEnd] = { - .code = 0x205, - .data_size = 0x4000, - .need_ack = 1, - }, - [ReqForceHwReset] = { - .code = 0x208, - .data_size = 0x4000, - .need_ack = 0, - }, - [ReqFlashSetAddress] = { - .code = 0x802, - .data_size = 0x4000, - .need_ack = 1, - }, - [ReqFlashWriteBlock] = { - .code = 0x804, - .data_size = 0x4000, - .need_ack = 0, - }, + [SetPortConf] = { + .code = 0x86, + .data_size = 0x800, + .need_ack = 1, + }, + [ReqSecStart] = { + .code = 0x204, + .data_size = 0x4000, + .need_ack = 1, + }, + [ReqSecEnd] = { + .code = 0x205, + .data_size = 0x4000, + .need_ack = 1, + }, + [ReqForceHwReset] = { + .code = 0x208, + .data_size = 0x4000, + .need_ack = 0, + }, + [ReqFlashSetAddress] = { + .code = 0x802, + .data_size = 0x4000, + .need_ack = 1, + }, + [ReqFlashWriteBlock] = { + .code = 0x804, + .data_size = 0x4000, + .need_ack = 0, + }, }; typedef struct { - uint8_t magic; - uint16_t length; - uint8_t padding; + uint8_t magic; + uint16_t length; + uint8_t padding; } __attribute__((packed)) psi_header_t; typedef struct { - uint8_t data[76]; + uint8_t data[76]; } __attribute__((packed)) boot_info_t; typedef struct { - uint16_t check; - uint16_t cmd; - uint32_t data_size; + uint16_t check; + uint16_t cmd; + uint32_t data_size; } __attribute__((packed)) bootloader_cmd_t; static int send_image(fwloader_context *ctx, enum xmm6260_image type) { - int ret = -1; - - if (type >= ARRAY_SIZE(i9100_radio_parts)) { - _e("bad image type %x", type); - goto fail; - } - - size_t length = i9100_radio_parts[type].length; - size_t offset = i9100_radio_parts[type].offset; - - size_t start = offset; - size_t end = length + start; - - //dump some image bytes - _d("image start"); - hexdump(ctx->radio_data + start, length); - - while (start < end) { - ret = write(ctx->boot_fd, ctx->radio_data + start, end - start); - if (ret < 0) { - _d("failed to write image chunk"); - goto fail; - } - start += ret; - } - - unsigned char crc = calculateCRC(ctx->radio_data, offset, length); - - if ((ret = write(ctx->boot_fd, &crc, 1)) < 1) { - _d("failed to write CRC"); - goto fail; - } - else { - _d("wrote CRC %x", crc); - } - - return 0; + int ret = -1; + + if (type >= ARRAY_SIZE(i9100_radio_parts)) { + _e("bad image type %x", type); + goto fail; + } + + size_t length = i9100_radio_parts[type].length; + size_t offset = i9100_radio_parts[type].offset; + + size_t start = offset; + size_t end = length + start; + + //dump some image bytes + _d("image start"); + hexdump(ctx->radio_data + start, length); + + while (start < end) { + ret = write(ctx->boot_fd, ctx->radio_data + start, end - start); + if (ret < 0) { + _d("failed to write image chunk"); + goto fail; + } + start += ret; + } + + unsigned char crc = calculateCRC(ctx->radio_data, offset, length); + + if ((ret = write(ctx->boot_fd, &crc, 1)) < 1) { + _d("failed to write CRC"); + goto fail; + } + else { + _d("wrote CRC %x", crc); + } + + return 0; fail: - return ret; + return ret; } static int send_PSI(fwloader_context *ctx) { - size_t length = i9100_radio_parts[PSI].length; - - psi_header_t hdr = { - .magic = XMM_PSI_MAGIC, - .length = length, - .padding = 0xff, - }; - int ret = -1; - - if ((ret = write(ctx->boot_fd, &hdr, sizeof(hdr))) != sizeof(hdr)) { - _d("%s: failed to write header, ret %d", __func__, ret); - goto fail; - } - - if ((ret = send_image(ctx, PSI)) < 0) { - _e("failed to send PSI image"); - goto fail; - } - - int i; - for (i = 0; i < 22; i++) { - char ack; - if (receive(ctx->boot_fd, &ack, 1) < 1) { - _d("failed to read ACK byte %d", i); - goto fail; - } - _d("%02x ", ack); - } - - if ((ret = expect_data(ctx->boot_fd, "\x1", 1)) < 0) { - _d("failed to wait for first ACK"); - goto fail; - } - - if ((ret = expect_data(ctx->boot_fd, "\x1", 1)) < 0) { - _d("failed to wait for second ACK"); - goto fail; - } - - if ((ret = expect_data(ctx->boot_fd, PSI_ACK_MAGIC, 2)) < 0) { - _e("failed to receive PSI ACK"); - goto fail; - } - else { - _d("received PSI ACK"); - } - - return 0; + size_t length = i9100_radio_parts[PSI].length; + + psi_header_t hdr = { + .magic = XMM_PSI_MAGIC, + .length = length, + .padding = 0xff, + }; + int ret = -1; + + if ((ret = write(ctx->boot_fd, &hdr, sizeof(hdr))) != sizeof(hdr)) { + _d("%s: failed to write header, ret %d", __func__, ret); + goto fail; + } + + if ((ret = send_image(ctx, PSI)) < 0) { + _e("failed to send PSI image"); + goto fail; + } + + int i; + for (i = 0; i < 22; i++) { + char ack; + if (receive(ctx->boot_fd, &ack, 1) < 1) { + _d("failed to read ACK byte %d", i); + goto fail; + } + _d("%02x ", ack); + } + + if ((ret = expect_data(ctx->boot_fd, "\x1", 1)) < 0) { + _d("failed to wait for first ACK"); + goto fail; + } + + if ((ret = expect_data(ctx->boot_fd, "\x1", 1)) < 0) { + _d("failed to wait for second ACK"); + goto fail; + } + + if ((ret = expect_data(ctx->boot_fd, PSI_ACK_MAGIC, 2)) < 0) { + _e("failed to receive PSI ACK"); + goto fail; + } + else { + _d("received PSI ACK"); + } + + return 0; fail: - return ret; + return ret; } static int send_EBL(fwloader_context *ctx) { - int ret; - int fd = ctx->boot_fd; - unsigned length = i9100_radio_parts[EBL].length; - - if ((ret = write(fd, &length, sizeof(length))) < 0) { - _e("failed to write EBL length"); - goto fail; - } - - if ((ret = expect_data(fd, EBL_HDR_ACK_MAGIC, 2)) < 0) { - _e("failed to wait for EBL header ACK"); - goto fail; - } - - if ((ret = send_image(ctx, EBL)) < 0) { - _e("failed to send EBL image"); - goto fail; - } - - if ((ret = expect_data(fd, EBL_IMG_ACK_MAGIC, 2)) < 0) { - _e("failed to wait for EBL image ACK"); - goto fail; - } - - return 0; + int ret; + int fd = ctx->boot_fd; + unsigned length = i9100_radio_parts[EBL].length; + + if ((ret = write(fd, &length, sizeof(length))) < 0) { + _e("failed to write EBL length"); + goto fail; + } + + if ((ret = expect_data(fd, EBL_HDR_ACK_MAGIC, 2)) < 0) { + _e("failed to wait for EBL header ACK"); + goto fail; + } + + if ((ret = send_image(ctx, EBL)) < 0) { + _e("failed to send EBL image"); + goto fail; + } + + if ((ret = expect_data(fd, EBL_IMG_ACK_MAGIC, 2)) < 0) { + _e("failed to wait for EBL image ACK"); + goto fail; + } + + return 0; fail: - return ret; + return ret; } static int bootloader_cmd(fwloader_context *ctx, enum xmm6260_boot_cmd cmd, - void *data, size_t data_size) + void *data, size_t data_size) { - int ret = 0; - char *cmd_data = 0; - if (cmd >= ARRAY_SIZE(i9100_boot_cmd_desc)) { - _e("bad command %x\n", cmd); - goto done_or_fail; - } - - unsigned cmd_code = i9100_boot_cmd_desc[cmd].code; - - uint16_t magic = (data_size & 0xffff) + cmd_code; - unsigned char *ptr = (unsigned char*)data; - size_t i; - for (i = 0; i < data_size; i++) { - magic += ptr[i]; - } - - bootloader_cmd_t header = { - .check = magic, - .cmd = cmd_code, - .data_size = data_size, - }; - - size_t cmd_size = i9100_boot_cmd_desc[cmd].data_size; - size_t buf_size = cmd_size + sizeof(header); - - cmd_data = (char*)malloc(buf_size); - if (!cmd_data) { - _e("failed to allocate command buffer"); - ret = -ENOMEM; - goto done_or_fail; - } - memset(cmd_data, 0, buf_size); - memcpy(cmd_data, &header, sizeof(header)); - memcpy(cmd_data + sizeof(header), data, data_size); - - _d("bootloader cmd packet"); - hexdump(cmd_data, buf_size); - - if ((ret = write(ctx->boot_fd, cmd_data, buf_size)) < 0) { - _e("failed to write command to socket"); - goto done_or_fail; - } - - if ((unsigned)ret != buf_size) { - _e("written %d bytes of %d", ret, buf_size); - ret = -EINVAL; - goto done_or_fail; - } - - _d("sent command %x magic=%x", header.cmd, header.check); - - if (!i9100_boot_cmd_desc[cmd].need_ack) { - ret = 0; - goto done_or_fail; - } - - bootloader_cmd_t ack = { - .check = 0, - }; - if ((ret = receive(ctx->boot_fd, &ack, sizeof(ack))) < 0) { - _e("failed to receive ack for cmd %x", header.cmd); - goto done_or_fail; - } - - if (ret != sizeof(ack)) { - _e("received %x bytes of %x for ack", ret, sizeof(ack)); - ret = -EINVAL; - goto done_or_fail; - } - - hexdump(&ack, sizeof(ack)); - - if (ack.cmd != header.cmd) { - _e("ack cmd %x does not match request %x", ack.cmd, header.cmd); - ret = -EINVAL; - goto done_or_fail; - } - - if ((ret = receive(ctx->boot_fd, cmd_data, cmd_size)) < 0) { - _e("failed to receive reply data"); - goto done_or_fail; - } - - if ((unsigned)ret != cmd_size) { - _e("received %x bytes of %x for reply data", ret, cmd_size); - ret = -EINVAL; - goto done_or_fail; - } - hexdump(cmd_data, cmd_size); + int ret = 0; + char *cmd_data = 0; + if (cmd >= ARRAY_SIZE(i9100_boot_cmd_desc)) { + _e("bad command %x\n", cmd); + goto done_or_fail; + } + + unsigned cmd_code = i9100_boot_cmd_desc[cmd].code; + + uint16_t magic = (data_size & 0xffff) + cmd_code; + unsigned char *ptr = (unsigned char*)data; + size_t i; + for (i = 0; i < data_size; i++) { + magic += ptr[i]; + } + + bootloader_cmd_t header = { + .check = magic, + .cmd = cmd_code, + .data_size = data_size, + }; + + size_t cmd_size = i9100_boot_cmd_desc[cmd].data_size; + size_t buf_size = cmd_size + sizeof(header); + + cmd_data = (char*)malloc(buf_size); + if (!cmd_data) { + _e("failed to allocate command buffer"); + ret = -ENOMEM; + goto done_or_fail; + } + memset(cmd_data, 0, buf_size); + memcpy(cmd_data, &header, sizeof(header)); + memcpy(cmd_data + sizeof(header), data, data_size); + + _d("bootloader cmd packet"); + hexdump(cmd_data, buf_size); + + if ((ret = write(ctx->boot_fd, cmd_data, buf_size)) < 0) { + _e("failed to write command to socket"); + goto done_or_fail; + } + + if ((unsigned)ret != buf_size) { + _e("written %d bytes of %d", ret, buf_size); + ret = -EINVAL; + goto done_or_fail; + } + + _d("sent command %x magic=%x", header.cmd, header.check); + + if (!i9100_boot_cmd_desc[cmd].need_ack) { + ret = 0; + goto done_or_fail; + } + + bootloader_cmd_t ack = { + .check = 0, + }; + if ((ret = receive(ctx->boot_fd, &ack, sizeof(ack))) < 0) { + _e("failed to receive ack for cmd %x", header.cmd); + goto done_or_fail; + } + + if (ret != sizeof(ack)) { + _e("received %x bytes of %x for ack", ret, sizeof(ack)); + ret = -EINVAL; + goto done_or_fail; + } + + hexdump(&ack, sizeof(ack)); + + if (ack.cmd != header.cmd) { + _e("ack cmd %x does not match request %x", ack.cmd, header.cmd); + ret = -EINVAL; + goto done_or_fail; + } + + if ((ret = receive(ctx->boot_fd, cmd_data, cmd_size)) < 0) { + _e("failed to receive reply data"); + goto done_or_fail; + } + + if ((unsigned)ret != cmd_size) { + _e("received %x bytes of %x for reply data", ret, cmd_size); + ret = -EINVAL; + goto done_or_fail; + } + hexdump(cmd_data, cmd_size); done_or_fail: - if (cmd_data) { - free(cmd_data); - } + if (cmd_data) { + free(cmd_data); + } - return ret; + return ret; } static int ack_BootInfo(fwloader_context *ctx) { - int ret; - boot_info_t info; - - if ((ret = receive(ctx->boot_fd, &info, sizeof(info))) != sizeof(info)) { - _e("failed to receive Boot Info ret=%d", ret); - ret = -1; - goto fail; - } - else { - _d("received Boot Info"); - hexdump(&info, sizeof(info)); - } - - if ((ret = bootloader_cmd(ctx, SetPortConf, &info, sizeof(info))) < 0) { - _e("failed to send SetPortConf command"); - goto fail; - } - else { - _d("sent SetPortConf command"); - } - - return 0; + int ret; + boot_info_t info; + + if ((ret = receive(ctx->boot_fd, &info, sizeof(info))) != sizeof(info)) { + _e("failed to receive Boot Info ret=%d", ret); + ret = -1; + goto fail; + } + else { + _d("received Boot Info"); + hexdump(&info, sizeof(info)); + } + + if ((ret = bootloader_cmd(ctx, SetPortConf, &info, sizeof(info))) < 0) { + _e("failed to send SetPortConf command"); + goto fail; + } + else { + _d("sent SetPortConf command"); + } + + return 0; fail: - return ret; + return ret; } static int send_image_data(fwloader_context *ctx, uint32_t addr, - void *data, int data_len) + void *data, int data_len) { - int ret = 0; - int count = 0; - char *data_p = (char *) data; - - if ((ret = bootloader_cmd(ctx, ReqFlashSetAddress, &addr, 4)) < 0) { - _e("failed to send ReqFlashSetAddress"); - goto fail; - } - else { - _d("sent ReqFlashSetAddress"); - } - - while (count < data_len) { - int rest = data_len - count; - int chunk = rest < SEC_DOWNLOAD_CHUNK ? rest : SEC_DOWNLOAD_CHUNK; - - ret = bootloader_cmd(ctx, ReqFlashWriteBlock, data_p, chunk); - if (ret < 0) { - _e("failed to send data chunk"); - goto fail; - } - - data_p += chunk; - count += chunk; - } - - usleep(SEC_DOWNLOAD_DELAY_US); + int ret = 0; + int count = 0; + char *data_p = (char *) data; + + if ((ret = bootloader_cmd(ctx, ReqFlashSetAddress, &addr, 4)) < 0) { + _e("failed to send ReqFlashSetAddress"); + goto fail; + } + else { + _d("sent ReqFlashSetAddress"); + } + + while (count < data_len) { + int rest = data_len - count; + int chunk = rest < SEC_DOWNLOAD_CHUNK ? rest : SEC_DOWNLOAD_CHUNK; + + ret = bootloader_cmd(ctx, ReqFlashWriteBlock, data_p, chunk); + if (ret < 0) { + _e("failed to send data chunk"); + goto fail; + } + + data_p += chunk; + count += chunk; + } + + usleep(SEC_DOWNLOAD_DELAY_US); fail: - return ret; + return ret; } static int send_image_addr(fwloader_context *ctx, uint32_t addr, - enum xmm6260_image type) + enum xmm6260_image type) { - uint32_t offset = i9100_radio_parts[type].offset; - uint32_t length = i9100_radio_parts[type].length; - char *start = ctx->radio_data + offset; - int ret = 0; + uint32_t offset = i9100_radio_parts[type].offset; + uint32_t length = i9100_radio_parts[type].length; + char *start = ctx->radio_data + offset; + int ret = 0; - ret = send_image_data(ctx, addr, start, length); + ret = send_image_data(ctx, addr, start, length); - return ret; + return ret; } static int send_SecureImage(fwloader_context *ctx) { - int ret = 0; - - uint32_t sec_off = i9100_radio_parts[SECURE_IMAGE].offset; - uint32_t sec_len = i9100_radio_parts[SECURE_IMAGE].length; - void *sec_img = ctx->radio_data + sec_off; - void *nv_data = NULL; - - if ((ret = bootloader_cmd(ctx, ReqSecStart, sec_img, sec_len)) < 0) { - _e("failed to write ReqSecStart"); - goto fail; - } - else { - _d("sent ReqSecStart"); - } - - if ((ret = send_image_addr(ctx, FW_LOAD_ADDR, FIRMWARE)) < 0) { - _e("failed to send FIRMWARE image"); - goto fail; - } - else { - _d("sent FIRMWARE image"); - } - - nv_data_check(ctx->client); - nv_data_md5_check(ctx->client); - - nv_data = ipc_file_read(ctx->client, nv_data_path(ctx->client), 2 << 20, 1024); - if (nv_data == NULL) { - _e("failed to read NVDATA image"); - goto fail; - } - - if ((ret = send_image_data(ctx, NVDATA_LOAD_ADDR, nv_data, 2 << 20)) < 0) { - _e("failed to send NVDATA image"); - goto fail; - } - else { - _d("sent NVDATA image"); - } - - free(nv_data); - - if ((ret = bootloader_cmd(ctx, ReqSecEnd, - BL_END_MAGIC, BL_END_MAGIC_LEN)) < 0) - { - _e("failed to write ReqSecEnd"); - goto fail; - } - else { - _d("sent ReqSecEnd"); - } - - ret = bootloader_cmd(ctx, ReqForceHwReset, - BL_RESET_MAGIC, BL_RESET_MAGIC_LEN); - if (ret < 0) { - _e("failed to write ReqForceHwReset"); - goto fail; - } - else { - _d("sent ReqForceHwReset"); - } + int ret = 0; + + uint32_t sec_off = i9100_radio_parts[SECURE_IMAGE].offset; + uint32_t sec_len = i9100_radio_parts[SECURE_IMAGE].length; + void *sec_img = ctx->radio_data + sec_off; + void *nv_data = NULL; + + if ((ret = bootloader_cmd(ctx, ReqSecStart, sec_img, sec_len)) < 0) { + _e("failed to write ReqSecStart"); + goto fail; + } + else { + _d("sent ReqSecStart"); + } + + if ((ret = send_image_addr(ctx, FW_LOAD_ADDR, FIRMWARE)) < 0) { + _e("failed to send FIRMWARE image"); + goto fail; + } + else { + _d("sent FIRMWARE image"); + } + + nv_data_check(ctx->client); + nv_data_md5_check(ctx->client); + + nv_data = ipc_file_read(ctx->client, nv_data_path(ctx->client), 2 << 20, 1024); + if (nv_data == NULL) { + _e("failed to read NVDATA image"); + goto fail; + } + + if ((ret = send_image_data(ctx, NVDATA_LOAD_ADDR, nv_data, 2 << 20)) < 0) { + _e("failed to send NVDATA image"); + goto fail; + } + else { + _d("sent NVDATA image"); + } + + free(nv_data); + + if ((ret = bootloader_cmd(ctx, ReqSecEnd, + BL_END_MAGIC, BL_END_MAGIC_LEN)) < 0) + { + _e("failed to write ReqSecEnd"); + goto fail; + } + else { + _d("sent ReqSecEnd"); + } + + ret = bootloader_cmd(ctx, ReqForceHwReset, + BL_RESET_MAGIC, BL_RESET_MAGIC_LEN); + if (ret < 0) { + _e("failed to write ReqForceHwReset"); + goto fail; + } + else { + _d("sent ReqForceHwReset"); + } fail: - return ret; + return ret; } /* @@ -486,277 +486,278 @@ fail: * Power management */ static int i9100_ehci_setpower(bool enabled) { - int ret = -1; - - _d("%s: enabled=%d", __func__, enabled); - - int ehci_fd = open(I9100_EHCI_PATH, O_RDWR); - if (ehci_fd < 0) { - _e("failed to open EHCI fd"); - ret = -ENODEV; - goto fail; - } - else { - _d("opened EHCI %s: fd=%d", I9100_EHCI_PATH, ehci_fd); - } - - ret = write(ehci_fd, enabled ? "1" : "0", 1); - - //must write exactly one byte - if (ret <= 0) { - _e("failed to set EHCI power"); - } - else { - _d("set EHCI power"); - } + int ret = -1; + + _d("%s: enabled=%d", __func__, enabled); + + int ehci_fd = open(I9100_EHCI_PATH, O_RDWR); + if (ehci_fd < 0) { + _e("failed to open EHCI fd"); + ret = -ENODEV; + goto fail; + } + else { + _d("opened EHCI %s: fd=%d", I9100_EHCI_PATH, ehci_fd); + } + + ret = write(ehci_fd, enabled ? "1" : "0", 1); + + //must write exactly one byte + if (ret <= 0) { + _e("failed to set EHCI power"); + } + else { + _d("set EHCI power"); + } fail: - if (ehci_fd >= 0) { - close(ehci_fd); - } + if (ehci_fd >= 0) { + close(ehci_fd); + } - return ret; + return ret; } static int reboot_modem_i9100(fwloader_context *ctx, bool hard) { - int ret; - - //wait for link to become ready before redetection - if (!hard) { - if ((ret = modemctl_wait_link_ready(ctx)) < 0) { - _e("failed to wait for link to get ready for redetection"); - goto fail; - } - else { - _d("link ready for redetection"); - } - } - - /* - * Disable the hardware to ensure consistent state - */ - if (hard) { - if ((ret = modemctl_modem_power(ctx, false)) < 0) { - _e("failed to disable xmm6260 power"); - goto fail; - } - else { - _d("disabled xmm6260 power"); - } - } - - if ((ret = modemctl_link_set_enabled(ctx, false)) < 0) { - _e("failed to disable I9100 HSIC link"); - goto fail; - } - else { - _d("disabled I9100 HSIC link"); - } - - if ((ret = i9100_ehci_setpower(false)) < 0) { - _e("failed to disable I9100 EHCI"); - goto fail; - } - else { - _d("disabled I9100 EHCI"); - } - - if ((ret = modemctl_link_set_active(ctx, false)) < 0) { - _e("failed to deactivate I9100 HSIC link"); - goto fail; - } - else { - _d("deactivated I9100 HSIC link"); - } - - /* - * Now, initialize the hardware - */ - - if ((ret = modemctl_link_set_enabled(ctx, true)) < 0) { - _e("failed to enable I9100 HSIC link"); - goto fail; - } - else { - _d("enabled I9100 HSIC link"); - } - - if ((ret = i9100_ehci_setpower(true)) < 0) { - _e("failed to enable I9100 EHCI"); - goto fail; - } - else { - _d("enabled I9100 EHCI"); - } - - if ((ret = modemctl_link_set_active(ctx, true)) < 0) { - _e("failed to activate I9100 HSIC link"); - goto fail; - } - else { - _d("activated I9100 HSIC link"); - } - - if (hard) { - if ((ret = modemctl_modem_power(ctx, true)) < 0) { - _e("failed to enable xmm6260 power"); - goto fail; - } - else { - _d("enabled xmm6260 power"); - } - } - - if ((ret = modemctl_wait_link_ready(ctx)) < 0) { - _e("failed to wait for link to get ready"); - goto fail; - } - else { - _d("link ready"); - } - + int ret; + + //wait for link to become ready before redetection + if (!hard) { + if ((ret = modemctl_wait_link_ready(ctx)) < 0) { + _e("failed to wait for link to get ready for redetection"); + goto fail; + } + else { + _d("link ready for redetection"); + } + } + + /* + * Disable the hardware to ensure consistent state + */ + if (hard) { + if ((ret = modemctl_modem_power(ctx, false)) < 0) { + _e("failed to disable xmm6260 power"); + goto fail; + } + else { + _d("disabled xmm6260 power"); + } + } + + if ((ret = modemctl_link_set_enabled(ctx, false)) < 0) { + _e("failed to disable I9100 HSIC link"); + goto fail; + } + else { + _d("disabled I9100 HSIC link"); + } + + if ((ret = i9100_ehci_setpower(false)) < 0) { + _e("failed to disable I9100 EHCI"); + goto fail; + } + else { + _d("disabled I9100 EHCI"); + } + + if ((ret = modemctl_link_set_active(ctx, false)) < 0) { + _e("failed to deactivate I9100 HSIC link"); + goto fail; + } + else { + _d("deactivated I9100 HSIC link"); + } + + /* + * Now, initialize the hardware + */ + + if ((ret = modemctl_link_set_enabled(ctx, true)) < 0) { + _e("failed to enable I9100 HSIC link"); + goto fail; + } + else { + _d("enabled I9100 HSIC link"); + } + + if ((ret = i9100_ehci_setpower(true)) < 0) { + _e("failed to enable I9100 EHCI"); + goto fail; + } + else { + _d("enabled I9100 EHCI"); + } + + if ((ret = modemctl_link_set_active(ctx, true)) < 0) { + _e("failed to activate I9100 HSIC link"); + goto fail; + } + else { + _d("activated I9100 HSIC link"); + } + + if (hard) { + if ((ret = modemctl_modem_power(ctx, true)) < 0) { + _e("failed to enable xmm6260 power"); + goto fail; + } + else { + _d("enabled xmm6260 power"); + } + } + + if ((ret = modemctl_wait_link_ready(ctx)) < 0) { + _e("failed to wait for link to get ready"); + goto fail; + } + else { + _d("link ready"); + } + fail: - return ret; + return ret; } int boot_modem_i9100(struct ipc_client *client) { - int ret = 0; - fwloader_context ctx; - memset(&ctx, 0, sizeof(ctx)); - - ctx.client = client; - - ctx.radio_fd = open(RADIO_IMAGE, O_RDONLY); - if (ctx.radio_fd < 0) { - _e("failed to open radio firmware"); - goto fail; - } - else { - _d("opened radio image %s, fd=%d", RADIO_IMAGE, ctx.radio_fd); - } - - if (fstat(ctx.radio_fd, &ctx.radio_stat) < 0) { - _e("failed to stat radio image, error %s", strerror(errno)); - goto fail; - } - - ctx.radio_data = mmap(0, RADIO_MAP_SIZE, PROT_READ, MAP_SHARED, - ctx.radio_fd, 0); - if (ctx.radio_data == MAP_FAILED) { - _e("failed to mmap radio image, error %s", strerror(errno)); - goto fail; - } - - 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; - } - else { - _d("opened boot device %s, fd=%d", BOOT_DEV, ctx.boot_fd); - } - - ctx.link_fd = open(LINK_PM, O_RDWR); - if (ctx.link_fd < 0) { - _e("failed to open link device"); - goto fail; - } - else { - _d("opened link device %s, fd=%d", LINK_PM, ctx.link_fd); - } - - if (reboot_modem_i9100(&ctx, true)) { - _e("failed to hard reset modem"); - goto fail; - } - else { - _d("modem hard reset done"); - } - - /* - * Now, actually load the firmware - */ - if (write(ctx.boot_fd, "ATAT", 4) != 4) { - _e("failed to write ATAT to boot socket"); - goto fail; - } - else { - _d("written ATAT to boot socket, waiting for ACK"); - } - - char buf[2]; - if (receive(ctx.boot_fd, buf, 1) < 0) { - _e("failed to receive bootloader ACK"); - goto fail; - } - if (receive(ctx.boot_fd, buf + 1, 1) < 0) { - _e("failed to receive chip IP ACK"); - goto fail; - } - _i("receive ID: [%02x %02x]", buf[0], buf[1]); - - if ((ret = send_PSI(&ctx)) < 0) { - _e("failed to upload PSI"); - goto fail; - } - else { - _d("PSI download complete"); - } - - if ((ret = send_EBL(&ctx)) < 0) { - _e("failed to upload EBL"); - goto fail; - } - else { - _d("EBL download complete"); - } - - if ((ret = ack_BootInfo(&ctx)) < 0) { - _e("failed to receive Boot Info"); - goto fail; - } - else { - _d("Boot Info ACK done"); - } - - if ((ret = send_SecureImage(&ctx)) < 0) { - _e("failed to upload Secure Image"); - goto fail; - } - else { - _d("Secure Image download complete"); - } - - usleep(POST_BOOT_TIMEOUT_US); - - if ((ret = reboot_modem_i9100(&ctx, false))) { - _e("failed to soft reset modem"); - goto fail; - } - else { - _d("modem soft reset done"); - } - - _i("online"); - ret = 0; + int ret = 0; + fwloader_context ctx; + memset(&ctx, 0, sizeof(ctx)); + + ctx.client = client; + + ctx.radio_fd = open(RADIO_IMAGE, O_RDONLY); + if (ctx.radio_fd < 0) { + _e("failed to open radio firmware"); + goto fail; + } + else { + _d("opened radio image %s, fd=%d", RADIO_IMAGE, ctx.radio_fd); + } + + if (fstat(ctx.radio_fd, &ctx.radio_stat) < 0) { + _e("failed to stat radio image, error %s", strerror(errno)); + goto fail; + } + + ctx.radio_data = mmap(0, RADIO_MAP_SIZE, PROT_READ, MAP_SHARED, + ctx.radio_fd, 0); + if (ctx.radio_data == MAP_FAILED) { + _e("failed to mmap radio image, error %s", strerror(errno)); + goto fail; + } + + 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; + } + else { + _d("opened boot device %s, fd=%d", BOOT_DEV, ctx.boot_fd); + } + + ctx.link_fd = open(LINK_PM, O_RDWR); + if (ctx.link_fd < 0) { + _e("failed to open link device"); + goto fail; + } + else { + _d("opened link device %s, fd=%d", LINK_PM, ctx.link_fd); + } + + if (reboot_modem_i9100(&ctx, true)) { + _e("failed to hard reset modem"); + goto fail; + } + else { + _d("modem hard reset done"); + } + + /* + * Now, actually load the firmware + */ + if (write(ctx.boot_fd, "ATAT", 4) != 4) { + _e("failed to write ATAT to boot socket"); + goto fail; + } + else { + _d("written ATAT to boot socket, waiting for ACK"); + } + + char buf[2]; + if (receive(ctx.boot_fd, buf, 1) < 0) { + _e("failed to receive bootloader ACK"); + goto fail; + } + if (receive(ctx.boot_fd, buf + 1, 1) < 0) { + _e("failed to receive chip IP ACK"); + goto fail; + } + _i("receive ID: [%02x %02x]", buf[0], buf[1]); + + if ((ret = send_PSI(&ctx)) < 0) { + _e("failed to upload PSI"); + goto fail; + } + else { + _d("PSI download complete"); + } + + if ((ret = send_EBL(&ctx)) < 0) { + _e("failed to upload EBL"); + goto fail; + } + else { + _d("EBL download complete"); + } + + if ((ret = ack_BootInfo(&ctx)) < 0) { + _e("failed to receive Boot Info"); + goto fail; + } + else { + _d("Boot Info ACK done"); + } + + if ((ret = send_SecureImage(&ctx)) < 0) { + _e("failed to upload Secure Image"); + goto fail; + } + else { + _d("Secure Image download complete"); + } + + usleep(POST_BOOT_TIMEOUT_US); + + if ((ret = reboot_modem_i9100(&ctx, false))) { + _e("failed to soft reset modem"); + goto fail; + } + else { + _d("modem soft reset done"); + } + + _i("online"); + ret = 0; fail: - if (ctx.radio_data != MAP_FAILED) { - munmap(ctx.radio_data, RADIO_MAP_SIZE); - } + if (ctx.radio_data != MAP_FAILED) { + munmap(ctx.radio_data, RADIO_MAP_SIZE); + } - if (ctx.link_fd >= 0) { - close(ctx.link_fd); - } + if (ctx.link_fd >= 0) { + close(ctx.link_fd); + } - if (ctx.radio_fd >= 0) { - close(ctx.radio_fd); - } + if (ctx.radio_fd >= 0) { + close(ctx.radio_fd); + } - if (ctx.boot_fd >= 0) { - close(ctx.boot_fd); - } + if (ctx.boot_fd >= 0) { + close(ctx.boot_fd); + } - return ret; + return ret; } +// vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/xmm6260/fwloader_i9100.h b/samsung-ipc/device/xmm6260/fwloader_i9100.h index 353bdd0..7cc18b2 100644 --- a/samsung-ipc/device/xmm6260/fwloader_i9100.h +++ b/samsung-ipc/device/xmm6260/fwloader_i9100.h @@ -49,3 +49,5 @@ #define NVDATA_LOAD_ADDR 0x60e80000 #endif + +// vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/xmm6260/fwloader_i9250.c b/samsung-ipc/device/xmm6260/fwloader_i9250.c index eb74dc2..af7d541 100644 --- a/samsung-ipc/device/xmm6260/fwloader_i9250.c +++ b/samsung-ipc/device/xmm6260/fwloader_i9250.c @@ -24,60 +24,60 @@ #include "fwloader_i9250.h" typedef struct { - uint32_t total_size; - uint16_t hdr_magic; - uint16_t cmd; - uint16_t data_size; + 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,\ + .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]; + 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",\ + .checksum = checksum,\ + .tail_magic = 3,\ + .unknown = "\xea\xea",\ } /* * Locations of the firmware components in the Samsung firmware */ static struct xmm6260_offset { - size_t offset; - size_t length; + size_t offset; + size_t length; } i9250_radio_parts[] = { - [PSI] = { - .offset = 0, - .length = 0xf000, - }, - [EBL] = { - .offset = 0xf000, - .length = 0x19000, - }, - [SECURE_IMAGE] = { - .offset = 0x9ff800, - .length = 0x800, - }, - [FIRMWARE] = { - .offset = 0x28000, - .length = 0x9d8000, - }, - [NVDATA] = { - .offset = 0xa00000, - .length = 2 << 20, - } + [PSI] = { + .offset = 0, + .length = 0xf000, + }, + [EBL] = { + .offset = 0xf000, + .length = 0x19000, + }, + [SECURE_IMAGE] = { + .offset = 0x9ff800, + .length = 0x800, + }, + [FIRMWARE] = { + .offset = 0x28000, + .length = 0x9d8000, + }, + [NVDATA] = { + .offset = 0xa00000, + .length = 2 << 20, + } }; /* @@ -86,741 +86,743 @@ static struct xmm6260_offset { */ struct { - unsigned code; - bool long_tail; - bool no_ack; + unsigned code; + bool long_tail; + bool no_ack; } i9250_boot_cmd_desc[] = { - [SetPortConf] = { - .code = 0x86, - .long_tail = 1, - }, - [ReqSecStart] = { - .code = 0x204, - .long_tail = 1, - }, - [ReqSecEnd] = { - .code = 0x205, - }, - [ReqForceHwReset] = { - .code = 0x208, - .long_tail = 1, - .no_ack = 1, - }, - [ReqFlashSetAddress] = { - .code = 0x802, - .long_tail = 1, - }, - [ReqFlashWriteBlock] = { - .code = 0x804, - }, + [SetPortConf] = { + .code = 0x86, + .long_tail = 1, + }, + [ReqSecStart] = { + .code = 0x204, + .long_tail = 1, + }, + [ReqSecEnd] = { + .code = 0x205, + }, + [ReqForceHwReset] = { + .code = 0x208, + .long_tail = 1, + .no_ack = 1, + }, + [ReqFlashSetAddress] = { + .code = 0x802, + .long_tail = 1, + }, + [ReqFlashWriteBlock] = { + .code = 0x804, + }, }; static int reboot_modem_i9250(fwloader_context *ctx, bool hard) { - int ret; - - if (!hard) { - return 0; - } - - /* - * Disable the hardware to ensure consistent state - */ - if ((ret = modemctl_modem_power(ctx, false)) < 0) { - _e("failed to disable modem power"); - goto fail; - } - else { - _d("disabled modem power"); - } - - if ((ret = modemctl_modem_boot_power(ctx, false)) < 0) { - _e("failed to disable modem boot power"); - goto fail; - } - else { - _d("disabled modem boot power"); - } - - /* - * Now, initialize the hardware - */ - if ((ret = modemctl_modem_boot_power(ctx, true)) < 0) { - _e("failed to enable modem boot power"); - goto fail; - } - else { - _d("enabled modem boot power"); - } - - if ((ret = modemctl_modem_power(ctx, true)) < 0) { - _e("failed to enable modem power"); - goto fail; - } - else { - _d("enabled modem power"); - } + int ret; + + if (!hard) { + return 0; + } + + /* + * Disable the hardware to ensure consistent state + */ + if ((ret = modemctl_modem_power(ctx, false)) < 0) { + _e("failed to disable modem power"); + goto fail; + } + else { + _d("disabled modem power"); + } + + if ((ret = modemctl_modem_boot_power(ctx, false)) < 0) { + _e("failed to disable modem boot power"); + goto fail; + } + else { + _d("disabled modem boot power"); + } + + /* + * Now, initialize the hardware + */ + if ((ret = modemctl_modem_boot_power(ctx, true)) < 0) { + _e("failed to enable modem boot power"); + goto fail; + } + else { + _d("enabled modem boot power"); + } + + if ((ret = modemctl_modem_power(ctx, true)) < 0) { + _e("failed to enable modem power"); + goto fail; + } + else { + _d("enabled modem power"); + } fail: - return ret; + return ret; } static int send_image_i9250(fwloader_context *ctx, enum xmm6260_image type) { - int ret = -1; - - if (type >= ARRAY_SIZE(i9250_radio_parts)) { - _e("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 start = offset; - size_t end = length + start; - - unsigned char crc = calculateCRC(ctx->radio_data, offset, length); - - //dump some image bytes - _d("image start"); - hexdump(ctx->radio_data + start, length); - - size_t chunk_size = 0xdfc; - - while (start < end) { - size_t remaining = end - start; - size_t curr_chunk = chunk_size < remaining ? chunk_size : remaining; - ret = write(ctx->boot_fd, ctx->radio_data + start, curr_chunk); - if (ret < 0) { - _e("failed to write image chunk"); - goto fail; - } - start += ret; - } - _d("sent image type=%d", type); - - if (type == EBL) { - if ((ret = write(ctx->boot_fd, &crc, 1)) < 1) { - _e("failed to write EBL CRC"); - goto fail; - } - else { - _d("wrote EBL CRC %02x", crc); - } - goto done; - } - - uint32_t crc32 = (crc << 24) | 0xffffff; - if ((ret = write(ctx->boot_fd, &crc32, 4)) != 4) { - _e("failed to write CRC"); - goto fail; - } - else { - _d("wrote CRC %x", crc); - } + int ret = -1; + + if (type >= ARRAY_SIZE(i9250_radio_parts)) { + _e("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 start = offset; + size_t end = length + start; + + unsigned char crc = calculateCRC(ctx->radio_data, offset, length); + + //dump some image bytes + _d("image start"); + hexdump(ctx->radio_data + start, length); + + size_t chunk_size = 0xdfc; + + while (start < end) { + size_t remaining = end - start; + size_t curr_chunk = chunk_size < remaining ? chunk_size : remaining; + ret = write(ctx->boot_fd, ctx->radio_data + start, curr_chunk); + if (ret < 0) { + _e("failed to write image chunk"); + goto fail; + } + start += ret; + } + _d("sent image type=%d", type); + + if (type == EBL) { + if ((ret = write(ctx->boot_fd, &crc, 1)) < 1) { + _e("failed to write EBL CRC"); + goto fail; + } + else { + _d("wrote EBL CRC %02x", crc); + } + goto done; + } + + uint32_t crc32 = (crc << 24) | 0xffffff; + if ((ret = write(ctx->boot_fd, &crc32, 4)) != 4) { + _e("failed to write CRC"); + goto fail; + } + else { + _d("wrote CRC %x", crc); + } done: - ret = 0; + ret = 0; fail: - return ret; + return ret; } static int send_PSI_i9250(fwloader_context *ctx) { - int ret = -1; - - if ((ret = write(ctx->boot_fd, I9250_PSI_START_MAGIC, 4)) < 0) { - _d("%s: failed to write header, ret %d", __func__, ret); - goto fail; - } - - if ((ret = send_image_i9250(ctx, PSI)) < 0) { - _e("failed to send PSI image"); - goto fail; - } - - char expected_acks[4][4] = { - "\xff\xff\xff\x01", - "\xff\xff\xff\x01", - "\x02\x00\x00\x00", - "\x01\xdd\x00\x00", - }; - - unsigned i; - for (i = 0; i < ARRAY_SIZE(expected_acks); i++) { - ret = expect_data(ctx->boot_fd, expected_acks[i], 4); - if (ret < 0) { - _d("failed to wait for ack %d", i); - goto fail; - } - } - _d("received PSI ACK"); - - return 0; + int ret = -1; + + if ((ret = write(ctx->boot_fd, I9250_PSI_START_MAGIC, 4)) < 0) { + _d("%s: failed to write header, ret %d", __func__, ret); + goto fail; + } + + if ((ret = send_image_i9250(ctx, PSI)) < 0) { + _e("failed to send PSI image"); + goto fail; + } + + char expected_acks[4][4] = { + "\xff\xff\xff\x01", + "\xff\xff\xff\x01", + "\x02\x00\x00\x00", + "\x01\xdd\x00\x00", + }; + + unsigned i; + for (i = 0; i < ARRAY_SIZE(expected_acks); i++) { + ret = expect_data(ctx->boot_fd, expected_acks[i], 4); + if (ret < 0) { + _d("failed to wait for ack %d", i); + goto fail; + } + } + _d("received PSI ACK"); + + return 0; fail: - return ret; + return ret; } static int send_EBL_i9250(fwloader_context *ctx) { - int ret; - int fd = ctx->boot_fd; - unsigned length = i9250_radio_parts[EBL].length; - - if ((ret = write(fd, "\x04\x00\x00\x00", 4)) != 4) { - _e("failed to write length of EBL length ('4') "); - goto fail; - } - - if ((ret = write(fd, &length, sizeof(length))) != sizeof(length)) { - _e("failed to write EBL length"); - goto fail; - } - - if ((ret = expect_data(fd, I9250_GENERAL_ACK, 4)) < 0) { - _e("failed to wait for EBL length ACK"); - goto fail; - } - - if ((ret = expect_data(fd, I9250_EBL_HDR_ACK_MAGIC, 4)) < 0) { - _e("failed to wait for EBL header ACK"); - goto fail; - } - - length++; - if ((ret = write(fd, &length, sizeof(length))) != sizeof(length)) { - _e("failed to write EBL length + 1"); - goto fail; - } - - if ((ret = send_image_i9250(ctx, EBL)) < 0) { - _e("failed to send EBL image"); - goto fail; - } - else { - _d("sent EBL image, waiting for ACK"); - } - - if ((ret = expect_data(fd, I9250_GENERAL_ACK, 4)) < 0) { - _e("failed to wait for EBL image general ACK"); - goto fail; - } - - if ((ret = expect_data(fd, I9250_EBL_IMG_ACK_MAGIC, 4)) < 0) { - _e("failed to wait for EBL image ACK"); - goto fail; - } - else { - _d("got EBL ACK"); - } - - return 0; + int ret; + int fd = ctx->boot_fd; + unsigned length = i9250_radio_parts[EBL].length; + + if ((ret = write(fd, "\x04\x00\x00\x00", 4)) != 4) { + _e("failed to write length of EBL length ('4') "); + goto fail; + } + + if ((ret = write(fd, &length, sizeof(length))) != sizeof(length)) { + _e("failed to write EBL length"); + goto fail; + } + + if ((ret = expect_data(fd, I9250_GENERAL_ACK, 4)) < 0) { + _e("failed to wait for EBL length ACK"); + goto fail; + } + + if ((ret = expect_data(fd, I9250_EBL_HDR_ACK_MAGIC, 4)) < 0) { + _e("failed to wait for EBL header ACK"); + goto fail; + } + + length++; + if ((ret = write(fd, &length, sizeof(length))) != sizeof(length)) { + _e("failed to write EBL length + 1"); + goto fail; + } + + if ((ret = send_image_i9250(ctx, EBL)) < 0) { + _e("failed to send EBL image"); + goto fail; + } + else { + _d("sent EBL image, waiting for ACK"); + } + + if ((ret = expect_data(fd, I9250_GENERAL_ACK, 4)) < 0) { + _e("failed to wait for EBL image general ACK"); + goto fail; + } + + if ((ret = expect_data(fd, I9250_EBL_IMG_ACK_MAGIC, 4)) < 0) { + _e("failed to wait for EBL image ACK"); + goto fail; + } + else { + _d("got EBL ACK"); + } + + return 0; fail: - return ret; + return ret; } static int bootloader_cmd(fwloader_context *ctx, - enum xmm6260_boot_cmd cmd, void *data, size_t data_size) + 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)) { - _e("bad command %x\n", cmd); - goto done_or_fail; - } - - unsigned cmd_code = i9250_boot_cmd_desc[cmd].code; - - uint16_t checksum = (data_size & 0xffff) + cmd_code; - unsigned char *ptr = (unsigned char*)data; - size_t i; - for (i = 0; i < data_size; i++) { - checksum += ptr[i]; - } - - DECLARE_BOOT_CMD_HEADER(header, cmd_code, data_size); - DECLARE_BOOT_TAIL_HEADER(tail, checksum); - - size_t tail_size = sizeof(tail); - if (!i9250_boot_cmd_desc[cmd].long_tail) { - tail_size -= 2; - } - - size_t cmd_buffer_size = data_size + sizeof(header) + tail_size; - _d("data_size %d [%d] checksum 0x%x", data_size, cmd_buffer_size, checksum); - - cmd_data = (char*)malloc(cmd_buffer_size); - if (!cmd_data) { - _e("failed to allocate command buffer"); - ret = -ENOMEM; - goto done_or_fail; - } - memset(cmd_data, 0, cmd_buffer_size); - memcpy(cmd_data, &header, sizeof(header)); - memcpy(cmd_data + sizeof(header), data, data_size); - memcpy(cmd_data + sizeof(header) + data_size, &tail, tail_size); - - _d("bootloader cmd packet"); - hexdump(cmd_data, cmd_buffer_size); - hexdump(cmd_data + cmd_buffer_size - 16, 16); - - if ((ret = write(ctx->boot_fd, cmd_data, cmd_buffer_size)) < 0) { - _e("failed to write command to socket"); - goto done_or_fail; - } - - if ((unsigned)ret < cmd_buffer_size) { - _e("written %d bytes of %d", ret, cmd_buffer_size); - ret = -EINVAL; - goto done_or_fail; - } - - _d("sent command %x", header.cmd); - if (i9250_boot_cmd_desc[cmd].no_ack) { - _i("not waiting for ACK"); - goto done_or_fail; - } - - uint32_t ack_length; - if ((ret = receive(ctx->boot_fd, &ack_length, 4)) < 0) { - _e("failed to receive ack header length"); - goto done_or_fail; - } - - if (ack_length + 4 > cmd_buffer_size) { - free(cmd_data); - cmd_data = NULL; - cmd_data = malloc(ack_length + 4); - if (!cmd_data) { - _e("failed to allocate the buffer for ack data"); - goto done_or_fail; - } - } - memset(cmd_data, 0, ack_length); - memcpy(cmd_data, &ack_length, 4); - 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"); - goto done_or_fail; - } - } - - _d("received ack"); - hexdump(cmd_data, ack_length + 4); - - bootloader_cmd_hdr_t *ack_hdr = (bootloader_cmd_hdr_t*)cmd_data; - bootloader_cmd_tail_t *ack_tail = (bootloader_cmd_tail_t*) - (cmd_data + ack_length + 4 - sizeof(bootloader_cmd_tail_t)); - - _d("ack code 0x%x checksum 0x%x", ack_hdr->cmd, ack_tail->checksum); - if (ack_hdr->cmd != header.cmd) { - _e("request and ack command codes do not match"); - ret = -1; - goto done_or_fail; - } - - ret = 0; + int ret = 0; + char *cmd_data = 0; + if (cmd >= ARRAY_SIZE(i9250_boot_cmd_desc)) { + _e("bad command %x\n", cmd); + goto done_or_fail; + } + + unsigned cmd_code = i9250_boot_cmd_desc[cmd].code; + + uint16_t checksum = (data_size & 0xffff) + cmd_code; + unsigned char *ptr = (unsigned char*)data; + size_t i; + for (i = 0; i < data_size; i++) { + checksum += ptr[i]; + } + + DECLARE_BOOT_CMD_HEADER(header, cmd_code, data_size); + DECLARE_BOOT_TAIL_HEADER(tail, checksum); + + size_t tail_size = sizeof(tail); + if (!i9250_boot_cmd_desc[cmd].long_tail) { + tail_size -= 2; + } + + size_t cmd_buffer_size = data_size + sizeof(header) + tail_size; + _d("data_size %d [%d] checksum 0x%x", data_size, cmd_buffer_size, checksum); + + cmd_data = (char*)malloc(cmd_buffer_size); + if (!cmd_data) { + _e("failed to allocate command buffer"); + ret = -ENOMEM; + goto done_or_fail; + } + memset(cmd_data, 0, cmd_buffer_size); + memcpy(cmd_data, &header, sizeof(header)); + memcpy(cmd_data + sizeof(header), data, data_size); + memcpy(cmd_data + sizeof(header) + data_size, &tail, tail_size); + + _d("bootloader cmd packet"); + hexdump(cmd_data, cmd_buffer_size); + hexdump(cmd_data + cmd_buffer_size - 16, 16); + + if ((ret = write(ctx->boot_fd, cmd_data, cmd_buffer_size)) < 0) { + _e("failed to write command to socket"); + goto done_or_fail; + } + + if ((unsigned)ret < cmd_buffer_size) { + _e("written %d bytes of %d", ret, cmd_buffer_size); + ret = -EINVAL; + goto done_or_fail; + } + + _d("sent command %x", header.cmd); + if (i9250_boot_cmd_desc[cmd].no_ack) { + _i("not waiting for ACK"); + goto done_or_fail; + } + + uint32_t ack_length; + if ((ret = receive(ctx->boot_fd, &ack_length, 4)) < 0) { + _e("failed to receive ack header length"); + goto done_or_fail; + } + + if (ack_length + 4 > cmd_buffer_size) { + free(cmd_data); + cmd_data = NULL; + cmd_data = malloc(ack_length + 4); + if (!cmd_data) { + _e("failed to allocate the buffer for ack data"); + goto done_or_fail; + } + } + memset(cmd_data, 0, ack_length); + memcpy(cmd_data, &ack_length, 4); + 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"); + goto done_or_fail; + } + } + + _d("received ack"); + hexdump(cmd_data, ack_length + 4); + + bootloader_cmd_hdr_t *ack_hdr = (bootloader_cmd_hdr_t*)cmd_data; + bootloader_cmd_tail_t *ack_tail = (bootloader_cmd_tail_t*) + (cmd_data + ack_length + 4 - sizeof(bootloader_cmd_tail_t)); + + _d("ack code 0x%x checksum 0x%x", ack_hdr->cmd, ack_tail->checksum); + if (ack_hdr->cmd != header.cmd) { + _e("request and ack command codes do not match"); + ret = -1; + goto done_or_fail; + } + + ret = 0; done_or_fail: - if (cmd_data) { - free(cmd_data); - } + if (cmd_data) { + free(cmd_data); + } - return ret; + return ret; } static int ack_BootInfo_i9250(fwloader_context *ctx) { - int ret = -1; - uint32_t boot_info_length; - char *boot_info = 0; - - - if ((ret = receive(ctx->boot_fd, &boot_info_length, 4)) < 0) { - _e("failed to receive boot info length"); - goto fail; - } - - _d("Boot Info length=0x%x", boot_info_length); - - boot_info = (char*)malloc(boot_info_length); - if (!boot_info) { - _e("failed to allocate memory for boot info"); - goto fail; - } - - memset(boot_info, 0, boot_info_length); - - size_t boot_chunk = 4; - size_t boot_chunk_count = (boot_info_length + boot_chunk - 1) / boot_chunk; - unsigned i; - for (i = 0; i < boot_chunk_count; i++) { - ret = receive(ctx->boot_fd, boot_info + (i * boot_chunk), boot_chunk); - if (ret < 0) { - _e("failed to receive Boot Info chunk %i ret=%d", i, ret); - goto fail; - } - } - - _d("received Boot Info"); - hexdump(boot_info, boot_info_length); - - ret = bootloader_cmd(ctx, SetPortConf, boot_info, boot_info_length); - if (ret < 0) { - _e("failed to send SetPortConf command"); - goto fail; - } - else { - _d("sent SetPortConf command"); - } - - ret = 0; + int ret = -1; + uint32_t boot_info_length; + char *boot_info = 0; + + + if ((ret = receive(ctx->boot_fd, &boot_info_length, 4)) < 0) { + _e("failed to receive boot info length"); + goto fail; + } + + _d("Boot Info length=0x%x", boot_info_length); + + boot_info = (char*)malloc(boot_info_length); + if (!boot_info) { + _e("failed to allocate memory for boot info"); + goto fail; + } + + memset(boot_info, 0, boot_info_length); + + size_t boot_chunk = 4; + size_t boot_chunk_count = (boot_info_length + boot_chunk - 1) / boot_chunk; + unsigned i; + for (i = 0; i < boot_chunk_count; i++) { + ret = receive(ctx->boot_fd, boot_info + (i * boot_chunk), boot_chunk); + if (ret < 0) { + _e("failed to receive Boot Info chunk %i ret=%d", i, ret); + goto fail; + } + } + + _d("received Boot Info"); + hexdump(boot_info, boot_info_length); + + ret = bootloader_cmd(ctx, SetPortConf, boot_info, boot_info_length); + if (ret < 0) { + _e("failed to send SetPortConf command"); + goto fail; + } + else { + _d("sent SetPortConf command"); + } + + ret = 0; fail: - if (boot_info) { - free(boot_info); - } + if (boot_info) { + free(boot_info); + } - return ret; + return ret; } static int send_secure_data(fwloader_context *ctx, uint32_t addr, - void *data, int data_len) + void *data, int data_len) { - int ret = 0; - int count = 0; - char *data_p = (char *) data; - - if ((ret = bootloader_cmd(ctx, ReqFlashSetAddress, &addr, 4)) < 0) { - _e("failed to send ReqFlashSetAddress"); - goto fail; - } - else { - _d("sent ReqFlashSetAddress"); - } - - while (count < data_len) { - int rest = data_len - count; - int chunk = rest < SEC_DOWNLOAD_CHUNK ? rest : SEC_DOWNLOAD_CHUNK; - - ret = bootloader_cmd(ctx, ReqFlashWriteBlock, data_p, chunk); - if (ret < 0) { - _e("failed to send data chunk"); - goto fail; - } - - data_p += chunk; - count += chunk; - } - - usleep(SEC_DOWNLOAD_DELAY_US); + int ret = 0; + int count = 0; + char *data_p = (char *) data; + + if ((ret = bootloader_cmd(ctx, ReqFlashSetAddress, &addr, 4)) < 0) { + _e("failed to send ReqFlashSetAddress"); + goto fail; + } + else { + _d("sent ReqFlashSetAddress"); + } + + while (count < data_len) { + int rest = data_len - count; + int chunk = rest < SEC_DOWNLOAD_CHUNK ? rest : SEC_DOWNLOAD_CHUNK; + + ret = bootloader_cmd(ctx, ReqFlashWriteBlock, data_p, chunk); + if (ret < 0) { + _e("failed to send data chunk"); + goto fail; + } + + data_p += chunk; + count += chunk; + } + + usleep(SEC_DOWNLOAD_DELAY_US); fail: - return ret; + return ret; } static int send_secure_image(fwloader_context *ctx, uint32_t addr, - enum xmm6260_image type) + enum xmm6260_image type) { - uint32_t offset = i9250_radio_parts[type].offset; - uint32_t length = i9250_radio_parts[type].length; - char *start = ctx->radio_data + offset; - int ret = 0; + uint32_t offset = i9250_radio_parts[type].offset; + uint32_t length = i9250_radio_parts[type].length; + char *start = ctx->radio_data + offset; + int ret = 0; - ret = send_secure_data(ctx, addr, start, length); + ret = send_secure_data(ctx, addr, start, length); - return ret; + return ret; } static int send_mps_data(fwloader_context *ctx) { - int ret = 0; - int mps_fd = -1; - char mps_data[I9250_MPS_LENGTH] = {}; - uint32_t addr = I9250_MPS_LOAD_ADDR; - - mps_fd = open(I9250_MPS_IMAGE_PATH, O_RDONLY); - if (mps_fd < 0) { - _e("failed to open MPS data"); - } - else { - read(mps_fd, mps_data, I9250_MPS_LENGTH); - } - - if ((ret = bootloader_cmd(ctx, ReqFlashSetAddress, &addr, 4)) < 0) { - _e("failed to send ReqFlashSetAddress"); - goto fail; - } - else { - _d("sent ReqFlashSetAddress"); - } - - if ((ret = bootloader_cmd(ctx, ReqFlashWriteBlock, - mps_data, I9250_MPS_LENGTH)) < 0) { - _e("failed to write MPS data to modem"); - goto fail; - } + int ret = 0; + int mps_fd = -1; + char mps_data[I9250_MPS_LENGTH] = {}; + uint32_t addr = I9250_MPS_LOAD_ADDR; + + mps_fd = open(I9250_MPS_IMAGE_PATH, O_RDONLY); + if (mps_fd < 0) { + _e("failed to open MPS data"); + } + else { + read(mps_fd, mps_data, I9250_MPS_LENGTH); + } + + if ((ret = bootloader_cmd(ctx, ReqFlashSetAddress, &addr, 4)) < 0) { + _e("failed to send ReqFlashSetAddress"); + goto fail; + } + else { + _d("sent ReqFlashSetAddress"); + } + + if ((ret = bootloader_cmd(ctx, ReqFlashWriteBlock, + mps_data, I9250_MPS_LENGTH)) < 0) { + _e("failed to write MPS data to modem"); + goto fail; + } fail: - if (mps_fd >= 0) { - close(mps_fd); - } + if (mps_fd >= 0) { + close(mps_fd); + } - return ret; + return ret; } static int send_SecureImage_i9250(fwloader_context *ctx) { - int ret = 0; - - uint32_t sec_off = i9250_radio_parts[SECURE_IMAGE].offset; - uint32_t sec_len = i9250_radio_parts[SECURE_IMAGE].length; - void *sec_img = ctx->radio_data + sec_off; - void *nv_data = NULL; - - if ((ret = bootloader_cmd(ctx, ReqSecStart, sec_img, sec_len)) < 0) { - _e("failed to write ReqSecStart"); - goto fail; - } - else { - _d("sent ReqSecStart"); - } - - if ((ret = send_secure_image(ctx, FW_LOAD_ADDR, FIRMWARE)) < 0) { - _e("failed to send FIRMWARE image"); - goto fail; - } - else { - _d("sent FIRMWARE image"); - } - - nv_data_check(ctx->client); - nv_data_md5_check(ctx->client); - - nv_data = ipc_file_read(ctx->client, nv_data_path(ctx->client), 2 << 20, 1024); - if (nv_data == NULL) { - _e("failed to read NVDATA image"); - goto fail; - } - - if ((ret = send_secure_data(ctx, NVDATA_LOAD_ADDR, nv_data, 2 << 20)) < 0) { - _e("failed to send NVDATA image"); - goto fail; - } - else { - _d("sent NVDATA image"); - } - - free(nv_data); - - if ((ret = send_mps_data(ctx)) < 0) { - _e("failed to send MPS data"); - goto fail; - } - else { - _d("sent MPS data"); - } - - if ((ret = bootloader_cmd(ctx, ReqSecEnd, - BL_END_MAGIC, BL_END_MAGIC_LEN)) < 0) - { - _e("failed to write ReqSecEnd"); - goto fail; - } - else { - _d("sent ReqSecEnd"); - } - - ret = bootloader_cmd(ctx, ReqForceHwReset, - BL_RESET_MAGIC, BL_RESET_MAGIC_LEN); - if (ret < 0) { - _e("failed to write ReqForceHwReset"); - goto fail; - } - else { - _d("sent ReqForceHwReset"); - } + int ret = 0; + + uint32_t sec_off = i9250_radio_parts[SECURE_IMAGE].offset; + uint32_t sec_len = i9250_radio_parts[SECURE_IMAGE].length; + void *sec_img = ctx->radio_data + sec_off; + void *nv_data = NULL; + + if ((ret = bootloader_cmd(ctx, ReqSecStart, sec_img, sec_len)) < 0) { + _e("failed to write ReqSecStart"); + goto fail; + } + else { + _d("sent ReqSecStart"); + } + + if ((ret = send_secure_image(ctx, FW_LOAD_ADDR, FIRMWARE)) < 0) { + _e("failed to send FIRMWARE image"); + goto fail; + } + else { + _d("sent FIRMWARE image"); + } + + nv_data_check(ctx->client); + nv_data_md5_check(ctx->client); + + nv_data = ipc_file_read(ctx->client, nv_data_path(ctx->client), 2 << 20, 1024); + if (nv_data == NULL) { + _e("failed to read NVDATA image"); + goto fail; + } + + if ((ret = send_secure_data(ctx, NVDATA_LOAD_ADDR, nv_data, 2 << 20)) < 0) { + _e("failed to send NVDATA image"); + goto fail; + } + else { + _d("sent NVDATA image"); + } + + free(nv_data); + + if ((ret = send_mps_data(ctx)) < 0) { + _e("failed to send MPS data"); + goto fail; + } + else { + _d("sent MPS data"); + } + + if ((ret = bootloader_cmd(ctx, ReqSecEnd, + BL_END_MAGIC, BL_END_MAGIC_LEN)) < 0) + { + _e("failed to write ReqSecEnd"); + goto fail; + } + else { + _d("sent ReqSecEnd"); + } + + ret = bootloader_cmd(ctx, ReqForceHwReset, + BL_RESET_MAGIC, BL_RESET_MAGIC_LEN); + if (ret < 0) { + _e("failed to write ReqForceHwReset"); + goto fail; + } + else { + _d("sent ReqForceHwReset"); + } fail: - return ret; + return ret; } int boot_modem_i9250(struct ipc_client *client) { - int ret = -1; - fwloader_context ctx; - memset(&ctx, 0, sizeof(ctx)); - - ctx.client = client; - - ctx.radio_fd = open(I9250_RADIO_IMAGE, O_RDONLY); - if (ctx.radio_fd < 0) { - _e("failed to open radio firmware"); - goto fail; - } - else { - _d("opened radio image %s, fd=%d", I9250_RADIO_IMAGE, ctx.radio_fd); - } - - if (fstat(ctx.radio_fd, &ctx.radio_stat) < 0) { - _e("failed to stat radio image, error %s", strerror(errno)); - goto fail; - } - - ctx.radio_data = mmap(0, RADIO_MAP_SIZE, PROT_READ, MAP_SHARED, - ctx.radio_fd, 0); - if (ctx.radio_data == MAP_FAILED) { - _e("failed to mmap radio image, error %s", strerror(errno)); - goto fail; - } - - 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; - } - else { - _d("opened boot device %s, fd=%d", BOOT_DEV, ctx.boot_fd); - } - - if (reboot_modem_i9250(&ctx, true) < 0) { - _e("failed to hard reset modem"); - goto fail; - } - else { - _d("modem hard reset done"); - } - - /* - * Now, actually load the firmware - */ - int i; - for (i = 0; i < 2; i++) { - if (write(ctx.boot_fd, "ATAT", 4) != 4) { - _e("failed to write ATAT to boot socket"); - goto fail; - } - else { - _d("written ATAT to boot socket, waiting for ACK"); - } - - if (read_select(ctx.boot_fd, 100) < 0) { - _d("failed to select before next ACK, ignoring"); - } - } - - //FIXME: make sure it does not timeout or add the retry in the ril library - - if ((ret = read_select(ctx.boot_fd, 100)) < 0) { - _e("failed to wait for bootloader ready state"); - goto fail; - } - else { - _d("ready for PSI upload"); - } - - ret = -ETIMEDOUT; - for (i = 0; i < I9250_BOOT_REPLY_MAX; i++) { - uint32_t id_buf; - if ((ret = receive(ctx.boot_fd, (void*)&id_buf, 4)) != 4) { - _e("failed receiving bootloader reply"); - goto fail; - } - _d("got bootloader reply %08x", id_buf); - if (id_buf == I9250_BOOT_LAST_MARKER) { - ret = 0; - break; - } - } - - if (ret < 0) { - _e("bootloader id marker not received"); - goto fail; - } - else { - _d("got bootloader id marker"); - } - - if ((ret = send_PSI_i9250(&ctx)) < 0) { - _e("failed to upload PSI"); - goto fail; - } - else { - _d("PSI download complete"); - } - - close(ctx.boot_fd); - 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; - } - else { - _d("opened second boot device %s, fd=%d", I9250_SECOND_BOOT_DEV, ctx.boot_fd); - } - - //RpsiCmdLoadAndExecute - if ((ret = write(ctx.boot_fd, I9250_PSI_CMD_EXEC, 4)) < 0) { - _e("failed writing cmd_load_exe_EBL"); - goto fail; - } - if ((ret = write(ctx.boot_fd, I9250_PSI_EXEC_DATA, 8)) < 0) { - _e("failed writing 8 bytes to boot1"); - goto fail; - } - - if ((ret = expect_data(ctx.boot_fd, I9250_GENERAL_ACK, 4)) < 0) { - _e("failed to receive cmd_load_exe_EBL ack"); - goto fail; - } - - if ((ret = expect_data(ctx.boot_fd, I9250_PSI_READY_ACK, 4)) < 0) { - _e("failed to receive PSI ready ack"); - goto fail; - } - - if ((ret = send_EBL_i9250(&ctx)) < 0) { - _e("failed to upload EBL"); - goto fail; - } - else { - _d("EBL download complete"); - } - - if ((ret = ack_BootInfo_i9250(&ctx)) < 0) { - _e("failed to receive Boot Info"); - goto fail; - } - else { - _d("Boot Info ACK done"); - } - - if ((ret = send_SecureImage_i9250(&ctx)) < 0) { - _e("failed to upload Secure Image"); - goto fail; - } - else { - _d("Secure Image download complete"); - } - - if ((ret = modemctl_wait_modem_online(&ctx))) { - _e("failed to wait for modem to become online"); - goto fail; - } - - _i("modem online"); - ret = 0; + int ret = -1; + fwloader_context ctx; + memset(&ctx, 0, sizeof(ctx)); + + ctx.client = client; + + ctx.radio_fd = open(I9250_RADIO_IMAGE, O_RDONLY); + if (ctx.radio_fd < 0) { + _e("failed to open radio firmware"); + goto fail; + } + else { + _d("opened radio image %s, fd=%d", I9250_RADIO_IMAGE, ctx.radio_fd); + } + + if (fstat(ctx.radio_fd, &ctx.radio_stat) < 0) { + _e("failed to stat radio image, error %s", strerror(errno)); + goto fail; + } + + ctx.radio_data = mmap(0, RADIO_MAP_SIZE, PROT_READ, MAP_SHARED, + ctx.radio_fd, 0); + if (ctx.radio_data == MAP_FAILED) { + _e("failed to mmap radio image, error %s", strerror(errno)); + goto fail; + } + + 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; + } + else { + _d("opened boot device %s, fd=%d", BOOT_DEV, ctx.boot_fd); + } + + if (reboot_modem_i9250(&ctx, true) < 0) { + _e("failed to hard reset modem"); + goto fail; + } + else { + _d("modem hard reset done"); + } + + /* + * Now, actually load the firmware + */ + int i; + for (i = 0; i < 2; i++) { + if (write(ctx.boot_fd, "ATAT", 4) != 4) { + _e("failed to write ATAT to boot socket"); + goto fail; + } + else { + _d("written ATAT to boot socket, waiting for ACK"); + } + + if (read_select(ctx.boot_fd, 100) < 0) { + _d("failed to select before next ACK, ignoring"); + } + } + + //FIXME: make sure it does not timeout or add the retry in the ril library + + if ((ret = read_select(ctx.boot_fd, 100)) < 0) { + _e("failed to wait for bootloader ready state"); + goto fail; + } + else { + _d("ready for PSI upload"); + } + + ret = -ETIMEDOUT; + for (i = 0; i < I9250_BOOT_REPLY_MAX; i++) { + uint32_t id_buf; + if ((ret = receive(ctx.boot_fd, (void*)&id_buf, 4)) != 4) { + _e("failed receiving bootloader reply"); + goto fail; + } + _d("got bootloader reply %08x", id_buf); + if (id_buf == I9250_BOOT_LAST_MARKER) { + ret = 0; + break; + } + } + + if (ret < 0) { + _e("bootloader id marker not received"); + goto fail; + } + else { + _d("got bootloader id marker"); + } + + if ((ret = send_PSI_i9250(&ctx)) < 0) { + _e("failed to upload PSI"); + goto fail; + } + else { + _d("PSI download complete"); + } + + close(ctx.boot_fd); + 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; + } + else { + _d("opened second boot device %s, fd=%d", I9250_SECOND_BOOT_DEV, ctx.boot_fd); + } + + //RpsiCmdLoadAndExecute + if ((ret = write(ctx.boot_fd, I9250_PSI_CMD_EXEC, 4)) < 0) { + _e("failed writing cmd_load_exe_EBL"); + goto fail; + } + if ((ret = write(ctx.boot_fd, I9250_PSI_EXEC_DATA, 8)) < 0) { + _e("failed writing 8 bytes to boot1"); + goto fail; + } + + if ((ret = expect_data(ctx.boot_fd, I9250_GENERAL_ACK, 4)) < 0) { + _e("failed to receive cmd_load_exe_EBL ack"); + goto fail; + } + + if ((ret = expect_data(ctx.boot_fd, I9250_PSI_READY_ACK, 4)) < 0) { + _e("failed to receive PSI ready ack"); + goto fail; + } + + if ((ret = send_EBL_i9250(&ctx)) < 0) { + _e("failed to upload EBL"); + goto fail; + } + else { + _d("EBL download complete"); + } + + if ((ret = ack_BootInfo_i9250(&ctx)) < 0) { + _e("failed to receive Boot Info"); + goto fail; + } + else { + _d("Boot Info ACK done"); + } + + if ((ret = send_SecureImage_i9250(&ctx)) < 0) { + _e("failed to upload Secure Image"); + goto fail; + } + else { + _d("Secure Image download complete"); + } + + if ((ret = modemctl_wait_modem_online(&ctx))) { + _e("failed to wait for modem to become online"); + goto fail; + } + + _i("modem online"); + ret = 0; fail: - if (ctx.radio_data != MAP_FAILED) { - munmap(ctx.radio_data, RADIO_MAP_SIZE); - } + if (ctx.radio_data != MAP_FAILED) { + munmap(ctx.radio_data, RADIO_MAP_SIZE); + } - if (ctx.radio_fd >= 0) { - close(ctx.radio_fd); - } + if (ctx.radio_fd >= 0) { + close(ctx.radio_fd); + } - if (ctx.boot_fd >= 0) { - close(ctx.boot_fd); - } + if (ctx.boot_fd >= 0) { + close(ctx.boot_fd); + } - return ret; + return ret; } + +// vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/xmm6260/fwloader_i9250.h b/samsung-ipc/device/xmm6260/fwloader_i9250.h index 0abe4fa..d398e31 100644 --- a/samsung-ipc/device/xmm6260/fwloader_i9250.h +++ b/samsung-ipc/device/xmm6260/fwloader_i9250.h @@ -55,3 +55,5 @@ #define BL_RESET_MAGIC_LEN 4 #endif + +// vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/xmm6260/io_helpers.c b/samsung-ipc/device/xmm6260/io_helpers.c index d1fffe2..96285ad 100644 --- a/samsung-ipc/device/xmm6260/io_helpers.c +++ b/samsung-ipc/device/xmm6260/io_helpers.c @@ -28,77 +28,78 @@ #define DEFAULT_TIMEOUT 50 int c_ioctl(int fd, unsigned long code, void* data) { - int ret; - - if (!data) { - ret = ioctl(fd, code); - } - else { - ret = ioctl(fd, code, data); - } - - if (ret < 0) { - _e("ioctl fd=%d code=%lx failed: %s", fd, code, strerror(errno)); - } - else { - _d("ioctl fd=%d code=%lx OK", fd, code); - } - - return ret; + int ret; + + if (!data) { + ret = ioctl(fd, code); + } + else { + ret = ioctl(fd, code, data); + } + + if (ret < 0) { + _e("ioctl fd=%d code=%lx failed: %s", fd, code, strerror(errno)); + } + else { + _d("ioctl fd=%d code=%lx OK", fd, code); + } + + return ret; } int read_select(int fd, unsigned timeout) { - int ret = 0; - - struct timeval tv = { - tv.tv_sec = timeout / 1000, - tv.tv_usec = 1000 * (timeout % 1000), - }; + 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); + fd_set read_set; + FD_ZERO(&read_set); + FD_SET(fd, &read_set); - ret = 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 < 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; - } + if (ret < 1 || !FD_ISSET(fd, &read_set)) { + _d("fd %d not in fd set", fd); + goto fail; + } fail: - return ret; + return ret; } int receive(int fd, void *buf, size_t size) { - int ret; - if ((ret = read_select(fd, DEFAULT_TIMEOUT)) < 1) { - _e("failed to select the fd %d", fd); - return ret; - } - else { - _d("selected %d fds for fd=%d", ret, fd); - } - - return read(fd, buf, size); + int ret; + if ((ret = read_select(fd, DEFAULT_TIMEOUT)) < 1) { + _e("failed to select the fd %d", fd); + return ret; + } + else { + _d("selected %d fds for fd=%d", ret, fd); + } + + return read(fd, buf, size); } int expect_data(int fd, void *data, size_t size) { - int ret; - char buf[size]; - if ((ret = receive(fd, buf, size)) != size) { - ret = -1; - _e("failed to receive data"); - return ret; - } - ret = memcmp(buf, data, size); - hexdump(buf, size); - - return ret; + int ret; + char buf[size]; + if ((ret = receive(fd, buf, size)) != size) { + ret = -1; + _e("failed to receive data"); + return ret; + } + ret = memcmp(buf, data, size); + hexdump(buf, 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 index df3bf20..d55bc1c 100644 --- a/samsung-ipc/device/xmm6260/io_helpers.h +++ b/samsung-ipc/device/xmm6260/io_helpers.h @@ -68,3 +68,5 @@ int receive(int fd, void *buf, size_t size); 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/log.c b/samsung-ipc/device/xmm6260/log.c index c467d0e..e7f3feb 100644 --- a/samsung-ipc/device/xmm6260/log.c +++ b/samsung-ipc/device/xmm6260/log.c @@ -25,19 +25,21 @@ #include "log.h" void hexdump(void* data, size_t size) { - if (size < 1) { - return; - } - char *_data = (char*)data; - char __hd_buf[DUMP_SIZE * 3 + 1]; + if (size < 1) { + return; + } + char *_data = (char*)data; + char __hd_buf[DUMP_SIZE * 3 + 1]; - 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]); - } + 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]); + } - __hd_buf[sizeof(__hd_buf) - 1] = '\0'; - _d("%s", __hd_buf); + __hd_buf[sizeof(__hd_buf) - 1] = '\0'; + _d("%s", __hd_buf); } + +// vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/xmm6260/log.h b/samsung-ipc/device/xmm6260/log.h index bfcc65d..3f0a065 100644 --- a/samsung-ipc/device/xmm6260/log.h +++ b/samsung-ipc/device/xmm6260/log.h @@ -28,20 +28,20 @@ #include "common.h" #ifndef SILENT - #define LOG_TAG "xmm6260-sec" - #define _p(fmt, x...) \ - do {\ - printf("[" LOG_TAG "]: " fmt " at %s:%s:%d\n", \ - ##x, __FILE__, __func__, __LINE__); \ - } while (0) + #define LOG_TAG "xmm6260-sec" + #define _p(fmt, x...) \ + do {\ + printf("[" LOG_TAG "]: " fmt " at %s:%s:%d\n", \ + ##x, __FILE__, __func__, __LINE__); \ + } while (0) #else - #define _p(fmt, x...) do {} while (0) + #define _p(fmt, x...) do {} while (0) #endif #ifdef DEBUG - #define _d(fmt, x...) _p("D/" fmt, ##x) + #define _d(fmt, x...) _p("D/" fmt, ##x) #else - #define _d(fmt, x...) do {} while (0) + #define _d(fmt, x...) do {} while (0) #endif #define _e(fmt, x...) _p("E/" fmt, ##x) @@ -52,3 +52,5 @@ void hexdump(void* data, size_t size); #endif //__LOG_H__ + +// vim:ts=4:sw=4:expandtab diff --git a/samsung-ipc/device/xmm6260/modemctl_common.c b/samsung-ipc/device/xmm6260/modemctl_common.c index 755e2be..253030a 100644 --- a/samsung-ipc/device/xmm6260/modemctl_common.c +++ b/samsung-ipc/device/xmm6260/modemctl_common.c @@ -26,138 +26,139 @@ * modemctl generic functions */ int modemctl_link_set_active(fwloader_context *ctx, bool enabled) { - unsigned status = enabled; - int ret; - unsigned long ioctl_code; + unsigned status = enabled; + int ret; + unsigned long ioctl_code; - ioctl_code = IOCTL_LINK_CONTROL_ACTIVE; - ret = c_ioctl(ctx->link_fd, ioctl_code, &status); + ioctl_code = IOCTL_LINK_CONTROL_ACTIVE; + ret = c_ioctl(ctx->link_fd, ioctl_code, &status); - if (ret < 0) { - _d("failed to set link active to %d", enabled); - goto fail; - } + if (ret < 0) { + _d("failed to set link active to %d", enabled); + goto fail; + } - return 0; + return 0; fail: - return ret; + return ret; } int modemctl_link_set_enabled(fwloader_context *ctx, bool enabled) { - unsigned status = enabled; - int ret; - unsigned long ioctl_code; + unsigned status = enabled; + int ret; + unsigned long ioctl_code; - ioctl_code = IOCTL_LINK_CONTROL_ENABLE; - ret = c_ioctl(ctx->link_fd, ioctl_code, &status); + ioctl_code = IOCTL_LINK_CONTROL_ENABLE; + ret = c_ioctl(ctx->link_fd, ioctl_code, &status); - if (ret < 0) { - _d("failed to set link state to %d", enabled); - goto fail; - } + if (ret < 0) { + _d("failed to set link state to %d", enabled); + goto fail; + } - return 0; + return 0; fail: - return ret; + return ret; } int modemctl_wait_link_ready(fwloader_context *ctx) { - int ret; + int ret; - struct timeval tv_start = {}; - struct timeval tv_end = {}; + struct timeval tv_start = {}; + struct timeval tv_end = {}; - gettimeofday(&tv_start, 0);; + gettimeofday(&tv_start, 0);; - //link wakeup timeout in milliseconds - long diff = 0; + //link wakeup timeout in milliseconds + long diff = 0; - do { - ret = c_ioctl(ctx->link_fd, IOCTL_LINK_CONNECTED, 0); - if (ret < 0) { - goto fail; - } + do { + ret = c_ioctl(ctx->link_fd, IOCTL_LINK_CONNECTED, 0); + if (ret < 0) { + goto fail; + } - if (ret == 1) { - return 0; - } + if (ret == 1) { + return 0; + } - usleep(LINK_POLL_DELAY_US); - gettimeofday(&tv_end, 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); + 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; - + ret = -ETIMEDOUT; + fail: - return ret; + return ret; } int modemctl_wait_modem_online(fwloader_context *ctx) { - int ret; + int ret; - struct timeval tv_start = {}; - struct timeval tv_end = {}; + struct timeval tv_start = {}; + struct timeval tv_end = {}; - gettimeofday(&tv_start, 0);; + gettimeofday(&tv_start, 0);; - //link wakeup timeout in milliseconds - long diff = 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; - } + do { + ret = c_ioctl(ctx->boot_fd, IOCTL_MODEM_STATUS, 0); + if (ret < 0) { + goto fail; + } - if (ret == STATE_ONLINE) { - return 0; - } + if (ret == STATE_ONLINE) { + return 0; + } - usleep(LINK_POLL_DELAY_US); - gettimeofday(&tv_end, 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); + 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; - + ret = -ETIMEDOUT; + fail: - return ret; + return ret; } int modemctl_modem_power(fwloader_context *ctx, bool enabled) { - if (enabled) { - return c_ioctl(ctx->boot_fd, IOCTL_MODEM_ON, 0); - } - else { - return c_ioctl(ctx->boot_fd, IOCTL_MODEM_OFF, 0); - } - return -1; + if (enabled) { + return c_ioctl(ctx->boot_fd, IOCTL_MODEM_ON, 0); + } + else { + return c_ioctl(ctx->boot_fd, IOCTL_MODEM_OFF, 0); + } + return -1; } int modemctl_modem_boot_power(fwloader_context *ctx, bool enabled) { - if (enabled) { - return c_ioctl(ctx->boot_fd, IOCTL_MODEM_BOOT_ON, 0); - } - else { - return c_ioctl(ctx->boot_fd, IOCTL_MODEM_BOOT_OFF, 0); - } - return -1; + if (enabled) { + return c_ioctl(ctx->boot_fd, IOCTL_MODEM_BOOT_ON, 0); + } + else { + return c_ioctl(ctx->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; + 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_common.h b/samsung-ipc/device/xmm6260/modemctl_common.h index 4571677..466c728 100644 --- a/samsung-ipc/device/xmm6260/modemctl_common.h +++ b/samsung-ipc/device/xmm6260/modemctl_common.h @@ -44,25 +44,25 @@ #define RADIO_MAP_SIZE (16 << 20) typedef struct { - int link_fd; - int boot_fd; + int link_fd; + int boot_fd; - int radio_fd; - char *radio_data; - struct stat radio_stat; + int radio_fd; + char *radio_data; + struct stat radio_stat; - struct ipc_client *client; + struct ipc_client *client; } fwloader_context; /* * Components of the Samsung XMM6260 firmware */ enum xmm6260_image { - PSI, - EBL, - SECURE_IMAGE, - FIRMWARE, - NVDATA, + PSI, + EBL, + SECURE_IMAGE, + FIRMWARE, + NVDATA, }; /* @@ -70,14 +70,14 @@ enum xmm6260_image { */ enum xmm6260_boot_cmd { - SetPortConf, + SetPortConf, - ReqSecStart, - ReqSecEnd, - ReqForceHwReset, + ReqSecStart, + ReqSecEnd, + ReqForceHwReset, - ReqFlashSetAddress, - ReqFlashWriteBlock, + ReqFlashSetAddress, + ReqFlashWriteBlock, }; /* @@ -169,3 +169,5 @@ int boot_modem_i9250(struct ipc_client *client); unsigned char calculateCRC(void* data, size_t offset, size_t length); #endif //__MODEMCTL_COMMON_H__ + +// vim:ts=4:sw=4:expandtab |