From c5357940ab0108b4102442d07825c44d5be0d22f Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Thu, 13 Jun 2013 02:02:53 +0200 Subject: hwstub: major improvement in the stub and the tools Fix the stub in many way to correctly detect the STMP family and act upon that. Drop some unused commands and bump version. Rewrite the tool to allows scripting in lua and load the register description from an XML file using the regtools. Introduce a new tool to load and run code using the hwstub (either binary format or Rockbox additive scramble format). Also switch to an optimise version of the memcpy/move/set functions to correctly handle alignement issue (like writing a full word/half-word when possible for registers which is crucial) Change-Id: Id1d5cfe0b1b47e8b43900d32c5cd6eafae6414f6 --- utils/hwstub/tools/hwemul_tool.c | 558 --------------------------------------- 1 file changed, 558 deletions(-) delete mode 100644 utils/hwstub/tools/hwemul_tool.c (limited to 'utils/hwstub/tools/hwemul_tool.c') diff --git a/utils/hwstub/tools/hwemul_tool.c b/utils/hwstub/tools/hwemul_tool.c deleted file mode 100644 index d75cd7a957..0000000000 --- a/utils/hwstub/tools/hwemul_tool.c +++ /dev/null @@ -1,558 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2012 by Amaury Pouly - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "hwemul.h" -#include -#include -#include -#include -#include -#include -#include - -bool g_quiet = false; -struct hwemul_device_t hwdev; -struct hwemul_soc_t *cur_soc = NULL; - -void print_log(struct hwemul_device_t *hwdev) -{ - do - { - char buffer[128]; - int length = hwemul_get_log(hwdev, buffer, sizeof(buffer) - 1); - if(length <= 0) - break; - buffer[length] = 0; - printf("%s", buffer); - }while(1); -} - -int print_help() -{ - printf("Commands:\n"); - printf(" help\t\tDisplay this help\n"); - printf(" call \tCall address \n"); - printf(" quit\t\tQuit this session\n"); - printf(" read32 \tRead a 32-bit word at \n"); - printf(" write32 \tRead the 32-bit word at \n"); - printf(" read \tRead a register by name\n"); - printf(" read .\tRead a register field by name\n"); - printf(" soc \tSelect the soc description to use\n"); - printf(" write \tWrite a register by name\n"); - printf(" write .\tWrite a register field by name\n"); - printf(" NOTE: if the register is SCT variant, no read is performed.\n"); - return 1; -} - -int syntax_error(char *str) -{ - printf("Syntax error at '%s'. Type 'help' to get some help.\n", str); - return 1; -} - -int parse_uint32(char *str, uint32_t *u) -{ - char *end; - *u = strtoul(str, &end, 0); - return *end == 0; -} - -int do_call(uint32_t a) -{ - hwemul_call(&hwdev, a); - return 1; -} - -int parse_call() -{ - char *arg = strtok(NULL, " "); - uint32_t addr; - if(arg && parse_uint32(arg, &addr)) - return do_call(addr); - else - return syntax_error(arg); -} - -int do_read32(uint32_t a) -{ - uint32_t val; - if(hwemul_rw_mem(&hwdev, 1, a, &val, sizeof(val)) == sizeof(val)) - printf("%#x = %#x\n", a, val); - else - printf("read error at %#x\n", a); - return 1; -} - -int parse_read32() -{ - char *arg = strtok(NULL, " "); - uint32_t addr; - if(arg && parse_uint32(arg, &addr)) - return do_read32(addr); - else - return syntax_error(arg); -} - -int do_write32(uint32_t val, uint32_t a) -{ - if(hwemul_rw_mem(&hwdev, 0, a, &val, sizeof(val)) == sizeof(val)) - printf("data written\n"); - else - printf("write error at %#x\n", a); - return 1; -} - -int parse_write32() -{ - char *arg = strtok(NULL, " "); - uint32_t val; - if(!arg || !parse_uint32(arg, &val)) - return syntax_error(arg); - uint32_t addr; - arg = strtok(NULL, " "); - if(arg && parse_uint32(arg, &addr)) - return do_write32(val, addr); - else - return syntax_error(arg); -} - -struct hwemul_soc_t *find_soc_by_name(const char *soc) -{ - struct hwemul_soc_list_t *list = hwemul_get_soc_list(); - for(size_t i = 0; i < list->nr_socs; i++) - if(strcmp(soc, list->socs[i]->name) == 0) - return list->socs[i]; - return NULL; -} - -struct hwemul_soc_reg_t *find_reg_by_name(struct hwemul_soc_t *soc, const char *reg) -{ - for(size_t i = 0; i < soc->nr_regs; i++) - if(strcmp(reg, soc->regs_by_name[i]->name) == 0) - return soc->regs_by_name[i]; - return NULL; -} - -struct hwemul_soc_reg_field_t *find_field_by_name(struct hwemul_soc_reg_t *reg, const char *field) -{ - for(size_t i = 0; i < reg->nr_fields; i++) - if(strcmp(field, reg->fields_by_name[i]->name) == 0) - return reg->fields_by_name[i]; - return NULL; -} - - -int do_read(char *regname) -{ - char *dot = strchr(regname, '.'); - if(dot != NULL) - *dot++ = 0; - if(cur_soc == NULL) - { - printf("No soc selected!\n"); - return 1; - } - struct hwemul_soc_reg_t *reg = find_reg_by_name(cur_soc, regname); - if(reg == NULL) - { - printf("no reg '%s' found\n", regname); - return 1; - } - uint32_t val; - if(hwemul_rw_mem(&hwdev, 1, reg->addr, &val, sizeof(val)) != sizeof(val)) - { - printf("read error at %#x\n", reg->addr); - return 1; - } - if(dot) - { - struct hwemul_soc_reg_field_t *field = find_field_by_name(reg, dot); - if(field == NULL) - { - printf("no field '%s' found\n", dot); - return 1; - } - val >>= field->first_bit; - val &= (1 << (field->last_bit - field->first_bit + 1)) - 1; - printf("%s.%s = %#x\n", regname, dot, val); - } - else - printf("%s = %#x\n", regname, val); - return 1; -} - -int parse_read() -{ - char *arg = strtok(NULL, " "); - if(arg) - return do_read(arg); - else - return syntax_error(arg); -} - -int do_soc(char *soc) -{ - struct hwemul_soc_t *s = find_soc_by_name(soc); - if(s == NULL) - printf("no soc '%s' found\n", soc); - else - cur_soc = s; - return 1; -} - -int parse_soc() -{ - char *arg = strtok(NULL, " "); - if(arg) - return do_soc(arg); - else - return syntax_error(arg); -} - -int do_write(uint32_t val, char *regname) -{ - char *dot = strchr(regname, '.'); - if(dot != NULL) - *dot++ = 0; - if(cur_soc == NULL) - { - printf("No soc selected!\n"); - return 1; - } - struct hwemul_soc_reg_t *reg = find_reg_by_name(cur_soc, regname); - int is_sct = 0; - uint32_t addr_off = 0; - if(reg == NULL) - { - size_t len = strlen(regname); - /* try SCT variant */ - if(strcmp(regname + len - 4, "_SET") == 0) - addr_off = 4; - else if(strcmp(regname + len - 4, "_CLR") == 0) - addr_off = 8; - else if(strcmp(regname + len - 4, "_TOG") == 0) - addr_off = 12; - else - { - printf("no reg '%s' found\n", regname); - return 1; - } - is_sct = 1; - regname[len - 4] = 0; - reg = find_reg_by_name(cur_soc, regname); - if(reg == NULL) - { - printf("no reg '%s' found\n", regname); - return 1; - } - } - if(dot) - { - struct hwemul_soc_reg_field_t *field = find_field_by_name(reg, dot); - if(field == NULL) - { - printf("no field '%s' found\n", dot); - return 1; - } - uint32_t actual_val = 0; - if(!is_sct) - { - if(hwemul_rw_mem(&hwdev, 1, reg->addr, &actual_val, sizeof(actual_val)) != sizeof(actual_val)) - { - printf("read error at %#x\n", reg->addr); - return 1; - } - printf("read %#x at %#x\n", actual_val, reg->addr); - } - uint32_t mask = ((1 << (field->last_bit - field->first_bit + 1)) - 1) << field->first_bit; - printf("mask=%#x\n", mask); - val = (actual_val & ~mask) | ((val << field->first_bit) & mask); - } - printf("write %#x to %#x\n", val, reg->addr + addr_off); - if(hwemul_rw_mem(&hwdev, 0, reg->addr + addr_off, &val, sizeof(val)) != sizeof(val)) - { - printf("write error at %#x\n", reg->addr); - return 1; - } - return 1; -} - -int parse_write() -{ - char *arg = strtok(NULL, " "); - uint32_t val; - if(!arg || !parse_uint32(arg, &val)) - return syntax_error(arg); - arg = strtok(NULL, " "); - if(arg) - return do_write(val, arg); - else - return syntax_error(arg); -} - -int parse_command(char *cmd) -{ - if(strcmp(cmd, "help") == 0) - return print_help(); - if(strcmp(cmd, "quit") == 0) - return 0; - if(strcmp(cmd, "call") == 0) - return parse_call(); - if(strcmp(cmd, "read32") == 0) - return parse_read32(); - if(strcmp(cmd, "write32") == 0) - return parse_write32(); - if(strcmp(cmd, "read") == 0) - return parse_read(); - if(strcmp(cmd, "soc") == 0) - return parse_soc(); - if(strcmp(cmd, "write") == 0) - return parse_write(); - return syntax_error(cmd); -} - -void interactive_mode(void) -{ - rl_bind_key('\t', rl_complete); - while(1) - { - char *input = readline("> "); - if(!input) - break; - add_history(input); - int ret = parse_command(input); - free(input); - if(ret == 0) - break; - } -} - -void usage(void) -{ - printf("hwemul_tool, compiled with hwemul %d.%d.%d\n", - HWEMUL_VERSION_MAJOR, HWEMUL_VERSION_MINOR, HWEMUL_VERSION_REV); - printf("available soc descriptions:"); - for(unsigned i = 0; i < hwemul_get_soc_list()->nr_socs; i++) - printf(" %s", hwemul_get_soc_list()->socs[i]->name); - printf("\n"); - printf("usage: hwemul_tool [options]\n"); - printf("options:\n"); - printf(" --help/-?\tDisplay this help\n"); - printf(" --quiet/-q\tQuiet non-command messages\n"); - exit(1); -} - -int main(int argc, char **argv) -{ - while(1) - { - static struct option long_options[] = - { - {"help", no_argument, 0, '?'}, - {"quiet", no_argument, 0, 'q'}, - {0, 0, 0, 0} - }; - - int c = getopt_long(argc, argv, "?q", long_options, NULL); - if(c == -1) - break; - switch(c) - { - case -1: - break; - case 'q': - g_quiet = true; - break; - case '?': - usage(); - break; - default: - abort(); - } - } - - if(argc - optind != 0) - { - usage(); - return 1; - } - - libusb_context *ctx; - libusb_init(&ctx); - libusb_set_debug(ctx, 3); - - if(!g_quiet) - printf("Looking for device %#04x:%#04x...\n", HWEMUL_USB_VID, HWEMUL_USB_PID); - - libusb_device_handle *handle = libusb_open_device_with_vid_pid(ctx, - HWEMUL_USB_VID, HWEMUL_USB_PID); - if(handle == NULL) - { - printf("No device found\n"); - return 1; - } - - libusb_device *mydev = libusb_get_device(handle); - if(!g_quiet) - { - printf("device found at %d:%d\n", - libusb_get_bus_number(mydev), - libusb_get_device_address(mydev)); - } - hwdev.handle = handle; - if(hwemul_probe(&hwdev)) - { - printf("Cannot probe device!\n"); - return 1; - } - - struct usb_resp_info_version_t ver; - int ret = hwemul_get_info(&hwdev, HWEMUL_INFO_VERSION, &ver, sizeof(ver)); - if(ret != sizeof(ver)) - { - printf("Cannot get version!\n"); - goto Lerr; - } - if(!g_quiet) - printf("Device version: %d.%d.%d\n", ver.major, ver.minor, ver.revision); - - struct usb_resp_info_layout_t layout; - ret = hwemul_get_info(&hwdev, HWEMUL_INFO_LAYOUT, &layout, sizeof(layout)); - if(ret != sizeof(layout)) - { - printf("Cannot get layout: %d\n", ret); - goto Lerr; - } - if(!g_quiet) - { - printf("Device layout:\n"); - printf(" Code: 0x%x (0x%x)\n", layout.oc_code_start, layout.oc_code_size); - printf(" Stack: 0x%x (0x%x)\n", layout.oc_stack_start, layout.oc_stack_size); - printf(" Buffer: 0x%x (0x%x)\n", layout.oc_buffer_start, layout.oc_buffer_size); - } - - struct usb_resp_info_features_t features; - ret = hwemul_get_info(&hwdev, HWEMUL_INFO_FEATURES, &features, sizeof(features)); - if(ret != sizeof(features)) - { - printf("Cannot get features: %d\n", ret); - goto Lerr; - } - if(!g_quiet) - { - printf("Device features:"); - if(features.feature_mask & HWEMUL_FEATURE_LOG) - printf(" log"); - if(features.feature_mask & HWEMUL_FEATURE_MEM) - printf(" mem"); - if(features.feature_mask & HWEMUL_FEATURE_CALL) - printf(" call"); - if(features.feature_mask & HWEMUL_FEATURE_JUMP) - printf(" jump"); - if(features.feature_mask & HWEMUL_FEATURE_AES_OTP) - printf(" aes_otp"); - printf("\n"); - } - - struct usb_resp_info_stmp_t stmp; - ret = hwemul_get_info(&hwdev, HWEMUL_INFO_STMP, &stmp, sizeof(stmp)); - if(ret != sizeof(stmp)) - { - printf("Cannot get stmp: %d\n", ret); - goto Lerr; - } - if(!g_quiet) - { - printf("Device stmp:\n"); - printf(" chip ID: %x (%s)\n", stmp.chipid,hwemul_get_product_string(&stmp)); - printf(" revision: %d (%s)\n", stmp.rev, hwemul_get_rev_string(&stmp)); - printf(" supported: %d\n", stmp.is_supported); - } - - if(!g_quiet) - { - void *rom = malloc(64 * 1024); - ret = hwemul_rw_mem(&hwdev, 1, 0xc0000000, rom, 64 * 1024); - if(ret != 64 * 1024) - { - printf("Cannot read ROM: %d\n", ret); - goto Lerr; - } - - printf("ROM successfully read!\n"); - FILE *f = fopen("rom.bin", "wb"); - fwrite(rom, 64 * 1024, 1, f); - fclose(f); - } - - if(!g_quiet) - { - struct - { - uint8_t iv[16]; - uint8_t data[16]; - } __attribute__((packed)) dcp_test; - - for(int i = 0; i < 16; i++) - dcp_test.iv[i] = rand(); - for(int i = 0; i < 16; i++) - dcp_test.data[i] = rand(); - printf("DCP\n"); - printf(" IN\n"); - printf(" IV:"); - for(int i = 0; i < 16; i++) - printf(" %02x", dcp_test.iv[i]); - printf("\n"); - printf(" IV:"); - for(int i = 0; i < 16; i++) - printf(" %02x", dcp_test.data[i]); - printf("\n"); - - if(!hwemul_aes_otp(&hwdev, &dcp_test, sizeof(dcp_test), HWEMUL_AES_OTP_ENCRYPT)) - { - printf(" OUT\n"); - printf(" IV:"); - for(int i = 0; i < 16; i++) - printf(" %02x", dcp_test.iv[i]); - printf("\n"); - printf(" IV:"); - for(int i = 0; i < 16; i++) - printf(" %02x", dcp_test.data[i]); - printf("\n"); - } - else - printf("DCP error!\n"); - } - - if(!g_quiet) - printf("Starting interactive session. Type 'help' to get help.\n"); - - interactive_mode(); - - Lerr: - if(features.feature_mask & HWEMUL_FEATURE_LOG) - { - if(!g_quiet) - printf("Device log:\n"); - print_log(&hwdev); - } - hwemul_release(&hwdev); - return 1; -} -- cgit v1.2.3