summaryrefslogtreecommitdiffstats
path: root/utils/hwstub/tools/hwemul_tool.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/hwstub/tools/hwemul_tool.c')
-rw-r--r--utils/hwstub/tools/hwemul_tool.c558
1 files changed, 0 insertions, 558 deletions
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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <stdbool.h>
-#include <readline/readline.h>
-#include <readline/history.h>
-
-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 <addr>\tCall address <addr>\n");
- printf(" quit\t\tQuit this session\n");
- printf(" read32 <addr>\tRead a 32-bit word at <addr>\n");
- printf(" write32 <value> <addr>\tRead the 32-bit word <value> at <addr>\n");
- printf(" read <regname>\tRead a register by name\n");
- printf(" read <regname>.<field>\tRead a register field by name\n");
- printf(" soc <socname>\tSelect the soc description to use\n");
- printf(" write <value> <regname>\tWrite a register by name\n");
- printf(" write <value <regname>.<field>\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;
-}