diff options
author | Vincent Huang <vincenthsw@gmail.com> | 2022-03-14 16:41:07 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-14 16:41:07 +0800 |
commit | aa18b07911a0e53a8d2072d76fc44ad488bc1d90 (patch) | |
tree | b46fd02eef4c8affba46bd566d173fea79d58eac | |
parent | 7f553ab32a9f7096c8d041bc8cf79533a4cb3ff2 (diff) | |
parent | 6940581af1507a177050fdd33c1847c1f9ba945c (diff) | |
download | rmi4utils-aa18b07911a0e53a8d2072d76fc44ad488bc1d90.tar.gz |
Merge pull request #32 from blueue/BLv10
Support firmware updating for BL v10
-rw-r--r-- | f54test/f54test.cpp | 2 | ||||
-rwxr-xr-x | rmi4update/firmware_image.cpp | 39 | ||||
-rwxr-xr-x | rmi4update/firmware_image.h | 38 | ||||
-rwxr-xr-x | rmi4update/rmi4update.cpp | 635 | ||||
-rwxr-xr-x | rmi4update/rmi4update.h | 25 | ||||
-rwxr-xr-x | rmidevice/hiddevice.cpp | 14 |
6 files changed, 717 insertions, 36 deletions
diff --git a/f54test/f54test.cpp b/f54test/f54test.cpp index 4b4f6b1..c6b351e 100644 --- a/f54test/f54test.cpp +++ b/f54test/f54test.cpp @@ -695,7 +695,7 @@ int F54Test::ReadF54Queries() sizeof(m_f54Query_61.data)); if (retval < 0) return retval; - offset += 1; + offset += 1; } /* query 62 63 */ diff --git a/rmi4update/firmware_image.cpp b/rmi4update/firmware_image.cpp index bfbbc54..e4813c5 100755 --- a/rmi4update/firmware_image.cpp +++ b/rmi4update/firmware_image.cpp @@ -54,6 +54,15 @@ void FirmwareImage::ParseHierarchicalImg() unsigned int length; unsigned char *content; unsigned short container_id; + unsigned int sigature_size; + + if (m_bootloaderVersion == RMI_IMG_V10_SIGNATURE_VERSION_NUMBER) { + fprintf (stdout, "has signature\n"); + for (ii = 0; ii < BLv7_MAX; ii++) { + m_signatureInfo[ii].bExisted = false; + m_signatureInfo[ii].size = 0; + } + } m_cntrAddr = extract_long(&m_memBlock[RMI_IMG_V10_CNTR_ADDR_OFFSET]); descriptor = (struct container_descriptor *)(m_memBlock + m_cntrAddr); @@ -68,21 +77,37 @@ void FirmwareImage::ParseHierarchicalImg() descriptor->container_id[1] << 8; content = m_memBlock + extract_long(descriptor->content_address); length = extract_long(descriptor->content_length); + sigature_size = extract_long(descriptor->signature_size); switch (container_id) { case BL_CONTAINER: m_bootloaderVersion = *content; break; case UI_CONTAINER: case CORE_CODE_CONTAINER: + if (sigature_size != 0) { + fprintf(stdout, "CORE CODE signature size : 0x%x\n", sigature_size); + m_signatureInfo[BLv7_CORE_CODE].bExisted = true; + m_signatureInfo[BLv7_CORE_CODE].size = sigature_size; + } m_firmwareData = content; m_firmwareSize = length; break; case FLASH_CONFIG_CONTAINER: + if (sigature_size != 0) { + fprintf(stdout, "FLASH CONFIG signature size : 0x%x\n", sigature_size); + m_signatureInfo[BLv7_FLASH_CONFIG].bExisted = true; + m_signatureInfo[BLv7_FLASH_CONFIG].size = sigature_size; + } m_flashConfigData = content; m_flashConfigSize = length; break; case UI_CONFIG_CONTAINER: case CORE_CONFIG_CONTAINER: + if (sigature_size != 0) { + fprintf(stdout, "CORE CONFIG signature size : 0x%x\n", sigature_size); + m_signatureInfo[BLv7_CORE_CONFIG].bExisted = true; + m_signatureInfo[BLv7_CORE_CONFIG].size = sigature_size; + } m_configData = content; m_configSize = length; break; @@ -98,6 +123,19 @@ void FirmwareImage::ParseHierarchicalImg() memcpy(m_productID, (content + 0x18), RMI_PRODUCT_ID_LENGTH); m_productID[RMI_PRODUCT_ID_LENGTH] = 0; break; + case FIXED_LOCATION_DATA_CONTAINER: + if (sigature_size != 0) { + fprintf(stdout, "FLD signature size : 0x%x\n", sigature_size); + m_signatureInfo[BLv7_FLD].bExisted = true; + m_signatureInfo[BLv7_FLD].size = sigature_size; + } + m_fldData = content; + m_fldSize = length; + break; + case GLOBAL_PARAMETERS_CONTAINER: + m_globalparaData = content; + m_globalparaSize = length; + break; default: break; } @@ -176,6 +214,7 @@ int FirmwareImage::Initialize(const char * filename) m_lockdownData = &m_memBlock[RMI_IMG_LOCKDOWN_V5_OFFSET]; break; case 16: + case RMI_IMG_V10_SIGNATURE_VERSION_NUMBER: ParseHierarchicalImg(); break; default: diff --git a/rmi4update/firmware_image.h b/rmi4update/firmware_image.h index b9dab84..e4279d5 100755 --- a/rmi4update/firmware_image.h +++ b/rmi4update/firmware_image.h @@ -45,16 +45,16 @@ // Leon add for BL_V7 #define RMI_IMG_V10_CNTR_ADDR_OFFSET 0x0C +#define RMI_IMG_V10_SIGNATURE_VERSION_NUMBER 0x11 +#define RMI_IMG_V10_SIGNATURE_LENGTH_OFFSET 0x8 +#define RMI_IMG_V10_SIGNATURE_LENGTH_SIZE 4 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 signature_size[4]; unsigned char container_option_flags[4]; unsigned char content_options_length[4]; unsigned char content_options_address[4]; @@ -87,6 +87,22 @@ enum container_id { EXTERNAL_TOUCH_AFE_CONFIG_CONTAINER, UTILITY_CONTAINER, UTILITY_PARAMETER_CONTAINER, + // Reserved : 24 ~ 26 + // V10 above + FIXED_LOCATION_DATA_CONTAINER = 27, +}; + +enum signature_BLv7 { + BLv7_CORE_CODE = 0, + BLv7_CORE_CONFIG, + BLv7_FLASH_CONFIG, + BLv7_FLD, + BLv7_MAX +}; + +struct signature_info { + bool bExisted; + unsigned short size; }; // BL_V7 end @@ -94,7 +110,7 @@ class FirmwareImage { public: FirmwareImage() : m_firmwareBuildID(0), m_packageID(0), m_firmwareData(NULL), m_configData(NULL), m_lockdownData(NULL), - m_memBlock(NULL) + m_memBlock(NULL), m_hasSignature(false), m_fldData(NULL), m_fldSize(0), m_globalparaData(NULL), m_globalparaSize(0) {} int Initialize(const char * filename); int VerifyImageMatchesDevice(unsigned long deviceFirmwareSize, @@ -103,11 +119,16 @@ public: unsigned char * GetConfigData() { return m_configData; } unsigned char * GetFlashConfigData() { return m_flashConfigData; } unsigned char * GetLockdownData() { return m_lockdownData; } + unsigned char * GetFLDData() { return m_fldData; } + unsigned char * GetGlobalParametersData() { return m_globalparaData; } unsigned long GetFirmwareSize() { return m_firmwareSize; } unsigned long GetConfigSize() { return m_configSize; } unsigned long GetFlashConfigSize() { return m_flashConfigSize; } unsigned long GetLockdownSize() { return m_lockdownSize; } unsigned long GetFirmwareID() { return m_firmwareBuildID; } + unsigned long GetFLDSize() { return m_fldSize; } + unsigned long GetGlobalParametersSize() { return m_globalparaSize; } + signature_info *GetSignatureInfo() { return m_signatureInfo; } int VerifyImageProductID(char* deviceProductID); bool HasIO() { return m_io; } @@ -138,6 +159,13 @@ private: unsigned char * m_lockdownData; unsigned char * m_memBlock; unsigned long m_cntrAddr; // BL_V7 + bool m_hasSignature; + unsigned char * m_fldData; + unsigned long m_fldSize; + unsigned char * m_globalparaData; + unsigned long m_globalparaSize; + + signature_info m_signatureInfo[BLv7_MAX]; }; #endif // _FIRMWAREIMAGE_H_ diff --git a/rmi4update/rmi4update.cpp b/rmi4update/rmi4update.cpp index fb34953..ec6e84b 100755 --- a/rmi4update/rmi4update.cpp +++ b/rmi4update/rmi4update.cpp @@ -141,9 +141,13 @@ int RMI4Update::UpdateFirmware(bool force, bool performLockdown) rc = ReadF34Queries(); if (rc != UPDATE_SUCCESS) return rc; - rc = m_firmwareImage.VerifyImageMatchesDevice(GetFirmwareSize(), GetConfigSize()); - if (rc != UPDATE_SUCCESS) - return rc; + + if (m_bootloaderID[1] < 10) { + // Checking size alignment for the device prior to BL v10. + rc = m_firmwareImage.VerifyImageMatchesDevice(GetFirmwareSize(), GetConfigSize()); + if (rc != UPDATE_SUCCESS) + return rc; + } if (m_f34.GetFunctionVersion() == 0x02) { fprintf(stdout, "Enable Flash V7+...\n"); @@ -154,46 +158,117 @@ int RMI4Update::UpdateFirmware(bool force, bool performLockdown) } fprintf(stdout, "Enable Flash done V7+...\n"); - if (!m_IsErased){ - fprintf(stdout, "Erasing FW V7+...\n"); - rc = EraseFirmwareV7(); + if (m_bootloaderID[1] >= 10) { + fprintf(stdout, "Writing FLD V10...\n"); + rc = WriteFLDV7(); 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_bootloaderID[1] == 8){ + fprintf(stdout, "Writing FLD done V10...\n"); + + fprintf(stdout, "Erasing Flash Config V10...\n"); + rc = EraseFlashConfigV10(); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + goto reset; + } + fprintf(stdout, "Erasing Flash Config done V10...\n"); + if (m_firmwareImage.GetFlashConfigData()) { - fprintf(stdout, "Writing flash configuration V8...\n"); + fprintf(stdout, "Writing flash configuration V10...\n"); rc = WriteFlashConfigV7(); if (rc != UPDATE_SUCCESS) { fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); goto reset; } - fprintf(stdout, "Writing flash config done V8...\n"); + fprintf(stdout, "Writing flash config done V10...\n"); } - } - if (m_firmwareImage.GetFirmwareData()) { - fprintf(stdout, "Writing firmware V7+...\n"); - rc = WriteFirmwareV7(); + + fprintf(stdout, "Erasing Core Code V10...\n"); + rc = EraseCoreCodeV10(); 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 core configuration V7+...\n"); - rc = WriteCoreConfigV7(); - if (rc != UPDATE_SUCCESS) { - fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + fprintf(stdout, "Erasing Core Code done V10...\n"); + + if (m_firmwareImage.GetFirmwareData()) { + fprintf(stdout, "Writing Core Code V10...\n"); + rc = WriteFirmwareV7(); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + goto reset; + } + fprintf(stdout, "Writing Core Code done V10...\n"); + } + + if (m_firmwareImage.GetConfigData()) { + fprintf(stdout, "Writing Core Config V10...\n"); + rc = WriteCoreConfigV7(); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + goto reset; + } + fprintf(stdout, "Writing Core Config done V10...\n"); + goto reset; + } + + if (m_firmwareImage.GetGlobalParametersSize() && m_hasGlobalParameters) { + fprintf(stdout, "Writing Global Parameters V10...\n"); + rc = WriteGlobalParametersV7(); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + goto reset; + } + fprintf(stdout, "Writing Global Parameters done V10...\n"); + goto reset; + } + + + } else { + if (!m_IsErased){ + 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_bootloaderID[1] == 8){ + if (m_firmwareImage.GetFlashConfigData()) { + fprintf(stdout, "Writing flash configuration V8...\n"); + rc = WriteFlashConfigV7(); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + goto reset; + } + fprintf(stdout, "Writing flash config done V8...\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 core configuration V7+...\n"); + rc = WriteCoreConfigV7(); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + goto reset; + } + fprintf(stdout, "Writing core config done V7+...\n"); goto reset; } - fprintf(stdout, "Writing core config done V7+...\n"); - goto reset; } + } else { rc = EnterFlashProgramming(); if (rc != UPDATE_SUCCESS) { @@ -524,6 +599,17 @@ int RMI4Update::ReadF34QueriesV7() idStr[1] = m_bootloaderID[1]; idStr[2] = 0; + m_hasCoreCode = query_1_7.has_core_code; + m_hasCoreConfig = query_1_7.has_core_config; + m_hasFlashConfig = query_1_7.has_flash_config; + m_hasFLD = query_1_7.has_fld; + m_hasGlobalParameters = query_1_7.has_global_parameters; + + fprintf(stdout, "F34 has CoreCode: %d\n", m_hasCoreCode); + fprintf(stdout, "F34 has CoreConfig: %d\n", m_hasCoreConfig); + fprintf(stdout, "F34 has FlashConfig: %d\n", m_hasFlashConfig); + fprintf(stdout, "F34 has FLD: %d\n", m_hasFLD); + 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); @@ -533,7 +619,12 @@ int RMI4Update::ReadF34QueriesV7() fprintf(stdout, "F34 payload length:%d\n", m_payloadLength); fprintf(stdout, "F34 build id: %lu\n", m_buildID); - return ReadFlashConfig(); + if ((m_device.GetDeviceType() == RMI_DEVICE_TYPE_TOUCHPAD) && (m_bootloaderID[1] == 10)) { + // FW size would be different from the one in image file in bootloader v10, + // we use size parsing in image file instead. + return UPDATE_SUCCESS; + } else + return ReadFlashConfig(); } int RMI4Update::ReadF34Queries() @@ -682,10 +773,16 @@ int RMI4Update::WriteFirmwareV7() unsigned short max_write_size; unsigned short dataAddr = m_f34.GetDataBase(); + if (m_bootloaderID[1] == 10) { + m_fwBlockCount = m_firmwareImage.GetFirmwareSize() / m_blockSize; + } + /* 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++; @@ -775,6 +872,16 @@ int RMI4Update::WriteFirmwareV7() } } + + if(m_device.GetDeviceType() == RMI_DEVICE_TYPE_TOUCHPAD) { + // Write signature. + rc = WriteSignatureV7(BLv7_CORE_CODE, m_firmwareImage.GetFirmwareData(), offset); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + return rc; + } + } + return UPDATE_SUCCESS; } @@ -795,11 +902,16 @@ int RMI4Update::WriteCoreConfigV7() int i; int retry = 0; unsigned char *data_temp; + if (m_bootloaderID[1] == 10) { + m_configBlockCount = m_firmwareImage.GetConfigSize() / m_blockSize; + } /* 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++; @@ -886,6 +998,16 @@ int RMI4Update::WriteCoreConfigV7() } } + + if(m_device.GetDeviceType() == RMI_DEVICE_TYPE_TOUCHPAD) { + // Write signature. + rc = WriteSignatureV7(BLv7_CORE_CONFIG, m_firmwareImage.GetConfigData(), offset); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + return rc; + } + } + return UPDATE_SUCCESS; } @@ -1002,6 +1124,382 @@ int RMI4Update::WriteFlashConfigV7() } } + + if(m_device.GetDeviceType() == RMI_DEVICE_TYPE_TOUCHPAD) { + // Write signature. + rc = WriteSignatureV7(BLv7_FLASH_CONFIG, m_firmwareImage.GetFlashConfigData(), offset); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + return rc; + } + } + + return UPDATE_SUCCESS; +} + +int RMI4Update::WriteFLDV7() +{ + 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(); + unsigned short fldBlockCount = m_firmwareImage.GetFLDSize() / m_blockSize; + + if (m_bootloaderID[1] < 10) { + // Not support writing FLD before bootloader v10 + return UPDATE_SUCCESS; + } + + /* calculate the count */ + partition_id = FIXED_LOCATION_DATA_PARTITION; + + remain_block = (fldBlockCount % m_payloadLength); + transaction_count = (fldBlockCount / 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.GetFLDData() + 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); + + if(m_device.GetDeviceType() == RMI_DEVICE_TYPE_TOUCHPAD) { + // Sleep 100 ms and wait for attention for touchpad only. + Sleep(100); + rc = WaitForIdle(RMI_F34_IDLE_WAIT_MS, false); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + return UPDATE_FAIL_TIMEOUT_WAITING_FOR_ATTN; + } + } + + + //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; + } + + } + + if(m_device.GetDeviceType() == RMI_DEVICE_TYPE_TOUCHPAD) { + // Write signature. + rc = WriteSignatureV7(BLv7_FLD, m_firmwareImage.GetFLDData(), offset); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + return rc; + } + } + + return UPDATE_SUCCESS; +} + +int RMI4Update::WriteGlobalParametersV7() +{ + 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(); + unsigned short glpBlockCount = m_firmwareImage.GetGlobalParametersSize() / m_blockSize; + + /* calculate the count */ + partition_id = GLOBAL_PARAMETERS_PARTITION; + + remain_block = (glpBlockCount % m_payloadLength); + transaction_count = (glpBlockCount / 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.GetFLDData() + 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); + + if(m_device.GetDeviceType() == RMI_DEVICE_TYPE_TOUCHPAD) { + // Sleep 100 ms and wait for attention for touchpad only. + Sleep(100); + rc = WaitForIdle(RMI_F34_IDLE_WAIT_MS, false); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + return UPDATE_FAIL_TIMEOUT_WAITING_FOR_ATTN; + } + } + + + //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::EraseFlashConfigV10() +{ + unsigned char erase_cmd[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + int retry = 0; + int rc; + + /* set partition id for bootloader 10 */ + erase_cmd[0] = FLASH_CONFIG_PARTITION; + /* write bootloader id */ + erase_cmd[6] = m_bootloaderID[0]; + erase_cmd[7] = m_bootloaderID[1]; + erase_cmd[5] = (unsigned char)CMD_V7_ERASE; + + fprintf(stdout, "Erase command : "); + for(int i = 0 ;i<8;i++){ + fprintf(stdout, "%d ", erase_cmd[i]); + } + fprintf(stdout, "\n"); + + rmi4update_poll(); + if (!m_inBLmode) + return UPDATE_FAIL_DEVICE_NOT_IN_BOOTLOADER; + + // For BL8 device, we need hold 1 seconds after querying + // F34 status to avoid not get attention by following giving + // erase command. + Sleep(1000); + + 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 + rc = WaitForIdle(RMI_F34_ERASE_V8_WAIT_MS, false); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + return UPDATE_FAIL_TIMEOUT_WAITING_FOR_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; + } + + return UPDATE_SUCCESS; +} + +int RMI4Update::EraseCoreCodeV10() +{ + unsigned char erase_cmd[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + int retry = 0; + int rc; + + /* set partition id for bootloader 10 */ + erase_cmd[0] = CORE_CODE_PARTITION; + /* write bootloader id */ + erase_cmd[6] = m_bootloaderID[0]; + erase_cmd[7] = m_bootloaderID[1]; + erase_cmd[5] = (unsigned char)CMD_V7_ERASE_AP; + + fprintf(stdout, "Erase command : "); + for(int i = 0 ;i<8;i++){ + fprintf(stdout, "%d ", erase_cmd[i]); + } + fprintf(stdout, "\n"); + + rmi4update_poll(); + if (!m_inBLmode) + return UPDATE_FAIL_DEVICE_NOT_IN_BOOTLOADER; + + // For BL8 device, we need hold 1 seconds after querying + // F34 status to avoid not get attention by following giving + // erase command. + Sleep(1000); + + 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 + rc = WaitForIdle(RMI_F34_ERASE_V8_WAIT_MS, false); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + return UPDATE_FAIL_TIMEOUT_WAITING_FOR_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; + } + return UPDATE_SUCCESS; } @@ -1324,6 +1822,93 @@ int RMI4Update::WriteBlocks(unsigned char *block, unsigned short count, unsigned return UPDATE_SUCCESS; } +int RMI4Update::WriteSignatureV7(enum signature_BLv7 signature_partition, unsigned char* data, int offset) +{ + fprintf(stdout, "Write Signature...\n"); + int rc; + unsigned char off[2] = {0, 0}; + unsigned char cmd_buf[1]; + unsigned short dataAddr = m_f34.GetDataBase(); + int transfer_leng = 0; + signature_info signature = m_firmwareImage.GetSignatureInfo()[signature_partition]; + unsigned char trans_leng_buf[2]; + unsigned short left_bytes; + unsigned short write_size; + unsigned short max_write_size; + unsigned char *data_temp; + int retry = 0; + rc = m_device.Write(dataAddr + 2, off, sizeof(off)); + if (rc != sizeof(off)) + return UPDATE_FAIL_WRITE_INITIAL_ZEROS; + + // Set Transfer Length + transfer_leng = signature.size / m_blockSize; + 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 Signature + cmd_buf[0] = (unsigned char)CMD_V7_SIGNATURE; + 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, data + 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_WRITE_BLOCK; + } + + offset += write_size; + left_bytes -= write_size; + free(data_temp); + } while (left_bytes); + + // Wair for attention for touchpad only. + rc = WaitForIdle(RMI_F34_IDLE_WAIT_MS, false); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + return UPDATE_FAIL_TIMEOUT_WAITING_FOR_ATTN; + } + + //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; +} + /* * This is a limited implementation of WaitForIdle which assumes WaitForAttention is supported * this will be true for HID, but other protocols will need to revert polling. Polling diff --git a/rmi4update/rmi4update.h b/rmi4update/rmi4update.h index b9de4ec..928e07b 100755 --- a/rmi4update/rmi4update.h +++ b/rmi4update/rmi4update.h @@ -52,6 +52,7 @@ enum v7_partition_id { DISPLAY_CONFIG_PARTITION, EXTERNAL_TOUCH_AFE_CONFIG_PARTITION, UTILITY_PARAMETER_PARTITION, + FIXED_LOCATION_DATA_PARTITION = 0x0E, }; enum v7_flash_command { @@ -62,6 +63,7 @@ enum v7_flash_command { CMD_V7_ERASE, CMD_V7_ERASE_AP, CMD_V7_SENSOR_ID, + CMD_V7_SIGNATURE, }; enum bl_version { @@ -69,6 +71,7 @@ enum bl_version { BL_V6 = 6, BL_V7 = 7, BL_V8 = 8, + BL_V10 = 10, }; struct f34_v7_query_0 { @@ -128,7 +131,9 @@ struct f34_v7_query_1_7 { 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_b11_13:3; + unsigned char has_fld:1; + unsigned char f34_query7_b15:1; unsigned char f34_query7_b16__23; unsigned char f34_query7_b24__31; } __attribute__((packed));; @@ -157,6 +162,11 @@ public: m_firmwareImage(firmwareImage), m_writeBlockWithCmd(true) { m_IsErased = false; + m_hasCoreCode = false; + m_hasCoreConfig = false; + m_hasFlashConfig = false; + m_hasFLD = false; + m_hasGlobalParameters = false; } int UpdateFirmware(bool force = false, bool performLockdown = false); @@ -171,14 +181,19 @@ private: int WriteBootloaderID(); int EnterFlashProgrammingV7(); int EraseFirmwareV7(); + int EraseFlashConfigV10(); + int EraseCoreCodeV10(); int WriteFirmwareV7(); int WriteCoreConfigV7(); int WriteFlashConfigV7(); + int WriteFLDV7(); + int WriteGlobalParametersV7(); int EnterFlashProgramming(); int WriteBlocks(unsigned char *block, unsigned short count, unsigned char cmd); int WaitForIdle(int timeout_ms, bool readF34OnSucess = true); int GetFirmwareSize() { return m_blockSize * m_fwBlockCount; } int GetConfigSize() { return m_blockSize * m_configBlockCount; } + int WriteSignatureV7(enum signature_BLv7 signature_partition, unsigned char* data, int offset); private: RMIDevice & m_device; @@ -215,6 +230,14 @@ private: unsigned char m_inBLmode; unsigned long m_buildID; unsigned char *m_guestData; + bool m_hasCoreCode; + bool m_hasCoreConfig; + bool m_hasFlashConfig; + bool m_hasGlobalParameters; + /* BL_V7 end */ + + /* for BL V10 */ + bool m_hasFLD; /* BL_V7 end */ unsigned short m_f34StatusAddr; diff --git a/rmidevice/hiddevice.cpp b/rmidevice/hiddevice.cpp index b727cb5..5bc7c99 100755 --- a/rmidevice/hiddevice.cpp +++ b/rmidevice/hiddevice.cpp @@ -302,6 +302,8 @@ int HIDDevice::Read(unsigned short addr, unsigned char *buf, unsigned short len) tv.tv_sec = 10 / 1000; tv.tv_usec = (10 % 1000) * 1000; + + fprintf(stdout, "R %02x : ", addr); if (!m_deviceOpen) return -1; @@ -397,6 +399,12 @@ Resend: fprintf(stdout, "\n"); } + for (int i=0 ; i<len ; i++) { + fprintf(stdout, "%02x ", buf[i]); + } + fprintf(stdout, "\n"); + + return totalBytesRead; } @@ -741,11 +749,9 @@ bool HIDDevice::CheckABSEvent() int fd=-1; unsigned int type; int abs[6] = {0}; - int k; struct dirent **namelist; - int i, ndev, devnum, match; - char *filename; - int max_device = 0; + int i, ndev; + char input_event_name[PATH_MAX]; unsigned long bit[EV_MAX][NBITS(KEY_MAX)]; |