From 5aaf95928be413c77911ed7ad75120142428b57d Mon Sep 17 00:00:00 2001 From: Bartosz Kokoszko Date: Thu, 22 Nov 2018 15:39:55 +0100 Subject: [PATCH] tools: moving rimage and logger to tools directory I've moved rimage and logger (from soft repo) to tools directory. Cmds for building tools: ./autogen.sh ./configure --enable-tools make sudo make install Signed-off-by: Bartosz Kokoszko --- .gitignore | 2 +- Makefile.am | 6 +- README.md | 5 +- configure.ac | 20 +- scripts/rimage-build.sh | 4 +- scripts/tools-build.sh | 28 ++ scripts/xtensa-build-all.sh | 14 +- tools/Makefile.am | 3 + tools/logger/Makefile.am | 8 + tools/logger/convert.c | 368 ++++++++++++++++++ tools/logger/convert.h | 37 ++ tools/logger/logger.c | 236 +++++++++++ {rimage => tools/rimage}/Makefile.am | 0 {rimage => tools/rimage}/cse.c | 0 {rimage => tools/rimage}/cse.h | 0 {rimage => tools/rimage}/css.c | 0 {rimage => tools/rimage}/css.h | 0 {rimage => tools/rimage}/elf.c | 0 {rimage => tools/rimage}/file_format.h | 0 {rimage => tools/rimage}/file_simple.c | 0 {rimage => tools/rimage}/hash.c | 0 {rimage => tools/rimage}/keys/Makefile.am | 0 {rimage => tools/rimage}/keys/README | 0 .../rimage}/keys/otc_private_key.pem | 0 .../rimage}/keys/otc_public_key.pem | 0 {rimage => tools/rimage}/man_apl.c | 0 {rimage => tools/rimage}/man_cnl.c | 0 {rimage => tools/rimage}/man_kbl.c | 0 {rimage => tools/rimage}/manifest.c | 0 {rimage => tools/rimage}/manifest.h | 0 {rimage => tools/rimage}/pkcs1_5.c | 0 {rimage => tools/rimage}/plat_auth.c | 0 {rimage => tools/rimage}/plat_auth.h | 0 {rimage => tools/rimage}/rimage.c | 0 {rimage => tools/rimage}/rimage.h | 0 35 files changed, 707 insertions(+), 24 deletions(-) create mode 100755 scripts/tools-build.sh create mode 100644 tools/Makefile.am create mode 100644 tools/logger/Makefile.am create mode 100644 tools/logger/convert.c create mode 100644 tools/logger/convert.h create mode 100644 tools/logger/logger.c rename {rimage => tools/rimage}/Makefile.am (100%) rename {rimage => tools/rimage}/cse.c (100%) rename {rimage => tools/rimage}/cse.h (100%) rename {rimage => tools/rimage}/css.c (100%) rename {rimage => tools/rimage}/css.h (100%) rename {rimage => tools/rimage}/elf.c (100%) rename {rimage => tools/rimage}/file_format.h (100%) rename {rimage => tools/rimage}/file_simple.c (100%) rename {rimage => tools/rimage}/hash.c (100%) rename {rimage => tools/rimage}/keys/Makefile.am (100%) rename {rimage => tools/rimage}/keys/README (100%) rename {rimage => tools/rimage}/keys/otc_private_key.pem (100%) rename {rimage => tools/rimage}/keys/otc_public_key.pem (100%) rename {rimage => tools/rimage}/man_apl.c (100%) rename {rimage => tools/rimage}/man_cnl.c (100%) rename {rimage => tools/rimage}/man_kbl.c (100%) rename {rimage => tools/rimage}/manifest.c (100%) rename {rimage => tools/rimage}/manifest.h (100%) rename {rimage => tools/rimage}/pkcs1_5.c (100%) rename {rimage => tools/rimage}/plat_auth.c (100%) rename {rimage => tools/rimage}/plat_auth.h (100%) rename {rimage => tools/rimage}/rimage.c (100%) rename {rimage => tools/rimage}/rimage.h (100%) diff --git a/.gitignore b/.gitignore index b2891b4d6deb..98517640894c 100644 --- a/.gitignore +++ b/.gitignore @@ -62,7 +62,7 @@ sof-* boot_ldr-* boot_module module -rimage/rimage +tools/rimage/rimage tap-driver.sh test-driver diff --git a/Makefile.am b/Makefile.am index 892cc2c08d98..f40cb2e4f4c6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ -if BUILD_RIMAGE -SUBDIRS = rimage +if BUILD_TOOLS +SUBDIRS = tools else SUBDIRS = doc src test endif @@ -65,7 +65,7 @@ doc-dummy: doc: doc-dummy $(MAKE) -C doc doc -if !BUILD_RIMAGE +if !BUILD_TOOLS all-local: rm -f $(top_srcdir)/src/include/version.h endif diff --git a/README.md b/README.md index cbde03ae74fb..36233f251255 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,11 @@ See [docs](https://thesofproject.github.io/latest/index.html) 1. Run `autogen.sh` -2. Build and install the rimage ELF image creator and signing tool +2. Build and install sof tools: rimage (ELF image creator and signing tool) and +logger ``` -./configure --enable-rimage +./configure --enable-tools make sudo make install ``` diff --git a/configure.ac b/configure.ac index a0ec650302e0..b1e81359dead 100644 --- a/configure.ac +++ b/configure.ac @@ -85,14 +85,14 @@ fi AM_CONDITIONAL(BUILD_LIB, test "$have_library" = "yes") # check if we are building tools -AC_ARG_ENABLE(rimage, [AS_HELP_STRING([--enable-rimage],[build rimage tool])], have_rimage=$enableval, have_rimage=no) +AC_ARG_ENABLE(tools, [AS_HELP_STRING([--enable-tools],[build sof tools])], have_tools=$enableval, have_tools=no) IMPLICIT_FALLTHROUGH_FLAG="" -if test "$have_rimage" = "yes"; then - AC_DEFINE([CONFIG_RIMAGE], [1], [Configure to build rimage]) +if test "$have_tools" = "yes"; then + AC_DEFINE([CONFIG_TOOLS], [1], [Configure to build sof tools]) AM_CFLAGS="-O2 -g -Wall -Werror -Wl,-EL -Wmissing-prototypes" IMPLICIT_FALLTHROUGH_FLAG="-Wimplicit-fallthrough=3" fi -AM_CONDITIONAL(BUILD_RIMAGE, test "$have_rimage" = "yes") +AM_CONDITIONAL(BUILD_TOOLS, test "$have_tools" = "yes") # check if we are building docs AC_ARG_ENABLE(doc, [AS_HELP_STRING([--enable-doc],[build doc])], have_doc=$enableval, have_doc=no) @@ -152,7 +152,7 @@ case "$with_arch" in AC_DEFINE([CONFIG_HOST], [1], [Configure for Host]) ;; *) - if test "$have_rimage" = "no" && test "$have_doc" = "no" ; then + if test "$have_tools" = "no" && test "$have_doc" = "no" ; then AC_MSG_ERROR([DSP architecture not specified]) fi ;; @@ -390,7 +390,7 @@ case "$with_platform" in AC_DEFINE([CONFIG_MEM_WND], [1], [Configure Memory Windows]) ;; *) - if test "$have_rimage" = "no" && test "$have_doc" = "no"; then + if test "$have_tools" = "no" && test "$have_doc" = "no"; then if test "$ARCH" = "host"; then PLATFORM="host" AC_SUBST(PLATFORM) @@ -504,7 +504,7 @@ AC_CHECK_TOOL([OBJDUMP], [objdump], []) # Check for openssl - used by rimage AC_CHECK_LIB([crypto], [OPENSSL_config], , [have_openssl="no"]) -if test "$have_rimage" = "yes"; then +if test "$have_tools" = "yes"; then if test "$have_openssl" = "no"; then AC_MSG_ERROR([Need OpenSSL libcrypto for rimage code signing]) fi @@ -537,8 +537,10 @@ AM_EXTRA_RECURSIVE_TARGETS([vminstall]) AC_CONFIG_FILES([ Makefile - rimage/Makefile - rimage/keys/Makefile + tools/Makefile + tools/logger/Makefile + tools/rimage/Makefile + tools/rimage/keys/Makefile doc/Makefile src/Makefile src/tasks/Makefile diff --git a/scripts/rimage-build.sh b/scripts/rimage-build.sh index 38f48ffcc4fe..c64f9f22b52e 100755 --- a/scripts/rimage-build.sh +++ b/scripts/rimage-build.sh @@ -16,13 +16,13 @@ done # make sure rimage is built and aligned with code if [[ "x$BUILD_LOCAL" == "x" ]] then - ./configure --enable-rimage + ./configure --enable-tools make sudo make install else echo "BUILD in local folder!" rm -rf $pwd/local/ - ./configure --enable-rimage --prefix=$pwd/local + ./configure --enable-tools --prefix=$pwd/local make make install fi diff --git a/scripts/tools-build.sh b/scripts/tools-build.sh new file mode 100755 index 000000000000..c64f9f22b52e --- /dev/null +++ b/scripts/tools-build.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +./autogen.sh + +pwd=`pwd` + +# parse the args +for args in $@ +do + if [[ "$args" == "-l" ]] + then + BUILD_LOCAL=1 + fi +done + +# make sure rimage is built and aligned with code +if [[ "x$BUILD_LOCAL" == "x" ]] +then + ./configure --enable-tools + make + sudo make install +else + echo "BUILD in local folder!" + rm -rf $pwd/local/ + ./configure --enable-tools --prefix=$pwd/local + make + make install +fi diff --git a/scripts/xtensa-build-all.sh b/scripts/xtensa-build-all.sh index af730f4b2ac2..b766c583cb69 100755 --- a/scripts/xtensa-build-all.sh +++ b/scripts/xtensa-build-all.sh @@ -1,7 +1,7 @@ #!/bin/bash SUPPORTED_PLATFORMS=(byt cht bdw hsw apl cnl sue icl skl kbl) -BUILD_RIMAGE=0 +BUILD_TOOLS=0 BUILD_DEBUG=no BUILD_JOBS=1 BUILD_JOBS_NEXT=0 @@ -11,7 +11,7 @@ pwd=`pwd` if [ "$#" -eq 0 ] then echo "usage: xtensa-build.sh [options] platform(s)" - echo " [-l] Build rimage locally" + echo " [-l] Build tools locally" echo " [-a] Build all platforms" echo " [-d] Enable debug build" echo " [-j [n]] Set number of make build jobs. Infinite jobs with no arg." @@ -23,7 +23,7 @@ else if [[ "$args" == "-l" ]] then BUILD_LOCAL=1 - BUILD_RIMAGE=1 + BUILD_TOOLS=1 PATH=$pwd/local/bin:$PATH @@ -74,18 +74,18 @@ set -e # run autogen.sh ./autogen.sh -# make sure rimage is built and aligned with code -if [[ "x$BUILD_RIMAGE" == "x1" ]] +# make sure tools is built and aligned with code +if [[ "x$BUILD_TOOLS" == "x1" ]] then if [[ "x$BUILD_LOCAL" == "x" ]] then - ./configure --enable-rimage + ./configure --enable-tools make -j ${BUILD_JOBS} sudo make install else echo "BUILD in local folder!" rm -rf $pwd/local/ - ./configure --enable-rimage --prefix=$pwd/local + ./configure --enable-tools --prefix=$pwd/local make -j ${BUILD_JOBS} make install PATH=$pwd/local/bin:$PATH diff --git a/tools/Makefile.am b/tools/Makefile.am new file mode 100644 index 000000000000..a867d00f8911 --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1,3 @@ +if BUILD_TOOLS +SUBDIRS = rimage logger +endif diff --git a/tools/logger/Makefile.am b/tools/logger/Makefile.am new file mode 100644 index 000000000000..ad8ae7e46083 --- /dev/null +++ b/tools/logger/Makefile.am @@ -0,0 +1,8 @@ +bin_PROGRAMS = sof-logger + +sof_logger_SOURCES = \ + logger.c \ + convert.c + +sof_logger_INCDIR = \ + -I $(SRC_DIR)/include \ No newline at end of file diff --git a/tools/logger/convert.c b/tools/logger/convert.c new file mode 100644 index 000000000000..03987ae1942d --- /dev/null +++ b/tools/logger/convert.c @@ -0,0 +1,368 @@ +/* + * debug log converter, using new logger format. + * + * Copyright (c) 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include +#include +#include +#include +#include "convert.h" + +#define CEIL(a, b) ((a+b-1)/b) + +#define TRACE_MAX_PARAMS_COUNT 4 +#define TRACE_MAX_TEXT_LEN 1024 +#define TRACE_MAX_FILENAME_LEN 128 +#define TRACE_MAX_IDS_STR 10 +#define TRACE_IDS_MASK ((1 << TRACE_ID_LENGTH) - 1) + +/* logs file signature */ +#define SND_SOF_LOGS_SIG_SIZE 4 +#define SND_SOF_LOGS_SIG "Logs" + +/* + * Logs dictionary file header. + */ +struct snd_sof_logs_header { + unsigned char sig[SND_SOF_LOGS_SIG_SIZE]; /* "Logs" */ + uint32_t base_address; /* address of log entries section */ + uint32_t data_length; /* amount of bytes following this header */ + uint32_t data_offset; /* offset to first entry in this file */ + struct sof_ipc_fw_version version; +}; + +struct ldc_entry_header { + uint32_t level; + uint32_t component_class; + uint32_t has_ids; + uint32_t params_num; + uint32_t line_idx; + uint32_t file_name_len; + uint32_t text_len; +}; + +struct ldc_entry { + struct ldc_entry_header header; + char *file_name; + char *text; + uint32_t *params; +}; + +static double to_usecs(uint64_t time, double clk) +{ + /* trace timestamp uses CPU system clock at default 25MHz ticks */ + // TODO: support variable clock rates + return (double)time / clk; +} + + +static inline void print_table_header(FILE *out_fd) +{ + fprintf(out_fd, "%5s %6s %12s %7s %16s %16s %24s\t%s\n", + "CORE", + "LEVEL", + "COMP_ID", + "", + "TIMESTAMP", + "DELTA", + "FILE_NAME", + "CONTENT"); + fflush(out_fd); +} + +#define CASE(x) \ + case(TRACE_CLASS_##x): return #x + +static const char *get_component_name(uint32_t component_id) +{ + switch (component_id) { + CASE(IRQ); + CASE(IPC); + CASE(PIPE); + CASE(HOST); + CASE(DAI); + CASE(DMA); + CASE(SSP); + CASE(COMP); + CASE(WAIT); + CASE(LOCK); + CASE(MEM); + CASE(MIXER); + CASE(BUFFER); + CASE(VOLUME); + CASE(SWITCH); + CASE(MUX); + CASE(SRC); + CASE(TONE); + CASE(EQ_FIR); + CASE(EQ_IIR); + CASE(SA); + CASE(DMIC); + CASE(POWER); + default: return "unknown"; + } +} + +static void print_entry_params(FILE *out_fd, struct log_entry_header dma_log, + struct ldc_entry entry, uint64_t last_timestamp, double clock) +{ + char ids[TRACE_MAX_IDS_STR]; + float dt = to_usecs(dma_log.timestamp - last_timestamp, clock); + + if (dt < 0 || dt > 1000.0 * 1000.0 * 1000.0) + dt = NAN; + + if (entry.header.has_ids) + sprintf(ids, "%d.%d", (dma_log.id_0 & TRACE_IDS_MASK), + (dma_log.id_1 & TRACE_IDS_MASK)); + + fprintf(out_fd, "%s%5u %6u %12s %-7s %16.6f %16.6f %20s:%-4u\t", + entry.header.level == LOG_LEVEL_CRITICAL ? KRED : KNRM, + dma_log.core_id, + entry.header.level, + get_component_name(entry.header.component_class), + entry.header.has_ids ? ids : "", + to_usecs(dma_log.timestamp, clock), + dt, + entry.file_name, + entry.header.line_idx); + + switch (entry.header.params_num) { + case 0: + fprintf(out_fd, "%s", entry.text); + break; + case 1: + fprintf(out_fd, entry.text, entry.params[0]); + break; + case 2: + fprintf(out_fd, entry.text, entry.params[0], entry.params[1]); + break; + case 3: + fprintf(out_fd, entry.text, entry.params[0], entry.params[1], + entry.params[2]); + break; + case 4: + fprintf(out_fd, entry.text, entry.params[0], entry.params[1], + entry.params[2], entry.params[3]); + break; + } + fprintf(out_fd, "%s\n", KNRM); + fflush(out_fd); +} + +static int fetch_entry(struct convert_config *config, uint32_t base_address, + uint32_t data_offset, struct log_entry_header dma_log, + uint64_t *last_timestamp) +{ + struct ldc_entry entry; + uint32_t entry_offset; + + int ret; + + entry.file_name = NULL; + entry.text = NULL; + entry.params = NULL; + + /* evaluate entry offset in input file */ + entry_offset = dma_log.log_entry_address - base_address; + + /* set file position to beginning of processed entry */ + fseek(config->ldc_fd, entry_offset + data_offset, SEEK_SET); + + /* fetching elf header params */ + ret = fread(&entry.header, sizeof(entry.header), 1, config->ldc_fd); + if (!ret) { + ret = -ferror(config->ldc_fd); + goto out; + } + if (entry.header.file_name_len > TRACE_MAX_FILENAME_LEN) { + fprintf(stderr, "Error: Invalid filename length.\n"); + ret = -EINVAL; + goto out; + } + entry.file_name = (char *)malloc(entry.header.file_name_len); + + if (!entry.file_name) { + fprintf(stderr, "error: can't allocate %d byte for " + "entry.file_name\n", entry.header.file_name_len); + ret = -ENOMEM; + goto out; + } + + ret = fread(entry.file_name, sizeof(char), entry.header.file_name_len, + config->ldc_fd); + if (ret != entry.header.file_name_len) { + ret = -ferror(config->ldc_fd); + goto out; + } + + /* fetching text */ + if (entry.header.text_len > TRACE_MAX_TEXT_LEN) { + fprintf(stderr, "Error: Invalid text length.\n"); + ret = -EINVAL; + goto out; + } + entry.text = (char *)malloc(entry.header.text_len); + if (entry.text == NULL) { + fprintf(stderr, "error: can't allocate %d byte for " + "entry.text\n", entry.header.text_len); + ret = -ENOMEM; + goto out; + } + ret = fread(entry.text, sizeof(char), entry.header.text_len, + config->ldc_fd); + if (ret != entry.header.text_len) { + ret = -ferror(config->ldc_fd); + goto out; + } + + /* fetching entry params from dma dump */ + if (entry.header.params_num > TRACE_MAX_PARAMS_COUNT) { + fprintf(stderr, "Error: Invalid number of parameters.\n"); + ret = -EINVAL; + goto out; + } + entry.params = (uint32_t *)malloc(sizeof(uint32_t) * + entry.header.params_num); + if (entry.params == NULL) { + fprintf(stderr, "error: can't allocate %d byte for " + "entry.params\n", (int)(sizeof(uint32_t) * + entry.header.params_num)); + ret = -ENOMEM; + goto out; + } + ret = fread(entry.params, sizeof(uint32_t), entry.header.params_num, + config->in_fd); + if (ret != entry.header.params_num) { + ret = -ferror(config->in_fd); + goto out; + } + + /* printing entry content */ + print_entry_params(config->out_fd, dma_log, entry, *last_timestamp, + config->clock); + *last_timestamp = dma_log.timestamp; + + /* set f_ldc file position to the beginning */ + rewind(config->ldc_fd); + + ret = 0; +out: + /* free alocated memory */ + free(entry.params); + free(entry.text); + free(entry.file_name); + + return ret; +} + +static int logger_read(struct convert_config *config, + struct snd_sof_logs_header *snd) +{ + struct log_entry_header dma_log; + int ret = 0; + + print_table_header(config->out_fd); + uint64_t last_timestamp = 0; + + while (!feof(config->in_fd)) { + /* getting entry parameters from dma dump */ + ret = fread(&dma_log, sizeof(dma_log), 1, config->in_fd); + if (!ret) + return -ferror(config->in_fd); + + /* checking if received trace address is located in + * entry section in elf file. + */ + if ((dma_log.log_entry_address < snd->base_address) || + dma_log.log_entry_address > snd->base_address + + snd->data_length) { + /* in case the address is not correct input fd should be + * move forward by one DWORD, not entire struct dma_log + */ + fseek(config->in_fd, + -(sizeof(dma_log) - sizeof(uint32_t)), + SEEK_CUR); + continue; + } + + /* fetching entry from elf dump */ + ret = fetch_entry(config, snd->base_address, snd->data_offset, + dma_log, &last_timestamp); + if (ret) + break; + } + + return ret; +} + +int convert(struct convert_config *config) +{ + struct snd_sof_logs_header snd; + int count, ret = 0; + + count = fread(&snd, sizeof(snd), 1, config->ldc_fd); + if (!count) { + fprintf(stderr, "Error while reading %s.\n", config->ldc_file); + return -ferror(config->ldc_fd); + } + + if (strncmp((char *) snd.sig, SND_SOF_LOGS_SIG, + SND_SOF_LOGS_SIG_SIZE)) { + fprintf(stderr, "Error: Invalid ldc file signature.\n"); + return -EINVAL; + } + + /* fw verification */ + if (config->version_fd) { + struct sof_ipc_fw_version ver; + + /* here fw verification should be exploited */ + count = fread(&ver, sizeof(ver), 1, config->version_fd); + if (!count) { + fprintf(stderr, "Error while reading %s.\n", + config->version_file); + return -ferror(config->version_fd); + } + + ret = memcmp(&ver, &snd.version, + sizeof(struct sof_ipc_fw_version)); + if (ret) { + fprintf(stderr, "Error: fw version in %s file " + "does not coincide with fw version in " + "%s file.\n", config->ldc_file, config->version_file); + return -EINVAL; + } + + /* logger and version_file abi verification */ + if SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, ver.abi_version) { + fprintf(stderr, "Error: abi version in %s file " + "does not coincide with abi version used " + "by logger.\n", config->version_file); + return -EINVAL; + } + } + + /* default logger and ldc_file abi verification */ + if SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, snd.version.abi_version) { + fprintf(stderr, "Error: abi version in %s file " + "does not coincide with abi version used " + "by logger.\n", config->ldc_file); + return -EINVAL; + } + + return logger_read(config, &snd); +} diff --git a/tools/logger/convert.h b/tools/logger/convert.h new file mode 100644 index 000000000000..f58735d1e255 --- /dev/null +++ b/tools/logger/convert.h @@ -0,0 +1,37 @@ +/* + * debug log converter interface. + * + * Copyright (c) 2018, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ +#include +#include +#include + +#define KNRM "\x1B[0m" +#define KRED "\x1B[31m" + +struct convert_config { + const char *out_file; + const char *in_file; + FILE *out_fd; + FILE *in_fd; + double clock; + int trace; + const char *ldc_file; + FILE *ldc_fd; + int input_std; + int version_fw; + char *version_file; + FILE *version_fd; +}; + +int convert(struct convert_config *config); diff --git a/tools/logger/logger.c b/tools/logger/logger.c new file mode 100644 index 000000000000..b9d7d71c4d1b --- /dev/null +++ b/tools/logger/logger.c @@ -0,0 +1,236 @@ +/* + * mbox dump to debug log converter. + * + * Copyright (c) 2015, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ +#include +#include +#include +#include +#include +#include +#include "convert.h" + +#define APP_NAME "sof-logger" + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +static const char *debugfs[] = { + "dmac0", "dmac1", "ssp0", "ssp1", + "ssp2", "iram", "dram", "shim", + "mbox", "etrace", +}; + +static void usage(void) +{ + fprintf(stdout, "Usage %s \n", APP_NAME); + fprintf(stdout, "%s:\t \t\t\tDisplay mailbox contents\n", APP_NAME); + fprintf(stdout, "%s:\t -i infile -o outfile\tDump infile contents to outfile\n", APP_NAME); + fprintf(stdout, "%s:\t -l *.ldc_file\t\t*.ldc files generated by rimage\n", APP_NAME); + fprintf(stdout, "%s:\t -p \t\t\tInput from stdin\n", APP_NAME); + fprintf(stdout, "%s:\t -e \t\t\tEnable checking firmware version with default verification file\n", APP_NAME); + fprintf(stdout, "%s:\t -v ver_file\t\tEnable checking firmware version with ver_file file\n", APP_NAME); + fprintf(stdout, "%s:\t -c\t\t\tSet timestamp clock in MHz\n", APP_NAME); + fprintf(stdout, "%s:\t -s\t\t\tTake a snapshot of state\n", APP_NAME); + fprintf(stdout, "%s:\t -t\t\t\tDisplay trace data\n", APP_NAME); + exit(0); +} + +static int snapshot(const char *name) +{ + const char *path = "/sys/kernel/debug/sof"; + uint32_t val, addr; + char pinname[64], poutname[64], buffer[128]; + FILE *in_fd, *out_fd; + int i, count; + + if (name == NULL) { + fprintf(stderr, "error: need snapshot name\n"); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(debugfs); i++) { + + sprintf(pinname, "%s/%s", path, debugfs[i]); + sprintf(poutname, "%s.%s.txt", name, debugfs[i]); + + /* open debugfs for reading */ + in_fd = fopen(pinname, "r"); + if (in_fd == NULL) { + fprintf(stderr, "error: unable to open %s for reading %d\n", + pinname, errno); + continue; + } + + /* open outfile for reading */ + out_fd = fopen(poutname, "w"); + if (out_fd == NULL) { + fprintf(stderr, "error: unable to open %s for writing %d\n", + poutname, errno); + fclose(in_fd); + continue; + } + + fprintf(stdout, "processing %s...\n", pinname); + addr = 0; + + while (1) { + count = fread(&val, 1, 4, in_fd); + if (count != 4) + break; + + sprintf(buffer, "0x%6.6x: 0x%8.8x\n", addr, val); + + count = fwrite(buffer, 1, strlen(buffer), out_fd); + + addr += 4; + } + + fclose(in_fd); + fclose(out_fd); + } + + return 0; +} + +int main(int argc, char *argv[]) +{ + struct convert_config config; + int opt, ret = 0; + + config.trace = 0; + config.clock = 19.2; + config.in_file = NULL; + config.out_file = NULL; + config.out_fd = NULL; + config.in_fd = NULL; + config.ldc_file = NULL; + config.ldc_fd = NULL; + config.input_std = 0; + /* checking fw version is disabled by default */ + config.version_file = NULL; + config.version_fd = NULL; + config.version_fw = 0; + + while ((opt = getopt(argc, argv, "ho:i:l:ps:m:c:tev:")) != -1) { + switch (opt) { + case 'o': + config.out_file = optarg; + break; + case 'i': + config.in_file = optarg; + break; + case 't': + config.trace = 1; + break; + case 'c': + config.clock = atof(optarg); + break; + case 's': + return snapshot(optarg); + case 'l': + config.ldc_file = optarg; + break; + case 'p': + config.input_std = 1; + break; + case 'e': + /* enabling checking fw version with default verification + * file + */ + config.version_fw = 1; + config.version_file = "/sys/kernel/debug/sof/fw_version"; + break; + case 'v': + /* enabling checking fw version with ver_file file */ + config.version_fw = 1; + config.version_file = optarg; + break; + case 'h': + default: /* '?' */ + usage(); + } + } + + if (!config.ldc_file) { + fprintf(stderr, "error: Missing ldc file\n"); + usage(); + } + + config.ldc_fd = fopen(config.ldc_file, "r"); + if (!config.ldc_fd) { + fprintf(stderr, "error: Unable to open ldc file %s\n", + config.ldc_file); + ret = -errno; + goto out; + } + + if (config.version_fw) { + config.version_fd = fopen(config.version_file, "r"); + if (!config.version_fd) { + fprintf(stderr, "error: Unable to open ver file %s\n", + config.version_file); + ret = -errno; + goto out; + } + } + + if (config.out_file) { + config.out_fd = fopen(config.out_file, "w"); + if (!config.out_fd) { + fprintf(stderr, "error: Unable to open out file %s\n", + config.out_file); + ret = -errno; + goto out; + } + } else { + config.out_fd = stdout; + } + + /* trace requested ? */ + if (config.trace) + config.in_file = "/sys/kernel/debug/sof/trace"; + + /* default option with no infile is to dump errors/debug data */ + if (!config.in_file) + config.in_file = "/sys/kernel/debug/sof/etrace"; + + if (config.input_std) { + config.in_fd = stdin; + } else { + config.in_fd = fopen(config.in_file, "r"); + if (!config.in_fd) { + fprintf(stderr, "error: Unable to open in file %s\n", + config.in_file); + ret = -errno; + goto out; + } + } + + convert(&config); + +out: + /* close files */ + if (config.out_fd) + fclose(config.out_fd); + + if (config.in_fd) + fclose(config.in_fd); + + if (config.ldc_fd) + fclose(config.ldc_fd); + + if (config.version_fd) + fclose(config.version_fd); + + return ret; +} diff --git a/rimage/Makefile.am b/tools/rimage/Makefile.am similarity index 100% rename from rimage/Makefile.am rename to tools/rimage/Makefile.am diff --git a/rimage/cse.c b/tools/rimage/cse.c similarity index 100% rename from rimage/cse.c rename to tools/rimage/cse.c diff --git a/rimage/cse.h b/tools/rimage/cse.h similarity index 100% rename from rimage/cse.h rename to tools/rimage/cse.h diff --git a/rimage/css.c b/tools/rimage/css.c similarity index 100% rename from rimage/css.c rename to tools/rimage/css.c diff --git a/rimage/css.h b/tools/rimage/css.h similarity index 100% rename from rimage/css.h rename to tools/rimage/css.h diff --git a/rimage/elf.c b/tools/rimage/elf.c similarity index 100% rename from rimage/elf.c rename to tools/rimage/elf.c diff --git a/rimage/file_format.h b/tools/rimage/file_format.h similarity index 100% rename from rimage/file_format.h rename to tools/rimage/file_format.h diff --git a/rimage/file_simple.c b/tools/rimage/file_simple.c similarity index 100% rename from rimage/file_simple.c rename to tools/rimage/file_simple.c diff --git a/rimage/hash.c b/tools/rimage/hash.c similarity index 100% rename from rimage/hash.c rename to tools/rimage/hash.c diff --git a/rimage/keys/Makefile.am b/tools/rimage/keys/Makefile.am similarity index 100% rename from rimage/keys/Makefile.am rename to tools/rimage/keys/Makefile.am diff --git a/rimage/keys/README b/tools/rimage/keys/README similarity index 100% rename from rimage/keys/README rename to tools/rimage/keys/README diff --git a/rimage/keys/otc_private_key.pem b/tools/rimage/keys/otc_private_key.pem similarity index 100% rename from rimage/keys/otc_private_key.pem rename to tools/rimage/keys/otc_private_key.pem diff --git a/rimage/keys/otc_public_key.pem b/tools/rimage/keys/otc_public_key.pem similarity index 100% rename from rimage/keys/otc_public_key.pem rename to tools/rimage/keys/otc_public_key.pem diff --git a/rimage/man_apl.c b/tools/rimage/man_apl.c similarity index 100% rename from rimage/man_apl.c rename to tools/rimage/man_apl.c diff --git a/rimage/man_cnl.c b/tools/rimage/man_cnl.c similarity index 100% rename from rimage/man_cnl.c rename to tools/rimage/man_cnl.c diff --git a/rimage/man_kbl.c b/tools/rimage/man_kbl.c similarity index 100% rename from rimage/man_kbl.c rename to tools/rimage/man_kbl.c diff --git a/rimage/manifest.c b/tools/rimage/manifest.c similarity index 100% rename from rimage/manifest.c rename to tools/rimage/manifest.c diff --git a/rimage/manifest.h b/tools/rimage/manifest.h similarity index 100% rename from rimage/manifest.h rename to tools/rimage/manifest.h diff --git a/rimage/pkcs1_5.c b/tools/rimage/pkcs1_5.c similarity index 100% rename from rimage/pkcs1_5.c rename to tools/rimage/pkcs1_5.c diff --git a/rimage/plat_auth.c b/tools/rimage/plat_auth.c similarity index 100% rename from rimage/plat_auth.c rename to tools/rimage/plat_auth.c diff --git a/rimage/plat_auth.h b/tools/rimage/plat_auth.h similarity index 100% rename from rimage/plat_auth.h rename to tools/rimage/plat_auth.h diff --git a/rimage/rimage.c b/tools/rimage/rimage.c similarity index 100% rename from rimage/rimage.c rename to tools/rimage/rimage.c diff --git a/rimage/rimage.h b/tools/rimage/rimage.h similarity index 100% rename from rimage/rimage.h rename to tools/rimage/rimage.h