189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos/* 289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos * Copyright 2014 Intel Corporation 389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos * 489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos * Licensed under the Apache License, Version 2.0 (the "License"); 589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos * you may not use this file except in compliance with the License. 689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos * You may obtain a copy of the License at 789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos * 889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos * http://www.apache.org/licenses/LICENSE-2.0 989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos * 1089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos * Unless required by applicable law or agreed to in writing, software 1189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos * distributed under the License is distributed on an "AS IS" BASIS, 1289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos * See the License for the specific language governing permissions and 1489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos * limitations under the License. 1589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos */ 1689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 17ee118cf15b62f076ae262fea80f77c32fa3695d6Elliott Hughes#include <errno.h> 1889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#include <stdio.h> 1989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#include <unistd.h> 2089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#include <stdbool.h> 21deaaf79a745176e24a12b55cbf0f5e74948e10dfElliott Hughes#include <stdlib.h> 22deaaf79a745176e24a12b55cbf0f5e74948e10dfElliott Hughes#include <string.h> 2389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#include <sys/types.h> 2489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#include <sys/stat.h> 2589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#include <fcntl.h> 2689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#include <cutils/properties.h> 2789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#include <sys/mman.h> 287a16fb337b8ecfe31e1b1a28616059952f49b49dTianjie Xu 2926d1d7701cc2945c29f0d8a1ee6e33c4b5d70130Tianjie Xu#include <memory> 307a16fb337b8ecfe31e1b1a28616059952f49b49dTianjie Xu#include <string> 317a16fb337b8ecfe31e1b1a28616059952f49b49dTianjie Xu#include <vector> 327a16fb337b8ecfe31e1b1a28616059952f49b49dTianjie Xu 3389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#include "fw_version_check.h" 3489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#include "edify/expr.h" 3589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 3689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#define FORCE_RW_OPT "0" 3789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#define BOOT_IFWI_SIZE 0x400000 3889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#define BOOT_UMIP_SIZE 0x10000 3989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#define BOOT_UMIP_SECTOR_SIZE 0x200 4089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#define BOOT_UMIP_XOR_OFFSET 0x7 4189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#define BOOT_UMIP_3GPP_OFFSET 0x76F 4289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#define BOOT_IFWI_XOR_OFFSET 0x0112d8 4389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#define BOOT_DNX_TIMEOUT_OFFSET 0x400 4489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#define IFWI_OFFSET 0 4589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#define TOKEN_UMIP_AREA_OFFSET 0x4000 4689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#define TOKEN_UMIP_AREA_SIZE 0x2C00 4789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#define FILE_PATH_SIZE 64 4889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos#define IFWI_TYPE_LSH 12 4989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 5089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenosstatic void dump_fw_versions(struct firmware_versions *v) 5189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos{ 5289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "Image FW versions:\n"); 5389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, " ifwi: %04X.%04X\n", v->ifwi.major, v->ifwi.minor); 5489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "---- components ----\n"); 5589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, " scu: %04X.%04X\n", v->scu.major, v->scu.minor); 5689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, " hooks/oem: %04X.%04X\n", v->valhooks.major, v->valhooks.minor); 5789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, " ia32: %04X.%04X\n", v->ia32.major, v->ia32.minor); 5889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, " chaabi: %04X.%04X\n", v->chaabi.major, v->chaabi.minor); 5989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, " mIA: %04X.%04X\n", v->mia.major, v->mia.minor); 6089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos} 6189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 623ed0cf2c1acc8ab7b94b720fe2b414ec445e142cTao Baostatic int force_rw(const char *name) { 6389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos int ret, fd; 6489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 6589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fd = open(name, O_WRONLY); 6689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (fd < 0) { 6789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "force_ro(): failed to open %s\n", name); 6889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return fd; 6989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 7089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 7189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos ret = write(fd, FORCE_RW_OPT, sizeof(FORCE_RW_OPT)); 7289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (ret <= 0) { 7389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "force_ro(): failed to write %s\n", name); 7489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos close(fd); 7589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return ret; 7689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 7789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 7889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos close(fd); 7989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return 0; 8089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos} 8189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 8289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenosint check_ifwi_file_scu_emmc(void *data, size_t size) 8389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos{ 8489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos struct firmware_versions dev_fw_rev, img_fw_rev; 8589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 8689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (get_image_fw_rev(data, size, &img_fw_rev)) { 8789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "Coudn't extract FW version data from image\n"); 8889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return -1; 8989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 9089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 9189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos dump_fw_versions(&img_fw_rev); 9289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (get_current_fw_rev(&dev_fw_rev)) { 9389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "Couldn't query existing IFWI version\n"); 9489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return -1; 9589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 9689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, 9789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos "Attempting to flash ifwi image version %04X.%04X over ifwi current version %04X.%04X\n", 9889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos img_fw_rev.ifwi.major, img_fw_rev.ifwi.minor, dev_fw_rev.ifwi.major, dev_fw_rev.ifwi.minor); 9989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 10089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (img_fw_rev.ifwi.major != dev_fw_rev.ifwi.major) { 10189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, 10289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos "IFWI FW Major version numbers (file=%04X current=%04X) don't match, Update abort.\n", 10389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos img_fw_rev.ifwi.major, dev_fw_rev.ifwi.major); 104838d53c304ff966d4170776681d2ac733940ecbcSylvain Chouleur return -1; 10589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 10689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 10789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return 1; 10889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos} 10989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 11089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenosstatic uint32_t xor_compute(char *ptr, uint32_t size) 11189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos{ 1123ed0cf2c1acc8ab7b94b720fe2b414ec445e142cTao Bao uint32_t val = 0; 11389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos uint32_t i; 11489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 11589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos for (i = 0; i < size; i+=4) 1163ed0cf2c1acc8ab7b94b720fe2b414ec445e142cTao Bao val = val ^ *(uint32_t *)(ptr + i); 11789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 1183ed0cf2c1acc8ab7b94b720fe2b414ec445e142cTao Bao return val; 11989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos} 12089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 1213ed0cf2c1acc8ab7b94b720fe2b414ec445e142cTao Baostatic uint8_t xor_factorize(uint32_t val) 12289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos{ 1233ed0cf2c1acc8ab7b94b720fe2b414ec445e142cTao Bao return (uint8_t)((val & 0xff) ^ ((val >> 8) & 0xff) ^ ((val >> 16) & 0xff) ^ ((val >> 24) & 0xff)); 12489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos} 12589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 12689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenosstatic void xor_update(char *ptr) 12789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos{ 12889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos uint16_t i; 1293ed0cf2c1acc8ab7b94b720fe2b414ec445e142cTao Bao uint32_t val; 13089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 13189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos /* update UMIP xor of sector 2 to 127 */ 13289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos for (i = 2; i < 128; i++) { 1333ed0cf2c1acc8ab7b94b720fe2b414ec445e142cTao Bao val = xor_compute(ptr + i * BOOT_UMIP_SECTOR_SIZE, BOOT_UMIP_SECTOR_SIZE); 1343ed0cf2c1acc8ab7b94b720fe2b414ec445e142cTao Bao *(uint32_t *)(ptr + 4 * i) = val; 13589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 13689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 13789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos /* update UMIP xor */ 13889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos *(ptr + BOOT_UMIP_XOR_OFFSET) = 0; 1393ed0cf2c1acc8ab7b94b720fe2b414ec445e142cTao Bao val= xor_compute(ptr, BOOT_UMIP_SIZE); 1403ed0cf2c1acc8ab7b94b720fe2b414ec445e142cTao Bao *(ptr + BOOT_UMIP_XOR_OFFSET) = xor_factorize(val); 14189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 14289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos /* update IFWI xor */ 14389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos *(uint32_t *)(ptr + BOOT_IFWI_XOR_OFFSET) = 0x0; 1443ed0cf2c1acc8ab7b94b720fe2b414ec445e142cTao Bao val= xor_compute(ptr, BOOT_IFWI_SIZE); 1453ed0cf2c1acc8ab7b94b720fe2b414ec445e142cTao Bao *(uint32_t *)(ptr + BOOT_IFWI_XOR_OFFSET) = val; 14689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos} 14789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 14889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenosstatic int write_umip_emmc(uint32_t addr_offset, void *data, size_t size) 14989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos{ 15089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos int boot_fd = 0; 15189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos int boot_index; 15289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos char boot_partition[FILE_PATH_SIZE]; 15389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos char boot_partition_force_ro[FILE_PATH_SIZE]; 15489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos char *ptr; 15589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos char *token_data; 15689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 15789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (addr_offset == IFWI_OFFSET) { 1583ed0cf2c1acc8ab7b94b720fe2b414ec445e142cTao Bao token_data = reinterpret_cast<char *>(malloc(TOKEN_UMIP_AREA_SIZE)); 15989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (!token_data) { 16089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "write_umip_emmc: Malloc error\n"); 16189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return -1; 16289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 16389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 16489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (size > BOOT_IFWI_SIZE) { 16589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "write_umip_emmc: Truncating last %d bytes from the IFWI\n", 16689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos (size - BOOT_IFWI_SIZE)); 16789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos /* Since the last 144 bytes are the FUP header which are not required,*/ 16889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos /* we truncate it to fit into the boot partition. */ 16989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos size = BOOT_IFWI_SIZE; 17089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 17189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 17289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 17389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos for (boot_index = 0; boot_index < 2; boot_index++) { 17489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos snprintf(boot_partition, FILE_PATH_SIZE, "/dev/block/mmcblk0boot%d", boot_index); 17589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos snprintf(boot_partition_force_ro, FILE_PATH_SIZE, "/sys/block/mmcblk0boot%d/force_ro", boot_index); 17689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 17789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (force_rw(boot_partition_force_ro)) { 17889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "write_umip_emmc: unable to force_ro %s\n", boot_partition); 17989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos goto err_boot1; 18089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 18189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos boot_fd = open(boot_partition, O_RDWR); 18289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (boot_fd < 0) { 18389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "write_umip_emmc: failed to open %s\n", boot_partition); 18489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos goto err_boot1; 18589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 18689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 18789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos ptr = (char *)mmap(NULL, BOOT_IFWI_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, boot_fd, 0); 18889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (ptr == MAP_FAILED) { 18989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "write_umip_emmc: mmap failed on boot%d with error : %s\n", boot_index, strerror(errno)); 19089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos goto err_boot1; 19189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 19289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 19389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (addr_offset == IFWI_OFFSET) 19489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos memcpy(token_data, ptr + TOKEN_UMIP_AREA_OFFSET, TOKEN_UMIP_AREA_SIZE); 19589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 19689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos /* Write the data */ 19789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (addr_offset + size <= BOOT_IFWI_SIZE) 19889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (data == NULL) 19989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos memset(ptr + addr_offset, 0, size); 20089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos else 20189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos memcpy(ptr + addr_offset, data, size); 20289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos else { 20389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "write_umip_emmc: write failed\n"); 20489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos goto err_boot2; 20589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 20689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 20789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (addr_offset == IFWI_OFFSET) 20889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos memcpy(ptr + TOKEN_UMIP_AREA_OFFSET, token_data, TOKEN_UMIP_AREA_SIZE); 20989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 21089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos /* Compute and write xor */ 21189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos xor_update(ptr); 21289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 21389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos munmap(ptr, BOOT_IFWI_SIZE); 21489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos close(boot_fd); 21589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 21689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 21789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (addr_offset == IFWI_OFFSET) 21889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos free(token_data); 21989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return 0; 22089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 22189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenoserr_boot2: 22289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos munmap(ptr, BOOT_IFWI_SIZE); 22389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 22489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenoserr_boot1: 22589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (addr_offset == IFWI_OFFSET) 22689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos free(token_data); 22789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos close(boot_fd); 22889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return -1; 22989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos} 23089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 23189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenosstatic int readbyte_umip_emmc(uint32_t addr_offset) 23289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos{ 23389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos int boot_fd = 0; 23489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos char *ptr; 23589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos int value = 0; 23689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 23789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (force_rw("/sys/block/mmcblk0boot0/force_ro")) { 23889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "read_umip_emmc: unable to force_ro\n"); 23989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos goto err_boot1; 24089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 24189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos boot_fd = open("/dev/block/mmcblk0boot0", O_RDWR); 24289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (boot_fd < 0) { 24389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "read_umip_emmc: failed to open /dev/block/mmcblk0boot0\n"); 24489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos goto err_boot1; 24589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 24689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 24789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos ptr = (char *)mmap(NULL, BOOT_UMIP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, boot_fd, 0); 24889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (ptr == MAP_FAILED) { 24989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "read_umip_emmc: mmap failed on boot0 with error : %s\n", strerror(errno)); 25089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos goto err_boot1; 25189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 25289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 25389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos /* Read the data */ 25489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (addr_offset < BOOT_UMIP_SIZE) 25589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos value = (int)*(ptr + addr_offset); 25689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos else { 25789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fprintf(stderr, "read_umip_emmc: read failed\n"); 25889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos goto err_boot2; 25989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 26089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 26189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos munmap(ptr, BOOT_UMIP_SIZE); 26289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos close(boot_fd); 26389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 26489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return value; 26589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 26689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenoserr_boot2: 26789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos munmap(ptr, BOOT_UMIP_SIZE); 26889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 26989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenoserr_boot1: 27089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos close(boot_fd); 27189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return -1; 27289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos} 27389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 27489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenosint update_ifwi_file_scu_emmc(void *data, size_t size) 27589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos{ 27689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return write_umip_emmc(IFWI_OFFSET, data, size); 27789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos} 27889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 27989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenosint flash_ifwi_scu_emmc(void *data, unsigned size) 28089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos{ 28189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos int ret; 28289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 28389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos ret = check_ifwi_file_scu_emmc(data, size); 28489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (ret > 0) 28589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return update_ifwi_file_scu_emmc(data, size); 28689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 28789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return ret; 28889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos} 28989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 29026d1d7701cc2945c29f0d8a1ee6e33c4b5d70130Tianjie XuValue* FlashIfwiFuguFn(const char *name, State * state, 29126d1d7701cc2945c29f0d8a1ee6e33c4b5d70130Tianjie Xu const std::vector<std::unique_ptr<Expr>>& argv) { 29289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos Value *ret = NULL; 29389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos unsigned char *buffer = NULL; 29489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos int ifwi_size; 29589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos FILE *f = NULL; 29689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 29726d1d7701cc2945c29f0d8a1ee6e33c4b5d70130Tianjie Xu if (argv.size() != 1) { 29826d1d7701cc2945c29f0d8a1ee6e33c4b5d70130Tianjie Xu ErrorAbort(state, "%s() expected 1 arg, got %zu", name, argv.size()); 29989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return NULL; 30089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 3017a16fb337b8ecfe31e1b1a28616059952f49b49dTianjie Xu std::vector<std::string> args; 30226d1d7701cc2945c29f0d8a1ee6e33c4b5d70130Tianjie Xu if (!ReadArgs(state, argv, &args)) { 30389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos ErrorAbort(state, "%s() invalid args ", name); 30489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return NULL; 30589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 3067a16fb337b8ecfe31e1b1a28616059952f49b49dTianjie Xu const std::string& filename = args[0]; 3077a16fb337b8ecfe31e1b1a28616059952f49b49dTianjie Xu if (filename.empty()) { 30889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos ErrorAbort(state, "filename argument to %s can't be empty", name); 3097a16fb337b8ecfe31e1b1a28616059952f49b49dTianjie Xu return nullptr; 31089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 31189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 3127a16fb337b8ecfe31e1b1a28616059952f49b49dTianjie Xu if ((f = fopen(filename.c_str(),"rb")) == NULL) { 3137a16fb337b8ecfe31e1b1a28616059952f49b49dTianjie Xu ErrorAbort(state, "Unable to open file %s: %s ", filename.c_str(), strerror(errno)); 3147a16fb337b8ecfe31e1b1a28616059952f49b49dTianjie Xu return nullptr; 31589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos } 31689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 31789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fseek(f, 0, SEEK_END); 31889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos ifwi_size = ftell(f); 31989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if (ifwi_size < 0) { 32089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos ErrorAbort(state, "Unable to get ifwi_size "); 3217a16fb337b8ecfe31e1b1a28616059952f49b49dTianjie Xu return nullptr; 32289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos }; 32389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fseek(f, 0, SEEK_SET); 32489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 3253ed0cf2c1acc8ab7b94b720fe2b414ec445e142cTao Bao if ((buffer = reinterpret_cast<unsigned char *>(malloc(ifwi_size))) == NULL) { 3269223a5b545f10b5b494790295a0b940e0c8335a6Benoit Fradin ErrorAbort(state, "Unable to alloc ifwi flash buffer of size %d", ifwi_size); 3277a16fb337b8ecfe31e1b1a28616059952f49b49dTianjie Xu return nullptr; 3289223a5b545f10b5b494790295a0b940e0c8335a6Benoit Fradin } 32989c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fread(buffer, ifwi_size, 1, f); 33089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos fclose(f); 33189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 33289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos if(flash_ifwi_scu_emmc(buffer, ifwi_size) !=0) { 33389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos ErrorAbort(state, "Unable to flash ifwi in emmc"); 33489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos free(buffer); 3357a16fb337b8ecfe31e1b1a28616059952f49b49dTianjie Xu return nullptr; 33689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos }; 33789c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 33889c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos free(buffer); 3397a16fb337b8ecfe31e1b1a28616059952f49b49dTianjie Xu ret = StringValue(""); 34089c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 34189c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos return ret; 34289c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos} 34389c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos 34489c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenosvoid Register_librecovery_updater_fugu() { 34589c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos RegisterFunction("fugu.flash_ifwi", FlashIfwiFuguFn); 34689c83d1a6f8a95121f28c3f6c10ef9208aa5923emarie cecile afantenos} 347