diff options
-rw-r--r-- | rmi4update/firmware_image.cpp | 59 | ||||
-rw-r--r-- | rmi4update/firmware_image.h | 49 | ||||
-rw-r--r-- | rmi4update/main.cpp | 2 | ||||
-rw-r--r-- | rmi4update/rmi4update.cpp | 579 | ||||
-rw-r--r-- | rmi4update/rmi4update.h | 148 |
5 files changed, 831 insertions, 6 deletions
diff --git a/rmi4update/firmware_image.cpp b/rmi4update/firmware_image.cpp index 8acc2d6..ea97812 100644 --- a/rmi4update/firmware_image.cpp +++ b/rmi4update/firmware_image.cpp @@ -43,6 +43,62 @@ unsigned long FirmwareImage::Checksum(unsigned short * data, unsigned long len) return checksum; } +void FirmwareImage::ParseHierarchicalImg() +{ + struct container_descriptor *descriptor; + int numOfCntrs; + int ii; + unsigned int addr; + unsigned int offset; + unsigned int length; + unsigned char *content; + unsigned short container_id; + + m_cntrAddr = extract_long(&m_memBlock[RMI_IMG_V10_CNTR_ADDR_OFFSET]); + descriptor = (struct container_descriptor *)(m_memBlock + m_cntrAddr); + offset = extract_long(descriptor->content_address); + numOfCntrs = extract_long(descriptor->content_length) / 4; + + for (ii = 0; ii < numOfCntrs; ii++) { + addr = extract_long(m_memBlock + offset); + offset += 4; + descriptor = (struct container_descriptor *)(m_memBlock + addr); + container_id = descriptor->container_id[0] | + descriptor->container_id[1] << 8; + content = m_memBlock + extract_long(descriptor->content_address); + length = extract_long(descriptor->content_length); + switch (container_id) { + case BL_CONTAINER: + m_bootloaderVersion = *content; + break; + case UI_CONTAINER: + case CORE_CODE_CONTAINER: + m_firmwareData = content; + m_firmwareSize = length; + break; + case UI_CONFIG_CONTAINER: + case CORE_CONFIG_CONTAINER: + m_configData = content; + m_configSize = length; + break; + case PERMANENT_CONFIG_CONTAINER: + case GUEST_SERIALIZATION_CONTAINER: + m_lockdownData = content; + m_lockdownSize = length; + break; + case GENERAL_INFORMATION_CONTAINER: + m_io = true; + m_packageID = extract_long(content); + m_firmwareBuildID = extract_long(content + 4); + memcpy(m_productID, (content + 0x18), RMI_PRODUCT_ID_LENGTH); + m_productID[RMI_PRODUCT_ID_LENGTH] = 0; + break; + default: + break; + } + } +} + int FirmwareImage::Initialize(const char * filename) { if (!filename) @@ -114,6 +170,9 @@ int FirmwareImage::Initialize(const char * filename) m_lockdownSize = RMI_IMG_LOCKDOWN_V5_SIZE; m_lockdownData = &m_memBlock[RMI_IMG_LOCKDOWN_V5_OFFSET]; break; + case 16: + ParseHierarchicalImg(); + break; default: return UPDATE_FAIL_UNSUPPORTED_IMAGE_VERSION; } diff --git a/rmi4update/firmware_image.h b/rmi4update/firmware_image.h index 1c91324..bba6e0d 100644 --- a/rmi4update/firmware_image.h +++ b/rmi4update/firmware_image.h @@ -43,6 +43,53 @@ #define RMI_IMG_LOCKDOWN_V5_OFFSET 0xB0 #define RMI_IMG_LOCKDOWN_V5_SIZE 0x50 +// Leon add for BL_V7 +#define RMI_IMG_V10_CNTR_ADDR_OFFSET 0x0C + +struct container_descriptor { + unsigned char content_checksum[4]; + unsigned char container_id[2]; + unsigned char minor_version; + unsigned char major_version; + unsigned char reserved_08; + unsigned char reserved_09; + unsigned char reserved_0a; + unsigned char reserved_0b; + unsigned char container_option_flags[4]; + unsigned char content_options_length[4]; + unsigned char content_options_address[4]; + unsigned char content_length[4]; + unsigned char content_address[4]; +}; + +enum container_id { + TOP_LEVEL_CONTAINER = 0, + UI_CONTAINER, + UI_CONFIG_CONTAINER, + BL_CONTAINER, + BL_IMAGE_CONTAINER, + BL_CONFIG_CONTAINER, + BL_LOCKDOWN_INFO_CONTAINER, + PERMANENT_CONFIG_CONTAINER, + GUEST_CODE_CONTAINER, + BL_PROTOCOL_DESCRIPTOR_CONTAINER, + UI_PROTOCOL_DESCRIPTOR_CONTAINER, + RMI_SELF_DISCOVERY_CONTAINER, + RMI_PAGE_CONTENT_CONTAINER, + GENERAL_INFORMATION_CONTAINER, + DEVICE_CONFIG_CONTAINER, + FLASH_CONFIG_CONTAINER, + GUEST_SERIALIZATION_CONTAINER, + GLOBAL_PARAMETERS_CONTAINER, + CORE_CODE_CONTAINER, + CORE_CONFIG_CONTAINER, + DISPLAY_CONFIG_CONTAINER, + EXTERNAL_TOUCH_AFE_CONFIG_CONTAINER, + UTILITY_CONTAINER, + UTILITY_PARAMETER_CONTAINER, +}; +// BL_V7 end + class FirmwareImage { public: @@ -65,6 +112,7 @@ public: private: unsigned long Checksum(unsigned short * data, unsigned long len); void PrintHeaderInfo(); + void ParseHierarchicalImg(); // BL_V7 private: unsigned long m_checksum; @@ -83,6 +131,7 @@ private: unsigned char * m_configData; unsigned char * m_lockdownData; unsigned char * m_memBlock; + unsigned long m_cntrAddr; // BL_V7 }; #endif // _FIRMWAREIMAGE_H_ diff --git a/rmi4update/main.cpp b/rmi4update/main.cpp index f8adcba..796c9c2 100644 --- a/rmi4update/main.cpp +++ b/rmi4update/main.cpp @@ -174,6 +174,8 @@ int main(int argc, char **argv) strerror(errno)); return 1; } + //device.SetTransportDevice(deviceName); + //device.g_transportDeviceName = deviceName; // leon } else { if (!device.FindDevice()) return 1; diff --git a/rmi4update/rmi4update.cpp b/rmi4update/rmi4update.cpp index 6c267bc..f132d65 100644 --- a/rmi4update/rmi4update.cpp +++ b/rmi4update/rmi4update.cpp @@ -124,10 +124,39 @@ int RMI4Update::UpdateFirmware(bool force, bool performLockdown) if (rc != UPDATE_SUCCESS) return rc; - rc = EnterFlashProgramming(); - if (rc != UPDATE_SUCCESS) { - fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); - goto reset; + if (m_f34.GetFunctionVersion() == 0x02) { + rc = EnterFlashProgrammingV7(); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + goto reset; + } + + fprintf(stdout, "Erasing FW V7...\n"); + rc = EraseFirmwareV7(); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + goto reset; + } + fprintf(stdout, "Erasing FW done V7...\n"); + if (m_firmwareImage.GetFirmwareData()) { + fprintf(stdout, "Writing firmware V7...\n"); + rc = WriteFirmwareV7(); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + goto reset; + } + fprintf(stdout, "Writing firmware done V7...\n"); + } + if (m_firmwareImage.GetConfigData()) { + fprintf(stdout, "Writing configuration V7...\n"); + rc = WriteConfigV7(); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + goto reset; + } + fprintf(stdout, "Writing config done V7...\n"); + goto reset; + } } if (performLockdown && m_unlocked) { @@ -151,7 +180,6 @@ int RMI4Update::UpdateFirmware(bool force, bool performLockdown) fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); goto reset; } - } rc = WriteBootloaderID(); @@ -239,6 +267,199 @@ int RMI4Update::FindUpdateFunctions() return UPDATE_SUCCESS; } +int RMI4Update::rmi4update_poll() +{ + unsigned char f34_status; + unsigned short dataAddr = m_f34.GetDataBase(); + int rc; + + rc = m_device.Read(dataAddr, &f34_status, sizeof(unsigned char)); + if (rc != sizeof(unsigned char)) + return UPDATE_FAIL_WRITE_FLASH_COMMAND; + + m_flashStatus = f34_status & 0x1F; + m_inBLmode = f34_status & 0x80; + if(!m_flashStatus) + rc = m_device.Read(dataAddr + 4, &m_flashCmd, sizeof(unsigned char)); + + return 0; +} + +int RMI4Update::ReadFlashConfig() +{ + int rc; + int transaction_count, remain_block; + unsigned char *flash_cfg; + int transfer_leng = 0; + int read_leng = 0; + int offset = 0; + unsigned char trans_leng_buf[2]; + unsigned char cmd_buf[1]; + unsigned char off[2] = {0, 0}; + unsigned char partition_id = FLASH_CONFIG_PARTITION; + unsigned short dataAddr = m_f34.GetDataBase(); + int i; + int retry = 0; + unsigned char *data_temp; + struct partition_tbl *partition_temp; + + flash_cfg = (unsigned char *)malloc(m_blockSize * m_flashConfigLength); + memset(flash_cfg, 0, m_blockSize * m_flashConfigLength); + partition_temp = (partition_tbl *)malloc(sizeof(struct partition_tbl)); + memset(partition_temp, 0, sizeof(struct partition_tbl)); + /* calculate the count */ + remain_block = (m_flashConfigLength % m_payloadLength); + transaction_count = (m_flashConfigLength / m_payloadLength); + + if (remain_block > 0) + transaction_count++; + + /* set partition id for bootloader 7 */ + rc = m_device.Write(dataAddr + 1, &partition_id, sizeof(partition_id)); + if (rc != sizeof(partition_id)) + return UPDATE_FAIL_WRITE_FLASH_COMMAND; + rc = m_device.Write(dataAddr + 2, off, sizeof(off)); + if (rc != sizeof(off)) + return UPDATE_FAIL_WRITE_INITIAL_ZEROS; + + for (i = 0; i < transaction_count; i++) + { + if ((i == (transaction_count -1)) && (remain_block > 0)) + transfer_leng = remain_block; + else + transfer_leng = m_payloadLength; + + // Set Transfer Length + trans_leng_buf[0] = (unsigned char)(transfer_leng & 0xFF); + trans_leng_buf[1] = (unsigned char)((transfer_leng & 0xFF00) >> 8); + rc = m_device.Write(dataAddr + 3, trans_leng_buf, sizeof(trans_leng_buf)); + if (rc != sizeof(trans_leng_buf)) + return UPDATE_FAIL_WRITE_FLASH_COMMAND; + + // Set Command to Read + cmd_buf[0] = (unsigned char)CMD_V7_READ; + rc = m_device.Write(dataAddr + 4, cmd_buf, sizeof(cmd_buf)); + if (rc != sizeof(cmd_buf)) + return UPDATE_FAIL_WRITE_FLASH_COMMAND; + + //Wait for completion + do { + Sleep(20); + rmi4update_poll(); + if (m_flashStatus == SUCCESS){ + break; + } + retry++; + } while(retry < 20); + + read_leng = transfer_leng * m_blockSize; + data_temp = (unsigned char *) malloc(sizeof(char) * read_leng); + rc = m_device.Read(dataAddr + 5, data_temp, sizeof(char) * read_leng); + if (rc != ((ssize_t)sizeof(char) * read_leng)) + return UPDATE_FAIL_READ_F34_QUERIES; + + memcpy(flash_cfg + offset, data_temp, sizeof(char) * read_leng); + offset += read_leng; + free(data_temp); + } + + /* parse the config length */ + for (i = 2; i < m_blockSize * m_flashConfigLength; i = i + 8) + { + memcpy(partition_temp->data ,flash_cfg + i, sizeof(struct partition_tbl)); + if (partition_temp->partition_id == CORE_CONFIG_PARTITION) + { + m_partitionConfig = (partition_tbl *) malloc(sizeof(struct partition_tbl)); + memcpy(m_partitionConfig ,partition_temp, sizeof(struct partition_tbl)); + memset(partition_temp, 0, sizeof(struct partition_tbl)); + fprintf(stdout, "CORE_CONFIG_PARTITION is found\n"); + } + else if (partition_temp->partition_id == CORE_CODE_PARTITION) + { + m_partitionCore = (partition_tbl *) malloc(sizeof(struct partition_tbl)); + memcpy(m_partitionCore ,partition_temp, sizeof(struct partition_tbl)); + memset(partition_temp, 0, sizeof(struct partition_tbl)); + fprintf(stdout, "CORE_CODE_PARTITION is found\n"); + } + else if (partition_temp->partition_id == GUEST_CODE_PARTITION) + { + m_partitionGuest = (partition_tbl *) malloc(sizeof(struct partition_tbl)); + memcpy(m_partitionGuest ,partition_temp, sizeof(struct partition_tbl)); + memset(partition_temp, 0, sizeof(struct partition_tbl)); + fprintf(stdout, "GUEST_CODE_PARTITION is found\n"); + } + else if (partition_temp->partition_id == NONE_PARTITION) + break; + } + + if (flash_cfg) + free(flash_cfg); + + if (partition_temp) + free(partition_temp); + + m_fwBlockCount = m_partitionCore->partition_len; + m_configBlockCount = m_partitionConfig->partition_len; + m_guestBlockCount = m_partitionGuest->partition_len; + fprintf(stdout, "F34 fw blocks: %d\n", m_fwBlockCount); + fprintf(stdout, "F34 config blocks: %d\n", m_configBlockCount); + fprintf(stdout, "F34 guest blocks: %d\n", m_guestBlockCount); + fprintf(stdout, "\n"); + + m_guestData = (unsigned char *) malloc(m_guestBlockCount * m_blockSize); + memset(m_guestData, 0, m_guestBlockCount * m_blockSize); + memset(m_guestData + m_guestBlockCount * m_blockSize -4, 0, 4); + return UPDATE_SUCCESS; +} + +int RMI4Update::ReadF34QueriesV7() +{ + int rc; + struct f34_v7_query_0 query_0; + struct f34_v7_query_1_7 query_1_7; + unsigned char idStr[3]; + unsigned short queryAddr = m_f34.GetQueryBase(); + unsigned char offset; + + rc = m_device.Read(queryAddr, query_0.data, sizeof(query_0.data)); + if (rc != sizeof(query_0.data)) + return UPDATE_FAIL_READ_BOOTLOADER_ID; + + offset = query_0.subpacket_1_size + 1; + rc = m_device.Read(queryAddr + offset, query_1_7.data, sizeof(query_1_7.data)); + if (rc != sizeof(query_1_7.data)) + return UPDATE_FAIL_READ_BOOTLOADER_ID; + + m_bootloaderID[0] = query_1_7.bl_minor_revision; + m_bootloaderID[1] = query_1_7.bl_major_revision; + m_hasConfigID = query_0.has_config_id; + m_blockSize = query_1_7.block_size_15_8 << 8 | + query_1_7.block_size_7_0; + m_flashConfigLength = query_1_7.flash_config_length_15_8 << 8 | + query_1_7.flash_config_length_7_0; + m_payloadLength = query_1_7.payload_length_15_8 << 8 | + query_1_7.payload_length_7_0; + m_buildID = query_1_7.bl_fw_id_7_0 | + query_1_7.bl_fw_id_15_8 << 8 | + query_1_7.bl_fw_id_23_16 << 16 | + query_1_7.bl_fw_id_31_24 << 24; + + idStr[0] = m_bootloaderID[0]; + idStr[1] = m_bootloaderID[1]; + idStr[2] = 0; + + fprintf(stdout, "F34 bootloader id: %s (%#04x %#04x)\n", idStr, m_bootloaderID[0], + m_bootloaderID[1]); + fprintf(stdout, "F34 has config id: %d\n", m_hasConfigID); + fprintf(stdout, "F34 unlocked: %d\n", m_unlocked); + fprintf(stdout, "F34 block size: %d\n", m_blockSize); + fprintf(stdout, "F34 flash cfg leng:%d\n", m_flashConfigLength); + fprintf(stdout, "F34 payload length:%d\n", m_payloadLength); + fprintf(stdout, "F34 build id: %lu\n", m_buildID); + + return ReadFlashConfig(); +} + int RMI4Update::ReadF34Queries() { int rc; @@ -248,7 +469,9 @@ int RMI4Update::ReadF34Queries() unsigned short f34Version = m_f34.GetFunctionVersion(); unsigned short querySize; - if (f34Version == 0x1) + if (f34Version == 0x2) + return ReadF34QueriesV7(); + else if (f34Version == 0x1) querySize = 8; else querySize = 2; @@ -365,6 +588,350 @@ int RMI4Update::WriteBootloaderID() return UPDATE_SUCCESS; } +int RMI4Update::WriteFirmwareV7() +{ + int transaction_count, remain_block; + int transfer_leng = 0; + int offset = 0; + unsigned char trans_leng_buf[2]; + unsigned char cmd_buf[1]; + unsigned char off[2] = {0, 0}; + unsigned char partition_id; + int i; + int retry = 0; + unsigned char *data_temp; + int rc; + unsigned short left_bytes; + unsigned short write_size; + unsigned short max_write_size; + unsigned short dataAddr = m_f34.GetDataBase(); + + /* calculate the count */ + partition_id = CORE_CODE_PARTITION; + remain_block = (m_fwBlockCount % m_payloadLength); + transaction_count = (m_fwBlockCount / m_payloadLength); + if (remain_block > 0) + transaction_count++; + + /* set partition id for bootloader 7 */ + rc = m_device.Write(dataAddr + 1, &partition_id, sizeof(partition_id)); + if (rc != sizeof(partition_id)) + return UPDATE_FAIL_WRITE_FLASH_COMMAND; + + rc = m_device.Write(dataAddr + 2, off, sizeof(off)); + if (rc != sizeof(off)) + return UPDATE_FAIL_WRITE_INITIAL_ZEROS; + + for (i = 0; i < transaction_count; i++) + { + if ((i == (transaction_count -1)) && (remain_block > 0)) + transfer_leng = remain_block; + else + transfer_leng = m_payloadLength; + + // Set Transfer Length + trans_leng_buf[0] = (unsigned char)(transfer_leng & 0xFF); + trans_leng_buf[1] = (unsigned char)((transfer_leng & 0xFF00) >> 8); + + rc = m_device.Write(dataAddr + 3, trans_leng_buf, sizeof(trans_leng_buf)); + if (rc != sizeof(trans_leng_buf)) + return UPDATE_FAIL_WRITE_FLASH_COMMAND; + + // Set Command to Write + cmd_buf[0] = (unsigned char)CMD_V7_WRITE; + rc = m_device.Write(dataAddr + 4, cmd_buf, sizeof(cmd_buf)); + if (rc != sizeof(cmd_buf)) + return UPDATE_FAIL_WRITE_FLASH_COMMAND; + + max_write_size = 16; + if (max_write_size >= transfer_leng * m_blockSize) + max_write_size = transfer_leng * m_blockSize; + else if (max_write_size > m_blockSize) + max_write_size -= max_write_size % m_blockSize; + else + max_write_size = m_blockSize; + + left_bytes = transfer_leng * m_blockSize; + do { + if (left_bytes / max_write_size) + write_size = max_write_size; + else + write_size = left_bytes; + + data_temp = (unsigned char *) malloc(sizeof(unsigned char) * write_size); + memcpy(data_temp, m_firmwareImage.GetFirmwareData() + offset, sizeof(char) * write_size); + rc = m_device.Write(dataAddr + 5, data_temp, sizeof(char) * write_size); + if (rc != ((ssize_t)sizeof(char) * write_size)) { + fprintf(stdout, "err write_size = %d; rc = %d\n", write_size, rc); + return UPDATE_FAIL_READ_F34_QUERIES; + } + + offset += write_size; + left_bytes -= write_size; + free(data_temp); + } while (left_bytes); + + //Wait for completion + do { + Sleep(20); + rmi4update_poll(); + if (m_flashStatus == SUCCESS){ + break; + } + retry++; + } while(retry < 20); + + if (m_flashStatus != SUCCESS) { + fprintf(stdout, "err flash_status = %d\n", m_flashStatus); + return UPDATE_FAIL_WRITE_F01_CONTROL_0; + } + + } + return UPDATE_SUCCESS; +} + +int RMI4Update::WriteConfigV7() +{ + int transaction_count, remain_block; + int transfer_leng = 0; + int offset = 0; + unsigned char trans_leng_buf[2]; + unsigned char cmd_buf[1]; + unsigned char off[2] = {0, 0}; + unsigned char partition_id; + unsigned short dataAddr = m_f34.GetDataBase(); + unsigned short left_bytes; + unsigned short write_size; + unsigned short max_write_size; + int rc; + int i; + int retry = 0; + unsigned char *data_temp; + + /* calculate the count */ + partition_id = CORE_CONFIG_PARTITION; + remain_block = (m_configBlockCount % m_payloadLength); + transaction_count = (m_configBlockCount / m_payloadLength); + if (remain_block > 0) + transaction_count++; + + /* set partition id for bootloader 7 */ + rc = m_device.Write(dataAddr + 1, &partition_id, sizeof(partition_id)); + if (rc != sizeof(partition_id)) + return UPDATE_FAIL_WRITE_FLASH_COMMAND; + + rc = m_device.Write(dataAddr + 2, off, sizeof(off)); + if (rc != sizeof(off)) + return UPDATE_FAIL_WRITE_INITIAL_ZEROS; + + for (i = 0; i < transaction_count; i++) + { + if ((i == (transaction_count -1)) && (remain_block > 0)) + transfer_leng = remain_block; + else + transfer_leng = m_payloadLength; + + // Set Transfer Length + trans_leng_buf[0] = (unsigned char)(transfer_leng & 0xFF); + trans_leng_buf[1] = (unsigned char)((transfer_leng & 0xFF00) >> 8); + + rc = m_device.Write(dataAddr + 3, trans_leng_buf, sizeof(trans_leng_buf)); + if (rc != sizeof(trans_leng_buf)) + return UPDATE_FAIL_WRITE_FLASH_COMMAND; + + // Set Command to Write + cmd_buf[0] = (unsigned char)CMD_V7_WRITE; + rc = m_device.Write(dataAddr + 4, cmd_buf, sizeof(cmd_buf)); + if (rc != sizeof(cmd_buf)) + return UPDATE_FAIL_WRITE_FLASH_COMMAND; + + max_write_size = 16; + if (max_write_size >= transfer_leng * m_blockSize) + max_write_size = transfer_leng * m_blockSize; + else if (max_write_size > m_blockSize) + max_write_size -= max_write_size % m_blockSize; + else + max_write_size = m_blockSize; + + left_bytes = transfer_leng * m_blockSize; + + do { + if (left_bytes / max_write_size) + write_size = max_write_size; + else + write_size = left_bytes; + + data_temp = (unsigned char *) malloc(sizeof(unsigned char) * write_size); + memcpy(data_temp, m_firmwareImage.GetConfigData() + offset, sizeof(char) * write_size); + rc = m_device.Write(dataAddr + 5, data_temp, sizeof(char) * write_size); + if (rc != ((ssize_t)sizeof(char) * write_size)) { + fprintf(stdout, "err write_size = %d; rc = %d\n", write_size, rc); + return UPDATE_FAIL_READ_F34_QUERIES; + } + + offset += write_size; + left_bytes -= write_size; + free(data_temp); + } while (left_bytes); + + //Wait for completion + do { + Sleep(20); + rmi4update_poll(); + if (m_flashStatus == SUCCESS){ + break; + } + retry++; + } while(retry < 20); + + if (m_flashStatus != SUCCESS) { + fprintf(stdout, "err flash_status = %d\n", m_flashStatus); + return UPDATE_FAIL_WRITE_F01_CONTROL_0; + } + + } + return UPDATE_SUCCESS; +} + +int RMI4Update::EraseFirmwareV7() +{ + unsigned char erase_cmd[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + int retry = 0; + int rc; + + /* set partition id for bootloader 7 */ + erase_cmd[0] = CORE_CODE_PARTITION; + /* write bootloader id */ + erase_cmd[6] = m_bootloaderID[0]; + erase_cmd[7] = m_bootloaderID[1]; + /* Set Command to Erase */ + erase_cmd[5] = (unsigned char)CMD_V7_ERASE; + + rmi4update_poll(); + if (!m_inBLmode) + return UPDATE_FAIL_DEVICE_NOT_IN_BOOTLOADER; + + rc = m_device.Write(m_f34.GetDataBase() + 1, erase_cmd, sizeof(erase_cmd)); + if (rc != sizeof(erase_cmd)) + return UPDATE_FAIL_WRITE_F01_CONTROL_0; + + Sleep(100); + + //Wait from ATTN + do { + Sleep(20); + rmi4update_poll(); + if (m_flashStatus == SUCCESS){ + break; + } + retry++; + } while(retry < 20); + + if (m_flashStatus != SUCCESS) { + fprintf(stdout, "err flash_status = %d\n", m_flashStatus); + return UPDATE_FAIL_WRITE_F01_CONTROL_0; + } + + fprintf(stdout, "Star to erase config\n"); + /* set partition id for bootloader 7 */ + erase_cmd[0] = CORE_CONFIG_PARTITION; + /* write bootloader id */ + erase_cmd[6] = m_bootloaderID[0]; + erase_cmd[7] = m_bootloaderID[1]; + /* Set ¡¥Command¡Š to ¡¥Erase¡Š */ + erase_cmd[5] = (unsigned char)CMD_V7_ERASE; + + Sleep(100); + rmi4update_poll(); + if (!m_inBLmode) + return UPDATE_FAIL_DEVICE_NOT_IN_BOOTLOADER; + + rc = m_device.Write(m_f34.GetDataBase() + 1, erase_cmd, sizeof(erase_cmd)); + if (rc != sizeof(erase_cmd)) + return UPDATE_FAIL_WRITE_F01_CONTROL_0; + + //Wait from ATTN + Sleep(100); + do { + Sleep(20); + rmi4update_poll(); + if (m_flashStatus == SUCCESS){ + break; + } + retry++; + } while(retry < 20); + + if (m_flashStatus != SUCCESS) { + fprintf(stdout, "err flash_status = %d\n", m_flashStatus); + return UPDATE_FAIL_WRITE_F01_CONTROL_0; + } + + return UPDATE_SUCCESS; +} + +int RMI4Update::EnterFlashProgrammingV7() +{ + int rc; + unsigned char EnterCmd[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + int retry = 0; + + /* set partition id for bootloader 7 */ + EnterCmd[0] = BOOTLOADER_PARTITION; + + /* write bootloader id */ + EnterCmd[6] = m_bootloaderID[0]; + EnterCmd[7] = m_bootloaderID[1]; + + // Set Command to EnterBL + EnterCmd[5] = (unsigned char)CMD_V7_ENTER_BL; + + rc = m_device.Write(m_f34.GetDataBase() + 1, EnterCmd, sizeof(EnterCmd)); + if (rc != sizeof(EnterCmd)) + return UPDATE_FAIL_WRITE_F01_CONTROL_0; + + //Wait from ATTN + do { + Sleep(20); + rmi4update_poll(); + if (m_flashStatus == SUCCESS){ + break; + } + retry++; + } while(retry < 20); + + if (m_flashStatus != SUCCESS) { + fprintf(stdout, "err flash_status = %d\n", m_flashStatus); + return UPDATE_FAIL_WRITE_F01_CONTROL_0; + } + + Sleep(RMI_F34_ENABLE_WAIT_MS); + + fprintf(stdout, "%s\n", __func__); + rmi4update_poll(); + if (!m_inBLmode) + return UPDATE_FAIL_DEVICE_NOT_IN_BOOTLOADER; +///////////////////////////////////////////////////////////////////////////// + // workaround + //rc = EraseFirmwareV7(); + //if (rc != UPDATE_SUCCESS) { + // fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + // return UPDATE_FAIL_ERASE_ALL; + //} +///////////////////////////////////////////////////////////////////////////// + m_device.RebindDriver(); + Sleep(RMI_F34_ENABLE_WAIT_MS); + + rc = FindUpdateFunctions(); + if (rc != UPDATE_SUCCESS) + return rc; + + rc = ReadF34Queries(); + if (rc != UPDATE_SUCCESS) + return rc; + + return UPDATE_SUCCESS; +} + int RMI4Update::EnterFlashProgramming() { int rc; diff --git a/rmi4update/rmi4update.h b/rmi4update/rmi4update.h index eaad0f6..f64028f 100644 --- a/rmi4update/rmi4update.h +++ b/rmi4update/rmi4update.h @@ -23,6 +23,133 @@ #define RMI_BOOTLOADER_ID_SIZE 2 +// leon add +enum v7_status { + SUCCESS = 0x00, + DEVICE_NOT_IN_BOOTLOADER_MODE, + INVALID_PARTITION, + INVALID_COMMAND, + INVALID_BLOCK_OFFSET, + INVALID_TRANSFER, + NOT_ERASED, + FLASH_PROGRAMMING_KEY_INCORRECT, + BAD_PARTITION_TABLE, + CHECKSUM_FAILED, + FLASH_HARDWARE_FAILURE = 0x1f, +}; + +enum v7_partition_id { + NONE_PARTITION = 0x00, + BOOTLOADER_PARTITION = 0x01, + DEVICE_CONFIG_PARTITION, + FLASH_CONFIG_PARTITION, + MANUFACTURING_BLOCK_PARTITION, + GUEST_SERIALIZATION_PARTITION, + GLOBAL_PARAMETERS_PARTITION, + CORE_CODE_PARTITION, + CORE_CONFIG_PARTITION, + GUEST_CODE_PARTITION, + DISPLAY_CONFIG_PARTITION, + EXTERNAL_TOUCH_AFE_CONFIG_PARTITION, + UTILITY_PARAMETER_PARTITION, +}; + +enum v7_flash_command { + CMD_V7_IDLE = 0x00, + CMD_V7_ENTER_BL, + CMD_V7_READ, + CMD_V7_WRITE, + CMD_V7_ERASE, + CMD_V7_ERASE_AP, + CMD_V7_SENSOR_ID, +}; + +enum bl_version { + BL_V5 = 5, + BL_V6 = 6, + BL_V7 = 7, + BL_V8 = 8, +}; + +struct f34_v7_query_0 { + union { + struct { + unsigned char subpacket_1_size:3; + unsigned char has_config_id:1; + unsigned char f34_query0_b4:1; + unsigned char has_thqa:1; + unsigned char f34_query0_b6__7:2; + } __attribute__((packed));; + unsigned char data[1]; + }; +}; + +struct f34_v7_query_1_7 { + union { + struct { + /* query 1 */ + unsigned char bl_minor_revision; + unsigned char bl_major_revision; + + /* query 2 */ + unsigned char bl_fw_id_7_0; + unsigned char bl_fw_id_15_8; + unsigned char bl_fw_id_23_16; + unsigned char bl_fw_id_31_24; + + /* query 3 */ + unsigned char minimum_write_size; + unsigned char block_size_7_0; + unsigned char block_size_15_8; + unsigned char flash_page_size_7_0; + unsigned char flash_page_size_15_8; + + /* query 4 */ + unsigned char adjustable_partition_area_size_7_0; + unsigned char adjustable_partition_area_size_15_8; + + /* query 5 */ + unsigned char flash_config_length_7_0; + unsigned char flash_config_length_15_8; + + /* query 6 */ + unsigned char payload_length_7_0; + unsigned char payload_length_15_8; + + /* query 7 */ + unsigned char f34_query7_b0:1; + unsigned char has_bootloader:1; + unsigned char has_device_config:1; + unsigned char has_flash_config:1; + unsigned char has_manufacturing_block:1; + unsigned char has_guest_serialization:1; + unsigned char has_global_parameters:1; + unsigned char has_core_code:1; + unsigned char has_core_config:1; + unsigned char has_guest_code:1; + unsigned char has_display_config:1; + unsigned char f34_query7_b11__15:5; + unsigned char f34_query7_b16__23; + unsigned char f34_query7_b24__31; + } __attribute__((packed));; + unsigned char data[21]; + }; +}; + +struct partition_tbl +{ + union { + struct { + unsigned short partition_id; + unsigned short partition_len; + unsigned short partition_addr; + unsigned short partition_prop; + } __attribute__((packed));; + unsigned char data[8]; + }; +}; +// leon end + class RMI4Update { public: @@ -34,9 +161,16 @@ public: private: int DisableNonessentialInterupts(); int FindUpdateFunctions(); + int ReadFlashConfig(); + int rmi4update_poll(); + int ReadF34QueriesV7(); int ReadF34Queries(); int ReadF34Controls(); int WriteBootloaderID(); + int EnterFlashProgrammingV7(); + int EraseFirmwareV7(); + int WriteFirmwareV7(); + int WriteConfigV7(); int EnterFlashProgramming(); int WriteBlocks(unsigned char *block, unsigned short count, unsigned char cmd); int WaitForIdle(int timeout_ms, bool readF34OnSucess = true); @@ -66,8 +200,22 @@ private: unsigned short m_blockSize; unsigned short m_fwBlockCount; unsigned short m_configBlockCount; + /* for BL_V7 */ + unsigned short m_flashConfigLength; + unsigned short m_payloadLength; + unsigned short m_guestBlockCount; + struct partition_tbl *m_partitionCore; + struct partition_tbl *m_partitionConfig; + struct partition_tbl *m_partitionGuest; + unsigned char m_flashStatus; + unsigned char m_flashCmd; + unsigned char m_inBLmode; + unsigned long m_buildID; + unsigned char *m_guestData; + /* BL_V7 end */ unsigned short m_f34StatusAddr; + enum bl_version m_blVersion; }; #endif // _RMI4UPDATE_H_ |