diff options
Diffstat (limited to 'rmi4update')
-rw-r--r-- | rmi4update/Android.bp | 1 | ||||
-rwxr-xr-x[-rw-r--r--] | rmi4update/firmware_image.cpp | 64 | ||||
-rwxr-xr-x[-rw-r--r--] | rmi4update/firmware_image.h | 53 | ||||
-rwxr-xr-x[-rw-r--r--] | rmi4update/main.cpp | 116 | ||||
-rwxr-xr-x[-rw-r--r--] | rmi4update/rmi4update.cpp | 847 | ||||
-rwxr-xr-x[-rw-r--r--] | rmi4update/rmi4update.h | 155 | ||||
-rw-r--r-- | rmi4update/updateutil.cpp | 26 | ||||
-rw-r--r-- | rmi4update/updateutil.h | 4 |
8 files changed, 1152 insertions, 114 deletions
diff --git a/rmi4update/Android.bp b/rmi4update/Android.bp index a7269c5..e3ba434 100644 --- a/rmi4update/Android.bp +++ b/rmi4update/Android.bp @@ -19,6 +19,7 @@ cc_binary { "-Wall", "-Werror", "-Wno-unused-parameter", + "-Wno-unused-private-field", ], static_libs: ["rmidevice"], } diff --git a/rmi4update/firmware_image.cpp b/rmi4update/firmware_image.cpp index babce56..6cc18c0 100644..100755 --- a/rmi4update/firmware_image.cpp +++ b/rmi4update/firmware_image.cpp @@ -21,6 +21,7 @@ #include <stdint.h> #include <stdlib.h> +#include "rmidevice.h" #include "firmware_image.h" using namespace std; @@ -43,6 +44,66 @@ 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 FLASH_CONFIG_CONTAINER: + m_flashConfigData = content; + m_flashConfigSize = 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) @@ -120,6 +181,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..3ce1c59 100644..100755 --- 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: @@ -54,9 +101,11 @@ public: unsigned long deviceConfigSize); unsigned char * GetFirmwareData() { return m_firmwareData; } unsigned char * GetConfigData() { return m_configData; } + unsigned char * GetFlashConfigData() { return m_flashConfigData; } unsigned char * GetLockdownData() { return m_lockdownData; } 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; } bool HasIO() { return m_io; } @@ -65,11 +114,13 @@ public: private: unsigned long Checksum(unsigned short * data, unsigned long len); void PrintHeaderInfo(); + void ParseHierarchicalImg(); // BL_V7 private: unsigned long m_checksum; unsigned long m_firmwareSize; unsigned long m_configSize; + unsigned long m_flashConfigSize; unsigned long m_lockdownSize; long m_imageSize; unsigned long m_firmwareBuildID; @@ -81,8 +132,10 @@ private: unsigned char * m_firmwareData; unsigned char * m_configData; + unsigned char * m_flashConfigData; 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 11146e1..a710764 100644..100755 --- a/rmi4update/main.cpp +++ b/rmi4update/main.cpp @@ -32,20 +32,22 @@ #include "rmi4update.h" #define VERSION_MAJOR 1 -#define VERSION_MINOR 2 -#define VERSION_SUBMINOR 0 +#define VERSION_MINOR 3 +#define VERSION_SUBMINOR 5 -#define RMI4UPDATE_GETOPTS "hfd:plv" +#define RMI4UPDATE_GETOPTS "hfd:t:pclv" void printHelp(const char *prog_name) { fprintf(stdout, "Usage: %s [OPTIONS] FIRMWAREFILE\n", prog_name); - fprintf(stdout, "\t-h, --help\tPrint this message\n"); - fprintf(stdout, "\t-f, --force\tForce updating firmware even it the image provided is older\n\t\t\tthen the current firmware on the device.\n"); - fprintf(stdout, "\t-d, --device\thidraw device file associated with the device being updated.\n"); - fprintf(stdout, "\t-p, --fw-props\tPrint the firmware properties.\n"); - fprintf(stdout, "\t-l, --lockdown\tPerform lockdown.\n"); - fprintf(stdout, "\t-v, --version\tPrint version number.\n"); + fprintf(stdout, "\t-h, --help\t\tPrint this message\n"); + fprintf(stdout, "\t-f, --force\t\tForce updating firmware even it the image provided is older\n\t\t\t\tthen the current firmware on the device.\n"); + fprintf(stdout, "\t-d, --device\t\thidraw device file associated with the device being updated.\n"); + fprintf(stdout, "\t-p, --fw-props\t\tPrint the firmware properties.\n"); + fprintf(stdout, "\t-c, --config-id\t\tPrint the config id.\n"); + fprintf(stdout, "\t-l, --lockdown\t\tPerform lockdown.\n"); + fprintf(stdout, "\t-v, --version\t\tPrint version number.\n"); + fprintf(stdout, "\t-t, --device-type\tFilter by device type [touchpad or touchscreen].\n"); } void printVersion() @@ -54,24 +56,7 @@ void printVersion() VERSION_MAJOR, VERSION_MINOR, VERSION_SUBMINOR); } -int UpdateDevice(FirmwareImage & image, bool force, bool performLockdown, const char * deviceFile) -{ - HIDDevice rmidevice; - int rc; - - rc = rmidevice.Open(deviceFile); - if (rc) - return rc; - - RMI4Update update(rmidevice, image); - rc = update.UpdateFirmware(force, performLockdown); - if (rc != UPDATE_SUCCESS) - return rc; - - return rc; -} - -int GetFirmwareProps(const char * deviceFile, std::string &props) +int GetFirmwareProps(const char * deviceFile, std::string &props, bool configid) { HIDDevice rmidevice; int rc = UPDATE_SUCCESS; @@ -84,12 +69,16 @@ int GetFirmwareProps(const char * deviceFile, std::string &props) rmidevice.ScanPDT(0x1); rmidevice.QueryBasicProperties(); - ss << rmidevice.GetFirmwareVersionMajor() << "." - << rmidevice.GetFirmwareVersionMinor() << "." - << std::hex << rmidevice.GetFirmwareID(); + if (configid) { + ss << std::hex << rmidevice.GetConfigID(); + } else { + ss << rmidevice.GetFirmwareVersionMajor() << "." + << rmidevice.GetFirmwareVersionMinor() << "." + << rmidevice.GetFirmwareID(); - if (rmidevice.InBootloader()) - ss << " bootloader"; + if (rmidevice.InBootloader()) + ss << " bootloader"; + } props = ss.str(); @@ -110,14 +99,17 @@ int main(int argc, char **argv) {"force", 0, NULL, 'f'}, {"device", 1, NULL, 'd'}, {"fw-props", 0, NULL, 'p'}, + {"config-id", 0, NULL, 'c'}, {"lockdown", 0, NULL, 'l'}, {"version", 0, NULL, 'v'}, + {"device-type", 1, NULL, 't'}, {0, 0, 0, 0}, }; - struct dirent * devDirEntry; - DIR * devDir; bool printFirmwareProps = false; + bool printConfigid = false; bool performLockdown = false; + HIDDevice device; + enum RMIDeviceType deviceType = RMI_DEVICE_TYPE_ANY; while ((opt = getopt_long(argc, argv, RMI4UPDATE_GETOPTS, long_options, &index)) != -1) { switch (opt) { @@ -133,9 +125,19 @@ int main(int argc, char **argv) case 'p': printFirmwareProps = true; break; + case 'c': + printFirmwareProps = true; + printConfigid = true; + break; case 'l': performLockdown = true; break; + case 't': + if (!strcasecmp((const char *)optarg, "touchpad")) + deviceType = RMI_DEVICE_TYPE_TOUCHPAD; + else if (!strcasecmp((const char *)optarg, "touchscreen")) + deviceType = RMI_DEVICE_TYPE_TOUCHSCREEN; + break; case 'v': printVersion(); return 0; @@ -152,7 +154,7 @@ int main(int argc, char **argv) fprintf(stderr, "Specifiy which device to query\n"); return 1; } - rc = GetFirmwareProps(deviceName, props); + rc = GetFirmwareProps(deviceName, props, printConfigid); if (rc) { fprintf(stderr, "Failed to read properties from device: %s\n", update_err_to_string(rc)); return 1; @@ -175,35 +177,25 @@ int main(int argc, char **argv) } if (deviceName) { - rc = UpdateDevice(image, force, performLockdown, deviceName); - - return rc; - } else { - char deviceFile[PATH_MAX]; - bool found = false; - - devDir = opendir("/dev"); - if (!devDir) - return -1; - - while ((devDirEntry = readdir(devDir)) != NULL) { - if (strstr(devDirEntry->d_name, "hidraw")) { - char rawDevice[PATH_MAX]; - strncpy(rawDevice, devDirEntry->d_name, PATH_MAX); - snprintf(deviceFile, PATH_MAX, "/dev/%s", devDirEntry->d_name); - rc = UpdateDevice(image, force, performLockdown, deviceFile); - if (rc != 0) { - continue; - } else { - found = true; - break; - } - } + rc = device.Open(deviceName); + if (rc) { + fprintf(stderr, "%s: failed to initialize rmi device (%d): %s\n", argv[0], errno, + strerror(errno)); + return 1; } - closedir(devDir); + } else { + if (!device.FindDevice(deviceType)) + return 1; + } + - if (!found) - return rc; + RMI4Update update(device, image); + rc = update.UpdateFirmware(force, performLockdown); + + if (rc != UPDATE_SUCCESS) + { + device.Reset(); + return 1; } return 0; diff --git a/rmi4update/rmi4update.cpp b/rmi4update/rmi4update.cpp index 6c267bc..19eadb5 100644..100755 --- a/rmi4update/rmi4update.cpp +++ b/rmi4update/rmi4update.cpp @@ -23,7 +23,8 @@ #include <string.h> #include <stdlib.h> #include <errno.h> - +#include <fcntl.h> +#include <linux/input.h> #include "rmi4update.h" #define RMI_F34_QUERY_SIZE 7 @@ -58,6 +59,7 @@ #define RMI_F34_ENABLE_WAIT_MS 300 #define RMI_F34_ERASE_WAIT_MS (5 * 1000) +#define RMI_F34_ERASE_V8_WAIT_MS (10000) #define RMI_F34_IDLE_WAIT_MS 500 /* Most recent device status event */ @@ -67,6 +69,9 @@ /* The device has lost its configuration for some reason. */ #define RMI_F01_STATUS_UNCONFIGURED(status) (!!((status) & 0x80)) +/* Indicates that flash programming is enabled V7(bootloader mode). */ +#define RMI_F01_STATUS_BOOTLOADER_v7(status) (!!((status) & 0x80)) + /* * Sleep mode controls power management on the device and affects all * functions of the device. @@ -91,7 +96,6 @@ int RMI4Update::UpdateFirmware(bool force, bool performLockdown) long long int duration_us = 0; int rc; const unsigned char eraseAll = RMI_F34_ERASE_ALL; - rc = FindUpdateFunctions(); if (rc != UPDATE_SUCCESS) return rc; @@ -119,15 +123,65 @@ 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; - rc = EnterFlashProgramming(); - if (rc != UPDATE_SUCCESS) { - fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); - goto reset; + if (m_f34.GetFunctionVersion() == 0x02) { + fprintf(stdout, "Enable Flash V7+...\n"); + rc = EnterFlashProgrammingV7(); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + goto reset; + } + fprintf(stdout, "Enable Flash done V7+...\n"); + + 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; + } + + } else { + rc = EnterFlashProgramming(); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + goto reset; + } } if (performLockdown && m_unlocked) { @@ -151,7 +205,6 @@ int RMI4Update::UpdateFirmware(bool force, bool performLockdown) fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); goto reset; } - } rc = WriteBootloaderID(); @@ -208,7 +261,24 @@ int RMI4Update::UpdateFirmware(bool force, bool performLockdown) reset: m_device.Reset(); +rebind: m_device.RebindDriver(); + if(!m_device.CheckABSEvent()) + { + goto rebind; + } + + // In order to print out new PR + rc = FindUpdateFunctions(); + if (rc != UPDATE_SUCCESS) + return rc; + + rc = m_device.QueryBasicProperties(); + if (rc < 0) + return UPDATE_FAIL_QUERY_BASIC_PROPERTIES; + fprintf(stdout, "Device Properties:\n"); + m_device.PrintProperties(); + return rc; } @@ -239,6 +309,204 @@ 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); + } + + // Initialize as NULL here to avoid segmentation fault. + m_partitionConfig = NULL; + m_partitionCore = NULL; + m_partitionGuest = NULL; + + /* 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 ? m_partitionCore->partition_len : 0; + m_configBlockCount = m_partitionConfig ? m_partitionConfig->partition_len : 0; + m_guestBlockCount = m_partitionGuest ? m_partitionGuest->partition_len : 0; + 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 +516,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 +635,530 @@ 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); + + // Sleep 100 ms and wait for attention. + 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::WriteCoreConfigV7() +{ + 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)) { + return UPDATE_FAIL_READ_F34_QUERIES; + } + + offset += write_size; + left_bytes -= write_size; + free(data_temp); + } while (left_bytes); + + // Wait for attention. + 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::WriteFlashConfigV7() +{ + 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; + unsigned short FlashConfigBlockCount; + + /* calculate the count */ + partition_id = FLASH_CONFIG_PARTITION; + + FlashConfigBlockCount = m_firmwareImage.GetFlashConfigSize() / m_blockSize; + + remain_block = (FlashConfigBlockCount % m_payloadLength); + transaction_count = (FlashConfigBlockCount / 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.GetFlashConfigData() + 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); + + // Wair for attention. + 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::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]; + if(m_bootloaderID[1] == 8){ + /* Set Command to Erase AP for BL8*/ + erase_cmd[5] = (unsigned char)CMD_V7_ERASE_AP; + } else { + /* Set Command to Erase AP for BL7*/ + 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; + if(m_bootloaderID[1] == 8){ + // 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 + if(m_bootloaderID[1] == 8){ + // Wait for attention for BL8 device. + 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; + } + + if(m_bootloaderID[1] == 7){ + // For BL7, we need erase config partition. + fprintf(stdout, "Start to erase config\n"); + erase_cmd[0] = CORE_CONFIG_PARTITION; + erase_cmd[6] = m_bootloaderID[0]; + erase_cmd[7] = m_bootloaderID[1]; + 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); + + rc = WaitForIdle(RMI_F34_ERASE_WAIT_MS, true); + 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::EnterFlashProgrammingV7() +{ + int rc; + unsigned char f34_status; + rc = m_device.Read(m_f34.GetDataBase(), &f34_status, sizeof(unsigned char)); + m_inBLmode = f34_status & 0x80; + if(!m_inBLmode){ + fprintf(stdout, "Not in BL mode, going to BL mode...\n"); + 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; + + rc = WaitForIdle(RMI_F34_ENABLE_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 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; + + } else + fprintf(stdout, "Already in BL mode, skip...\n"); + + if(m_device.GetDeviceType() != RMI_DEVICE_TYPE_TOUCHPAD) { + // workaround for touchscreen only + fprintf(stdout, "Erase in BL mode\n"); + rc = EraseFirmwareV7(); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + return UPDATE_FAIL_ERASE_ALL; + } + fprintf(stdout, "Erase in BL mode end\n"); + 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; @@ -381,7 +1175,10 @@ int RMI4Update::EnterFlashProgramming() return UPDATE_FAIL_ENABLE_FLASH_PROGRAMMING; Sleep(RMI_F34_ENABLE_WAIT_MS); - m_device.RebindDriver(); + if(m_device.GetDeviceType() != RMI_DEVICE_TYPE_TOUCHPAD) { + fprintf(stdout, "not TouchPad, rebind driver here\n"); + m_device.RebindDriver(); + } rc = WaitForIdle(0); if (rc != UPDATE_SUCCESS) return UPDATE_FAIL_NOT_IN_IDLE_STATE; @@ -398,8 +1195,15 @@ int RMI4Update::EnterFlashProgramming() if (rc != 1) return UPDATE_FAIL_READ_DEVICE_STATUS; - if (!RMI_F01_STATUS_BOOTLOADER(m_deviceStatus)) - return UPDATE_FAIL_DEVICE_NOT_IN_BOOTLOADER; + if(m_f34.GetFunctionVersion() > 0x1){ + if (!RMI_F01_STATUS_BOOTLOADER_v7(m_deviceStatus)) + return UPDATE_FAIL_DEVICE_NOT_IN_BOOTLOADER; + fprintf(stdout, "Already in BL mode V7\n"); + } else { + if (!RMI_F01_STATUS_BOOTLOADER(m_deviceStatus)) + return UPDATE_FAIL_DEVICE_NOT_IN_BOOTLOADER; + fprintf(stdout, "Already in BL mode\n"); + } rc = ReadF34Queries(); if (rc != UPDATE_SUCCESS) @@ -487,7 +1291,7 @@ int RMI4Update::WaitForIdle(int timeout_ms, bool readF34OnSucess) tv.tv_usec = (timeout_ms % 1000) * 1000; rc = m_device.WaitForAttention(&tv, m_f34.GetInterruptMask()); - if (rc == -ETIMEDOUT) + if (rc == -ETIMEDOUT){ /* * If for some reason we are not getting attention reports for HID devices * then we can still continue after the timeout and read F34 status @@ -495,7 +1299,8 @@ int RMI4Update::WaitForIdle(int timeout_ms, bool readF34OnSucess) * will be slow. If this message shows up a lot then something is wrong * with receiving attention reports and that should be fixed. */ - fprintf(stderr, "Timed out waiting for attn report\n"); + fprintf(stderr, "RMI4Update::WaitForIdle Timed out waiting for attn report\n"); + } } if (rc <= 0 || readF34OnSucess) { @@ -505,18 +1310,18 @@ int RMI4Update::WaitForIdle(int timeout_ms, bool readF34OnSucess) if (!m_f34Status && !m_f34Command) { if (!m_programEnabled) { - fprintf(stderr, "Bootloader is idle but program_enabled bit isn't set.\n"); + fprintf(stderr, "RMI4Update::WaitForIdle Bootloader is idle but program_enabled bit isn't set.\n"); return UPDATE_FAIL_PROGRAMMING_NOT_ENABLED; } else { return UPDATE_SUCCESS; } } - - fprintf(stderr, "ERROR: Waiting for idle status.\n"); - fprintf(stderr, "Command: %#04x\n", m_f34Command); - fprintf(stderr, "Status: %#04x\n", m_f34Status); - fprintf(stderr, "Enabled: %d\n", m_programEnabled); - fprintf(stderr, "Idle: %d\n", !m_f34Command && !m_f34Status); + fprintf(stderr, "RMI4Update::WaitForIdle\n"); + fprintf(stderr, " ERROR: Waiting for idle status.\n"); + fprintf(stderr, " Command: %#04x\n", m_f34Command); + fprintf(stderr, " Status: %#04x\n", m_f34Status); + fprintf(stderr, " Enabled: %d\n", m_programEnabled); + fprintf(stderr, " Idle: %d\n", !m_f34Command && !m_f34Status); return UPDATE_FAIL_NOT_IN_IDLE_STATE; } diff --git a/rmi4update/rmi4update.h b/rmi4update/rmi4update.h index eaad0f6..b9de4ec 100644..100755 --- a/rmi4update/rmi4update.h +++ b/rmi4update/rmi4update.h @@ -23,20 +23,157 @@ #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: RMI4Update(RMIDevice & device, FirmwareImage & firmwareImage) : m_device(device), m_firmwareImage(firmwareImage), m_writeBlockWithCmd(true) - {} + { + m_IsErased = false; + } int UpdateFirmware(bool force = false, bool performLockdown = false); 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 WriteCoreConfigV7(); + int WriteFlashConfigV7(); int EnterFlashProgramming(); int WriteBlocks(unsigned char *block, unsigned short count, unsigned char cmd); int WaitForIdle(int timeout_ms, bool readF34OnSucess = true); @@ -66,8 +203,24 @@ 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; + + bool m_IsErased; }; #endif // _RMI4UPDATE_H_ diff --git a/rmi4update/updateutil.cpp b/rmi4update/updateutil.cpp index df070a6..1d654cd 100644 --- a/rmi4update/updateutil.cpp +++ b/rmi4update/updateutil.cpp @@ -57,29 +57,3 @@ const char * update_err_to_string(int err) { return update_error_str[err]; } - -unsigned long extract_long(const unsigned char *data) -{ - return (unsigned long)data [0] - + (unsigned long)data [1] * 0x100 - + (unsigned long)data [2] * 0x10000 - + (unsigned long)data [3] * 0x1000000; -} - -unsigned short extract_short(const unsigned char *data) -{ - return (unsigned long)data [0] - + (unsigned long)data [1] * 0x100; -} - -const char * StripPath(const char * path, ssize_t size) -{ - int i; - const char * str; - - for (i = size - 1, str = &path[size - 1]; i > 0; --i, --str) - if (path[i - 1] == '/') - break; - - return str; -}
\ No newline at end of file diff --git a/rmi4update/updateutil.h b/rmi4update/updateutil.h index 6907781..59f1a08 100644 --- a/rmi4update/updateutil.h +++ b/rmi4update/updateutil.h @@ -54,8 +54,4 @@ enum update_error { const char * update_err_to_string(int err); -unsigned long extract_long(const unsigned char *data); -unsigned short extract_short(const unsigned char *data); -const char * StripPath(const char * path, ssize_t size); - #endif // _UPDATEUTIL_H_
\ No newline at end of file |