static bool is_hab_enabled(void) { struct imx_sec_config_fuse_t *fuse = (struct imx_sec_config_fuse_t *)&imx_sec_config_fuse; uint32_t reg; int ret; ret = fuse_read(fuse->bank, fuse->word, ®); if (ret) { puts("\nSecure boot fuse read error\n"); return ret; } return (reg & IS_HAB_ENABLED_BIT) == IS_HAB_ENABLED_BIT; }
static int fuse_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { if (offset >= file_size) return 0; if (offset + (off_t) size > file_size) size = file_size - offset; if (size == 0) return 0; ssize_t res_size = 0; int num, num_end; for (;;){ num = offset / part_size; num_end = (offset + size - 1) / part_size; if (num == num_end) break; size_t size_now = (num + 1) * part_size - offset; int res = fuse_read(path, buf, size_now, offset, fi); if (res != size_now){ return 0; } buf += size_now; offset += size_now; size -= size_now; res_size += size_now; } char tmp[NAME_SIZE]; snprintf(tmp, NAME_SIZE, url, num); offset -= num * part_size; int retry; for ( retry = 3; retry; --retry){ static __thread CURL *curl = NULL; if (!curl) curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_URL, tmp); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 120L); curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L); struct curl_buf buf_now ; buf_now.mem = buf; buf_now.size = size; buf_now.used = 0; curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &buf_now); char range[128]; sprintf(range, "%lld-%lld", (my_off_t) offset, (my_off_t) offset + size - 1); curl_easy_setopt(curl, CURLOPT_RANGE, range); CURLcode res = curl_easy_perform(curl); //curl_easy_cleanup(curl); if(res != CURLE_OK) { printf("curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); continue; } if (buf_now.size != buf_now.used){ printf("fuse_read size %llu != used %llu\n", buf_now.size, buf_now.used); continue; } res_size += size; break; } if (!retry) return 0; return res_size; }
static int do_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { const char *op = argc >= 2 ? argv[1] : NULL; int confirmed = argc >= 3 && !strcmp(argv[2], "-y"); u32 bank, word, cnt, val; int ret, i; argc -= 2 + confirmed; argv += 2 + confirmed; if (argc < 2 || strtou32(argv[0], 0, &bank) || strtou32(argv[1], 0, &word)) return CMD_RET_USAGE; if (!strcmp(op, "read")) { if (argc == 2) cnt = 1; else if (argc != 3 || strtou32(argv[2], 0, &cnt)) return CMD_RET_USAGE; printf("Reading bank %u:\n", bank); for (i = 0; i < cnt; i++, word++) { if (!(i % 4)) printf("\nWord 0x%.8x:", word); ret = fuse_read(bank, word, &val); if (ret) goto err; printf(" %.8x", val); } putc('\n'); } else if (!strcmp(op, "sense")) { if (argc == 2) cnt = 1; else if (argc != 3 || strtou32(argv[2], 0, &cnt)) return CMD_RET_USAGE; printf("Sensing bank %u:\n", bank); for (i = 0; i < cnt; i++, word++) { if (!(i % 4)) printf("\nWord 0x%.8x:", word); ret = fuse_sense(bank, word, &val); if (ret) goto err; printf(" %.8x", val); } putc('\n'); } else if (!strcmp(op, "prog")) { if (argc < 3) return CMD_RET_USAGE; for (i = 2; i < argc; i++, word++) { if (strtou32(argv[i], 16, &val)) return CMD_RET_USAGE; printf("Programming bank %u word 0x%.8x to 0x%.8x...\n", bank, word, val); if (!confirmed && !confirm_prog()) return CMD_RET_FAILURE; ret = fuse_prog(bank, word, val); if (ret) goto err; } } else if (!strcmp(op, "override")) { if (argc < 3) return CMD_RET_USAGE; for (i = 2; i < argc; i++, word++) { if (strtou32(argv[i], 16, &val)) return CMD_RET_USAGE; printf("Overriding bank %u word 0x%.8x with " "0x%.8x...\n", bank, word, val); ret = fuse_override(bank, word, val); if (ret) goto err; } } else { return CMD_RET_USAGE; } return 0; err: puts("ERROR\n"); return ret; }