diff options
Diffstat (limited to 'util')
130 files changed, 10734 insertions, 16723 deletions
diff --git a/util/battery_temp b/util/battery_temp index c69e3d4778..01f4002b99 100755 --- a/util/battery_temp +++ b/util/battery_temp @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2018 The Chromium OS Authors. All rights reserved. +# Copyright 2018 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # diff --git a/util/bin2h.sh b/util/bin2h.sh index 1507bc4004..276d89f0cf 100755 --- a/util/bin2h.sh +++ b/util/bin2h.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2018 The Chromium OS Authors. All rights reserved. +# Copyright 2018 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # diff --git a/util/build.mk b/util/build.mk index 2948bd9d91..8f047dd1d2 100644 --- a/util/build.mk +++ b/util/build.mk @@ -1,5 +1,5 @@ # -*- makefile -*- -# Copyright 2014 The Chromium OS Authors. All rights reserved. +# Copyright 2014 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # diff --git a/util/build_with_clang.py b/util/build_with_clang.py index a38ade2cb8..e73f765e1e 100755 --- a/util/build_with_clang.py +++ b/util/build_with_clang.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Copyright 2021 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -12,15 +12,14 @@ import multiprocessing import os import subprocess import sys - from concurrent.futures import ThreadPoolExecutor # Add to this list as compilation errors are fixed for boards. BOARDS_THAT_COMPILE_SUCCESSFULLY_WITH_CLANG = [ - 'dartmonkey', - 'bloonchipper', - 'nucleo-f412zg', - 'nucleo-h743zi', + "dartmonkey", + "bloonchipper", + "nucleo-f412zg", + "nucleo-h743zi", ] @@ -29,35 +28,31 @@ def build(board_name: str) -> None: logging.debug('Building board: "%s"', board_name) cmd = [ - 'make', - 'BOARD=' + board_name, - '-j', + "make", + "BOARD=" + board_name, + "-j", ] - logging.debug('Running command: "%s"', ' '.join(cmd)) - subprocess.run(cmd, env=dict(os.environ, CC='clang'), check=True) + logging.debug('Running command: "%s"', " ".join(cmd)) + subprocess.run(cmd, env=dict(os.environ, CC="clang"), check=True) def main() -> int: parser = argparse.ArgumentParser() - log_level_choices = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'] + log_level_choices = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] parser.add_argument( - '--log_level', '-l', - choices=log_level_choices, - default='DEBUG' + "--log_level", "-l", choices=log_level_choices, default="DEBUG" ) parser.add_argument( - '--num_threads', '-j', - type=int, - default=multiprocessing.cpu_count() + "--num_threads", "-j", type=int, default=multiprocessing.cpu_count() ) args = parser.parse_args() logging.basicConfig(level=args.log_level) - logging.debug('Building with %d threads', args.num_threads) + logging.debug("Building with %d threads", args.num_threads) failed_boards = [] with ThreadPoolExecutor(max_workers=args.num_threads) as executor: @@ -73,13 +68,15 @@ def main() -> int: failed_boards.append(board) if len(failed_boards) > 0: - logging.error('The following boards failed to compile:\n%s', - '\n'.join(failed_boards)) + logging.error( + "The following boards failed to compile:\n%s", + "\n".join(failed_boards), + ) return 1 - logging.info('All boards compiled successfully!') + logging.info("All boards compiled successfully!") return 0 -if __name__ == '__main__': +if __name__ == "__main__": sys.exit(main()) diff --git a/util/cbi-util.c b/util/cbi-util.c index fe0c4c2bce..5bea9a04b9 100644 --- a/util/cbi-util.c +++ b/util/cbi-util.c @@ -1,4 +1,4 @@ -/* Copyright 2018 The Chromium OS Authors. All rights reserved. +/* Copyright 2018 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -20,10 +20,10 @@ #include "cros_board_info.h" #include "crc8.h" -#define ARGS_MASK_BOARD_VERSION BIT(0) -#define ARGS_MASK_FILENAME BIT(1) -#define ARGS_MASK_SIZE BIT(2) -#define ARGS_MASK_SKU_ID BIT(3) +#define ARGS_MASK_BOARD_VERSION BIT(0) +#define ARGS_MASK_FILENAME BIT(1) +#define ARGS_MASK_SIZE BIT(2) +#define ARGS_MASK_SKU_ID BIT(3) /* TODO: Set it by macro */ const char cmd_name[] = "cbi-util"; @@ -41,6 +41,7 @@ enum { OPT_PCB_SUPPLIER, OPT_SSFC, OPT_REWORK_ID, + OPT_FACTORY_CALIBRATION_DATA, OPT_SIZE, OPT_ERASE_BYTE, OPT_SHOW_ALL, @@ -48,27 +49,26 @@ enum { }; static const struct option opts_create[] = { - {"file", 1, 0, OPT_FILENAME}, - {"board_version", 1, 0, OPT_BOARD_VERSION}, - {"oem_id", 1, 0, OPT_OEM_ID}, - {"sku_id", 1, 0, OPT_SKU_ID}, - {"dram_part_num", 1, 0, OPT_DRAM_PART_NUM}, - {"oem_name", 1, 0, OPT_OEM_NAME}, - {"model_id", 1, 0, OPT_MODEL_ID}, - {"fw_config", 1, 0, OPT_FW_CONFIG}, - {"pcb_supplier", 1, 0, OPT_PCB_SUPPLIER}, - {"ssfc", 1, 0, OPT_SSFC}, - {"rework_id", 1, 0, OPT_REWORK_ID}, - {"size", 1, 0, OPT_SIZE}, - {"erase_byte", 1, 0, OPT_ERASE_BYTE}, - {NULL, 0, 0, 0} + { "file", 1, 0, OPT_FILENAME }, + { "board_version", 1, 0, OPT_BOARD_VERSION }, + { "oem_id", 1, 0, OPT_OEM_ID }, + { "sku_id", 1, 0, OPT_SKU_ID }, + { "dram_part_num", 1, 0, OPT_DRAM_PART_NUM }, + { "oem_name", 1, 0, OPT_OEM_NAME }, + { "model_id", 1, 0, OPT_MODEL_ID }, + { "fw_config", 1, 0, OPT_FW_CONFIG }, + { "pcb_supplier", 1, 0, OPT_PCB_SUPPLIER }, + { "ssfc", 1, 0, OPT_SSFC }, + { "rework_id", 1, 0, OPT_REWORK_ID }, + { "factory_calibration_data", 1, 0, OPT_FACTORY_CALIBRATION_DATA }, + { "size", 1, 0, OPT_SIZE }, + { "erase_byte", 1, 0, OPT_ERASE_BYTE }, + { NULL, 0, 0, 0 } }; -static const struct option opts_show[] = { - {"file", 1, 0, OPT_FILENAME}, - {"all", 0, 0, OPT_SHOW_ALL}, - {NULL, 0, 0, 0} -}; +static const struct option opts_show[] = { { "file", 1, 0, OPT_FILENAME }, + { "all", 0, 0, OPT_SHOW_ALL }, + { NULL, 0, 0, 0 } }; static const char *field_name[] = { /* Same order as enum cbi_data_tag */ @@ -82,6 +82,7 @@ static const char *field_name[] = { "PCB_SUPPLIER", "SSFC", "REWORK_ID", + "FACTORY_CALIBRATION_DATA", }; BUILD_ASSERT(ARRAY_SIZE(field_name) == CBI_TAG_COUNT); @@ -105,6 +106,7 @@ const char help_create[] = " --pcb_supplier <value> PCB supplier\n" " --ssfc <value> Second Source Factory Cache bit-field\n" " --rework_id <lvalue> REWORK_ID\n" + " --factory_calibration_data <value> Factory calibration data\n" "\n" "<value> must be a positive integer <= 0XFFFFFFFF, <lvalue> must be a\n" " positive integer <= 0xFFFFFFFFFFFFFFFF and field size can be\n" @@ -147,8 +149,9 @@ static void print_help_show(void) static void print_help(void) { printf("\nUsage: %s <create|show> [ARGS]\n" - "\n" - "Utility for CBI:Cros Board Info images.\n", cmd_name); + "\n" + "Utility for CBI:Cros Board Info images.\n", + cmd_name); print_help_create(); print_help_show(); } @@ -314,6 +317,7 @@ static int cmd_create(int argc, char **argv) struct integer_field pcb_supplier; struct integer_field ssfc; struct long_integer_field rework; + struct integer_field factory_calibration_data; const char *dram_part_num; const char *oem_name; } bi; @@ -398,11 +402,16 @@ static int cmd_create(int argc, char **argv) if (parse_uint64_field(optarg, &bi.rework)) return -1; break; + case OPT_FACTORY_CALIBRATION_DATA: + if (parse_integer_field(optarg, + &bi.factory_calibration_data)) + return -1; + break; } } if (set_mask != (ARGS_MASK_BOARD_VERSION | ARGS_MASK_FILENAME | - ARGS_MASK_SIZE | ARGS_MASK_SKU_ID)) { + ARGS_MASK_SIZE | ARGS_MASK_SKU_ID)) { fprintf(stderr, "Missing required arguments\n"); print_help_create(); return -1; @@ -427,9 +436,12 @@ static int cmd_create(int argc, char **argv) p = cbi_set_data(p, CBI_TAG_FW_CONFIG, &bi.fw_config.val, bi.fw_config.size); p = cbi_set_data(p, CBI_TAG_PCB_SUPPLIER, &bi.pcb_supplier.val, - bi.pcb_supplier.size); + bi.pcb_supplier.size); p = cbi_set_data(p, CBI_TAG_SSFC, &bi.ssfc.val, bi.ssfc.size); p = cbi_set_data(p, CBI_TAG_REWORK_ID, &bi.rework.val, bi.rework.size); + p = cbi_set_data(p, CBI_TAG_FACTORY_CALIBRATION_DATA, + &bi.factory_calibration_data.val, + bi.factory_calibration_data.size); p = cbi_set_string(p, CBI_TAG_DRAM_PART_NUM, bi.dram_part_num); p = cbi_set_string(p, CBI_TAG_OEM_NAME, bi.oem_name); @@ -460,7 +472,7 @@ static void print_string(const uint8_t *buf, enum cbi_data_tag tag) name = d->tag < CBI_TAG_COUNT ? field_name[d->tag] : "???"; printf(" %s: %.*s (%u, %u)\n", name, d->size, (const char *)d->value, - d->tag, d->size); + d->tag, d->size); } static void print_integer(const uint8_t *buf, enum cbi_data_tag tag) @@ -489,12 +501,12 @@ static void print_integer(const uint8_t *buf, enum cbi_data_tag tag) v = *(uint64_t *)d->value; break; default: - printf(" %s: Integer of size %d not supported\n", - name, d->size); + printf(" %s: Integer of size %d not supported\n", name, + d->size); return; } printf(" %s: %llu (0x%llx, %u, %u)\n", name, (unsigned long long)v, - (unsigned long long)v, d->tag, d->size); + (unsigned long long)v, d->tag, d->size); } static int cmd_show(int argc, char **argv) @@ -564,6 +576,7 @@ static int cmd_show(int argc, char **argv) print_integer(buf, CBI_TAG_PCB_SUPPLIER); print_integer(buf, CBI_TAG_SSFC); print_integer(buf, CBI_TAG_REWORK_ID); + print_integer(buf, CBI_TAG_FACTORY_CALIBRATION_DATA); print_string(buf, CBI_TAG_DRAM_PART_NUM); print_string(buf, CBI_TAG_OEM_NAME); diff --git a/util/chargen b/util/chargen index 9ba14d3d6a..fd9e73cbda 100644 --- a/util/chargen +++ b/util/chargen @@ -1,10 +1,11 @@ #!/usr/bin/env python3 -# Copyright 2019 The Chromium OS Authors. All rights reserved. +# Copyright 2019 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import sys + def chargen(modulo, max_chars): """Generate a stream of characters on the console. @@ -18,7 +19,7 @@ def chargen(modulo, max_chars): zero, if zero - print indefinitely """ - base = '0' + base = "0" c = base counter = 0 while True: @@ -26,25 +27,25 @@ def chargen(modulo, max_chars): counter = counter + 1 if (max_chars != 0) and (counter == max_chars): - sys.stdout.write('\n') + sys.stdout.write("\n") return if modulo and ((counter % modulo) == 0): c = base continue - if c == 'z': + if c == "z": c = base - elif c == 'Z': - c = 'a' - elif c == '9': - c = 'A' + elif c == "Z": + c = "a" + elif c == "9": + c = "A" else: - c = '%c' % (ord(c) + 1) + c = "%c" % (ord(c) + 1) def main(args): - '''Process command line arguments and invoke chargen if args are valid''' + """Process command line arguments and invoke chargen if args are valid""" modulo = 0 max_chars = 0 @@ -55,8 +56,7 @@ def main(args): if len(args) > 1: max_chars = int(args[1]) except ValueError: - sys.stderr.write('usage %s:' - "['seq_length' ['max_chars']]\n") + sys.stderr.write("usage %s:" "['seq_length' ['max_chars']]\n") sys.exit(1) try: @@ -64,6 +64,7 @@ def main(args): except KeyboardInterrupt: print() -if __name__ == '__main__': + +if __name__ == "__main__": main(sys.argv[1:]) sys.exit(0) diff --git a/util/check_clang_format.py b/util/check_clang_format.py new file mode 100755 index 0000000000..3be63774f7 --- /dev/null +++ b/util/check_clang_format.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Validate all C source is formatted with clang-format. + +This isn't very useful to users to call directly, but it is run it the +CQ. Most users will likely find out they forgot to clang-format by +the pre-upload checks. +""" + +import logging +import pathlib +import subprocess +import sys + +from chromite.lib import commandline + + +def main(argv=None): + """Find all C files and runs clang-format on them.""" + parser = commandline.ArgumentParser() + parser.parse_args(argv) + + logging.info("Validating all code is formatted with clang-format.") + ec_dir = pathlib.Path(__file__).resolve().parent.parent + all_files = [ + ec_dir / path + for path in subprocess.run( + ["git", "ls-files", "-z"], + check=True, + cwd=ec_dir, + stdout=subprocess.PIPE, + encoding="utf-8", + ).stdout.split("\0") + if path + ] + + clang_format_files = [] + for path in all_files: + if not path.is_file() or path.is_symlink(): + continue + if "third_party" in path.parts: + continue + if path.name.endswith(".c") or path.name.endswith(".h"): + clang_format_files.append(path) + + result = subprocess.run( + ["clang-format", "--dry-run", *clang_format_files], + check=False, + cwd=ec_dir, + stderr=subprocess.PIPE, + encoding="utf-8", + ) + if result.stderr: + logging.error("All C source must be formatted with clang-format!") + for line in result.stderr.splitlines(): + logging.error("%s", line) + return 1 + if result.returncode != 0: + logging.error("clang-format failed with no output!") + return result.returncode + + logging.info("No clang-format issues found!") + return 0 + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/util/comm-dev.c b/util/comm-dev.c index e73538b323..f6467492f9 100644 --- a/util/comm-dev.c +++ b/util/comm-dev.c @@ -1,4 +1,4 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. +/* Copyright 2013 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -27,7 +27,7 @@ static int fd = -1; #define ARRAY_SIZE(t) (sizeof(t) / sizeof(t[0])) #endif -static const char * const meanings[] = { +static const char *const meanings[] = { "SUCCESS", "INVALID_COMMAND", "ERROR", @@ -60,9 +60,8 @@ static const char *strresult(int i) /* Old ioctl format, used by Chrome OS 3.18 and older */ -static int ec_command_dev(int command, int version, - const void *outdata, int outsize, - void *indata, int insize) +static int ec_command_dev(int command, int version, const void *outdata, + int outsize, void *indata, int insize) { struct cros_ec_command s_cmd; int r; @@ -83,12 +82,15 @@ static int ec_command_dev(int command, int version, if (errno == EAGAIN && s_cmd.result == EC_RES_IN_PROGRESS) { s_cmd.command = EC_CMD_RESEND_RESPONSE; r = ioctl(fd, CROS_EC_DEV_IOCXCMD, &s_cmd); - fprintf(stderr, - "ioctl %d, errno %d (%s), EC result %d (%s)\n", - r, errno, strerror(errno), s_cmd.result, - strresult(s_cmd.result)); + if (r < 0) { + fprintf(stderr, + "ioctl %d, errno %d (%s), EC result %d (%s)\n", + r, errno, strerror(errno), s_cmd.result, + strresult(s_cmd.result)); + } } - } else if (s_cmd.result != EC_RES_SUCCESS) { + } + if (r >= 0 && s_cmd.result != EC_RES_SUCCESS) { fprintf(stderr, "EC result %d (%s)\n", s_cmd.result, strresult(s_cmd.result)); return -EECRESULT - s_cmd.result; @@ -117,16 +119,14 @@ static int ec_readmem_dev(int offset, int bytes, void *dest) r_mem.offset = offset; r_mem.size = bytes; - return ec_command_dev(EC_CMD_READ_MEMMAP, 0, - &r_mem, sizeof(r_mem), + return ec_command_dev(EC_CMD_READ_MEMMAP, 0, &r_mem, sizeof(r_mem), dest, bytes); } /* New ioctl format, used by Chrome OS 4.4 and later as well as upstream 4.0+ */ -static int ec_command_dev_v2(int command, int version, - const void *outdata, int outsize, - void *indata, int insize) +static int ec_command_dev_v2(int command, int version, const void *outdata, + int outsize, void *indata, int insize) { struct cros_ec_command_v2 *s_cmd; int r; @@ -153,18 +153,22 @@ static int ec_command_dev_v2(int command, int version, strresult(s_cmd->result)); if (errno == EAGAIN && s_cmd->result == EC_RES_IN_PROGRESS) { s_cmd->command = EC_CMD_RESEND_RESPONSE; - r = ioctl(fd, CROS_EC_DEV_IOCXCMD_V2, &s_cmd); - fprintf(stderr, - "ioctl %d, errno %d (%s), EC result %d (%s)\n", - r, errno, strerror(errno), s_cmd->result, - strresult(s_cmd->result)); + r = ioctl(fd, CROS_EC_DEV_IOCXCMD_V2, s_cmd); + if (r < 0) { + fprintf(stderr, + "ioctl %d, errno %d (%s), EC result %d (%s)\n", + r, errno, strerror(errno), + s_cmd->result, + strresult(s_cmd->result)); + } } - } else { + } + if (r >= 0) { memcpy(indata, s_cmd->data, MIN(r, insize)); if (s_cmd->result != EC_RES_SUCCESS) { fprintf(stderr, "EC result %d (%s)\n", s_cmd->result, strresult(s_cmd->result)); - r = -EECRESULT - s_cmd->result; + r = -EECRESULT - s_cmd->result; } } free(s_cmd); @@ -193,8 +197,7 @@ static int ec_readmem_dev_v2(int offset, int bytes, void *dest) r_mem.offset = offset; r_mem.size = bytes; - return ec_command_dev_v2(EC_CMD_READ_MEMMAP, 0, - &r_mem, sizeof(r_mem), + return ec_command_dev_v2(EC_CMD_READ_MEMMAP, 0, &r_mem, sizeof(r_mem), dest, bytes); } @@ -204,11 +207,9 @@ static int ec_readmem_dev_v2(int offset, int bytes, void *dest) */ static int ec_dev_is_v2(void) { - struct ec_params_hello h_req = { - .in_data = 0xa0b0c0d0 - }; + struct ec_params_hello h_req = { .in_data = 0xa0b0c0d0 }; struct ec_response_hello h_resp; - struct cros_ec_command s_cmd = { }; + struct cros_ec_command s_cmd = {}; int r; s_cmd.command = EC_CMD_HELLO; @@ -256,7 +257,7 @@ int comm_init_dev(const char *device_name) if (fd < 0) return 1; - r = read(fd, version, sizeof(version)-1); + r = read(fd, version, sizeof(version) - 1); if (r <= 0) { close(fd); return 2; diff --git a/util/comm-host.c b/util/comm-host.c index 45d6f85a02..914e6d27e8 100644 --- a/util/comm-host.c +++ b/util/comm-host.c @@ -1,4 +1,4 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. +/* Copyright 2013 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -15,10 +15,8 @@ #include "ec_commands.h" #include "misc_util.h" - -int (*ec_command_proto)(int command, int version, - const void *outdata, int outsize, - void *indata, int insize); +int (*ec_command_proto)(int command, int version, const void *outdata, + int outsize, void *indata, int insize); int (*ec_readmem)(int offset, int bytes, void *dest); @@ -45,8 +43,8 @@ static int fake_readmem(int offset, int bytes, void *dest) if (bytes) { p.size = bytes; - c = ec_command(EC_CMD_READ_MEMMAP, 0, &p, sizeof(p), - dest, p.size); + c = ec_command(EC_CMD_READ_MEMMAP, 0, &p, sizeof(p), dest, + p.size); if (c < 0) return c; return p.size; @@ -73,14 +71,12 @@ void set_command_offset(int offset) command_offset = offset; } -int ec_command(int command, int version, - const void *outdata, int outsize, +int ec_command(int command, int version, const void *outdata, int outsize, void *indata, int insize) { /* Offset command code to support sub-devices */ - return ec_command_proto(command_offset + command, version, - outdata, outsize, - indata, insize); + return ec_command_proto(command_offset + command, version, outdata, + outsize, indata, insize); } int comm_init_alt(int interfaces, const char *device_name, int i2c_bus) @@ -99,13 +95,13 @@ int comm_init_alt(int interfaces, const char *device_name, int i2c_bus) dev_is_cros_ec = !strcmp(CROS_EC_DEV_NAME, device_name); /* Fallback to direct LPC on x86 */ - if (dev_is_cros_ec && (interfaces & COMM_LPC) && - comm_init_lpc && !comm_init_lpc()) + if (dev_is_cros_ec && (interfaces & COMM_LPC) && comm_init_lpc && + !comm_init_lpc()) return 0; /* Fallback to direct I2C */ if ((dev_is_cros_ec || i2c_bus != -1) && (interfaces & COMM_I2C) && - comm_init_i2c && !comm_init_i2c(i2c_bus)) + comm_init_i2c && !comm_init_i2c(i2c_bus)) return 0; /* Give up */ @@ -134,11 +130,11 @@ int comm_init_buffer(void) /* read max request / response size from ec for protocol v3+ */ if (ec_command(EC_CMD_GET_PROTOCOL_INFO, 0, NULL, 0, &info, - sizeof(info)) == sizeof(info)) { + sizeof(info)) == sizeof(info)) { int outsize = info.max_request_packet_size - - sizeof(struct ec_host_request); + sizeof(struct ec_host_request); int insize = info.max_response_packet_size - - sizeof(struct ec_host_response); + sizeof(struct ec_host_response); if ((allow_large_buffer) || (outsize < ec_max_outsize)) ec_max_outsize = outsize; if ((allow_large_buffer) || (insize < ec_max_insize)) diff --git a/util/comm-host.h b/util/comm-host.h index bd22655e57..907df3df96 100644 --- a/util/comm-host.h +++ b/util/comm-host.h @@ -1,4 +1,4 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. +/* Copyright 2013 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -63,9 +63,12 @@ int comm_init_buffer(void); * Send a command to the EC. Returns the length of output data returned (0 if * none), or negative on error. */ -int ec_command(int command, int version, - const void *outdata, int outsize, /* to the EC */ - void *indata, int insize); /* from the EC */ +int ec_command(int command, int version, const void *outdata, + int outsize, /* to + the + EC + */ + void *indata, int insize); /* from the EC */ /** * Set the offset to be applied to the command number when ec_command() calls @@ -79,9 +82,9 @@ void set_command_offset(int offset); * by the protocol-specific driver. DO NOT call this version directly from * anywhere but ec_command(), or the --device option will not work. */ -extern int (*ec_command_proto)(int command, int version, - const void *outdata, int outsize, /* to EC */ - void *indata, int insize); /* from EC */ +extern int (*ec_command_proto)(int command, int version, const void *outdata, + int outsize, /* to EC */ + void *indata, int insize); /* from EC */ /** * Return the content of the EC information area mapped as "memory". diff --git a/util/comm-i2c.c b/util/comm-i2c.c index d76749fbe5..1548beaaa2 100644 --- a/util/comm-i2c.c +++ b/util/comm-i2c.c @@ -1,4 +1,4 @@ -/* Copyright 2012 The Chromium OS Authors. All rights reserved. +/* Copyright 2012 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -27,7 +27,7 @@ #define I2C_ADAPTER_NODE "/sys/class/i2c-adapter/i2c-%d/%d-%04x/name" #define I2C_ADAPTER_NAME "cros-ec-i2c" -#define I2C_MAX_ADAPTER 32 +#define I2C_MAX_ADAPTER 32 #define I2C_NODE "/dev/i2c-%d" #ifdef DEBUG @@ -62,9 +62,8 @@ static void dump_buffer(const uint8_t *data, int length) * Sends a command to the EC (protocol v3). Returns the command status code * (>= 0), or a negative EC_RES_* value on error. */ -static int ec_command_i2c_3(int command, int version, - const void *outdata, int outsize, - void *indata, int insize) +static int ec_command_i2c_3(int command, int version, const void *outdata, + int outsize, void *indata, int insize) { int ret = -EC_RES_ERROR; int error; @@ -87,8 +86,8 @@ static int ec_command_i2c_3(int command, int version, insize, ec_max_insize); return -EC_RES_ERROR; } - req_len = I2C_REQUEST_HEADER_SIZE + sizeof(struct ec_host_request) - + outsize; + req_len = I2C_REQUEST_HEADER_SIZE + sizeof(struct ec_host_request) + + outsize; req_buf = (uint8_t *)(calloc(1, req_len)); if (!req_buf) goto done; @@ -102,8 +101,8 @@ static int ec_command_i2c_3(int command, int version, req->reserved = 0; req->data_len = outsize; - memcpy(&req_buf[I2C_REQUEST_HEADER_SIZE - + sizeof(struct ec_host_request)], + memcpy(&req_buf[I2C_REQUEST_HEADER_SIZE + + sizeof(struct ec_host_request)], outdata, outsize); req->checksum = @@ -115,8 +114,8 @@ static int ec_command_i2c_3(int command, int version, i2c_msg.len = req_len; i2c_msg.buf = req_buf; - resp_len = I2C_RESPONSE_HEADER_SIZE + sizeof(struct ec_host_response) - + insize; + resp_len = I2C_RESPONSE_HEADER_SIZE + sizeof(struct ec_host_response) + + insize; resp_buf = (uint8_t *)(calloc(1, resp_len)); if (!resp_buf) goto done; @@ -135,8 +134,8 @@ static int ec_command_i2c_3(int command, int version, data.nmsgs = 1; error = ioctl(i2c_fd, I2C_RDWR, &data); if (error < 0) { - fprintf(stderr, "I2C write failed: %d (err: %d, %s)\n", - error, errno, strerror(errno)); + fprintf(stderr, "I2C write failed: %d (err: %d, %s)\n", error, + errno, strerror(errno)); goto done; } @@ -146,8 +145,8 @@ static int ec_command_i2c_3(int command, int version, i2c_msg.buf = resp_buf; error = ioctl(i2c_fd, I2C_RDWR, &data); if (error < 0) { - fprintf(stderr, "I2C read failed: %d (err: %d, %s)\n", - error, errno, strerror(errno)); + fprintf(stderr, "I2C read failed: %d (err: %d, %s)\n", error, + errno, strerror(errno)); goto done; } @@ -177,15 +176,16 @@ static int ec_command_i2c_3(int command, int version, goto done; } - if ((uint8_t)sum_bytes(&resp_buf[I2C_RESPONSE_HEADER_SIZE], resp_buf[1]) - != 0) { + if ((uint8_t)sum_bytes(&resp_buf[I2C_RESPONSE_HEADER_SIZE], + resp_buf[1]) != 0) { debug("Bad checksum on EC response.\n"); ret = -EC_RES_INVALID_CHECKSUM; goto done; } - memcpy(indata, &resp_buf[I2C_RESPONSE_HEADER_SIZE - + sizeof(struct ec_host_response)], + memcpy(indata, + &resp_buf[I2C_RESPONSE_HEADER_SIZE + + sizeof(struct ec_host_response)], insize); ret = resp->data_len; @@ -208,7 +208,8 @@ int comm_init_i2c(int i2c_bus) i = i2c_bus; if (i >= I2C_MAX_ADAPTER) { - fprintf(stderr, "Invalid I2C bus number %d. (The highest possible bus number is %d.)\n", + fprintf(stderr, + "Invalid I2C bus number %d. (The highest possible bus number is %d.)\n", i, I2C_MAX_ADAPTER); return -1; } @@ -217,8 +218,8 @@ int comm_init_i2c(int i2c_bus) for (i = 0; i < I2C_MAX_ADAPTER; i++) { FILE *f; - if (asprintf(&file_path, I2C_ADAPTER_NODE, - i, i, EC_I2C_ADDR) < 0) + if (asprintf(&file_path, I2C_ADAPTER_NODE, i, i, + EC_I2C_ADDR) < 0) return -1; f = fopen(file_path, "r"); if (f) { @@ -248,10 +249,10 @@ int comm_init_i2c(int i2c_bus) free(file_path); ec_command_proto = ec_command_i2c_3; - ec_max_outsize = I2C_MAX_HOST_PACKET_SIZE - I2C_REQUEST_HEADER_SIZE - - sizeof(struct ec_host_request); - ec_max_insize = I2C_MAX_HOST_PACKET_SIZE - I2C_RESPONSE_HEADER_SIZE - - sizeof(struct ec_host_response); + ec_max_outsize = I2C_MAX_HOST_PACKET_SIZE - I2C_REQUEST_HEADER_SIZE - + sizeof(struct ec_host_request); + ec_max_insize = I2C_MAX_HOST_PACKET_SIZE - I2C_RESPONSE_HEADER_SIZE - + sizeof(struct ec_host_response); return 0; } diff --git a/util/comm-lpc.c b/util/comm-lpc.c index d1ce761fc2..8e2042f0cc 100644 --- a/util/comm-lpc.c +++ b/util/comm-lpc.c @@ -1,4 +1,4 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. +/* Copyright 2013 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -14,7 +14,7 @@ #include "comm-host.h" -#define INITIAL_UDELAY 5 /* 5 us */ +#define INITIAL_UDELAY 5 /* 5 us */ #define MAXIMUM_UDELAY 10000 /* 10 ms */ /* @@ -43,12 +43,11 @@ static int wait_for_ec(int status_addr, int timeout_usec) if (i > 20) delay = MIN(delay * 2, MAXIMUM_UDELAY); } - return -1; /* Timeout */ + return -1; /* Timeout */ } -static int ec_command_lpc(int command, int version, - const void *outdata, int outsize, - void *indata, int insize) +static int ec_command_lpc(int command, int version, const void *outdata, + int outsize, void *indata, int insize) { struct ec_lpc_host_args args; const uint8_t *d; @@ -112,8 +111,7 @@ static int ec_command_lpc(int command, int version, csum = command + args.flags + args.command_version + args.data_size; /* Read response and update checksum */ - for (i = 0, dout = (uint8_t *)indata; i < args.data_size; - i++, dout++) { + for (i = 0, dout = (uint8_t *)indata; i < args.data_size; i++, dout++) { *dout = inb(EC_LPC_ADDR_HOST_PARAM + i); csum += *dout; } @@ -128,9 +126,8 @@ static int ec_command_lpc(int command, int version, return args.data_size; } -static int ec_command_lpc_3(int command, int version, - const void *outdata, int outsize, - void *indata, int insize) +static int ec_command_lpc_3(int command, int version, const void *outdata, + int outsize, void *indata, int insize) { struct ec_host_request rq; struct ec_host_response rs; @@ -231,10 +228,10 @@ static int ec_readmem_lpc(int offset, int bytes, void *dest) if (offset >= EC_MEMMAP_SIZE - bytes) return -1; - if (bytes) { /* fixed length */ + if (bytes) { /* fixed length */ for (; cnt < bytes; i++, s++, cnt++) *s = inb(EC_LPC_ADDR_MEMMAP + i); - } else { /* string */ + } else { /* string */ for (; i < EC_MEMMAP_SIZE; i++, s++) { *s = inb(EC_LPC_ADDR_MEMMAP + i); cnt++; @@ -294,9 +291,9 @@ int comm_init_lpc(void) /* Protocol version 3 */ ec_command_proto = ec_command_lpc_3; ec_max_outsize = EC_LPC_HOST_PACKET_SIZE - - sizeof(struct ec_host_request); + sizeof(struct ec_host_request); ec_max_insize = EC_LPC_HOST_PACKET_SIZE - - sizeof(struct ec_host_response); + sizeof(struct ec_host_response); } else if (i & EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED) { /* Protocol version 2 */ diff --git a/util/comm-servo-spi.c b/util/comm-servo-spi.c index ef6dc7880b..170b1e4e40 100644 --- a/util/comm-servo-spi.c +++ b/util/comm-servo-spi.c @@ -1,4 +1,4 @@ -/* Copyright 2018 The Chromium OS Authors. All rights reserved. +/* Copyright 2018 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -74,8 +74,8 @@ enum mpsse_pins { * propagates data on the falling edge * and reads data on the rising edge of the clock. */ -#define SPI_CMD_TX (MPSSE_DO_WRITE | MPSSE_WRITE_NEG) -#define SPI_CMD_RX (MPSSE_DO_READ) +#define SPI_CMD_TX (MPSSE_DO_WRITE | MPSSE_WRITE_NEG) +#define SPI_CMD_RX (MPSSE_DO_READ) #define SPI_CMD_TXRX (MPSSE_DO_WRITE | MPSSE_DO_READ | MPSSE_WRITE_NEG) static int raw_read(uint8_t *buf, int size) @@ -94,7 +94,7 @@ static int raw_read(uint8_t *buf, int size) static int mpsse_set_pins(uint8_t levels) { - uint8_t buf[MPSSE_CMD_SIZE] = {0}; + uint8_t buf[MPSSE_CMD_SIZE] = { 0 }; buf[0] = SET_BITS_LOW; buf[1] = levels; @@ -103,8 +103,8 @@ static int mpsse_set_pins(uint8_t levels) return ftdi_write_data(&ftdi, buf, sizeof(buf)) != sizeof(buf); } -static int send_request(int cmd, int version, - const uint8_t *outdata, size_t outsize) +static int send_request(int cmd, int version, const uint8_t *outdata, + size_t outsize) { uint8_t *txbuf; struct ec_host_request *request; @@ -133,8 +133,8 @@ static int send_request(int cmd, int version, request->data_len = outsize; /* copy the data to transmit after the command header */ - memcpy(txbuf + MPSSE_CMD_SIZE + sizeof(struct ec_host_request), - outdata, outsize); + memcpy(txbuf + MPSSE_CMD_SIZE + sizeof(struct ec_host_request), outdata, + outsize); /* Compute the checksum */ for (i = MPSSE_CMD_SIZE; i < total_len; i++) @@ -212,13 +212,12 @@ static int get_response(uint8_t *bodydest, size_t bodylen) /* Check the header */ if (hdr.struct_version != EC_HOST_RESPONSE_VERSION) { fprintf(stderr, "response version %d (should be %d)\n", - hdr.struct_version, - EC_HOST_RESPONSE_VERSION); + hdr.struct_version, EC_HOST_RESPONSE_VERSION); return -EC_RES_ERROR; } if (hdr.data_len > bodylen) { - fprintf(stderr, "response data_len %d is > %zd\n", - hdr.data_len, bodylen); + fprintf(stderr, "response data_len %d is > %zd\n", hdr.data_len, + bodylen); return -EC_RES_ERROR; } @@ -243,9 +242,8 @@ read_error: return -EC_RES_ERROR; } -static int ec_command_servo_spi(int cmd, int version, - const void *outdata, int outsize, - void *indata, int insize) +static int ec_command_servo_spi(int cmd, int version, const void *outdata, + int outsize, void *indata, int insize) { int ret = -EC_RES_ERROR; @@ -275,7 +273,7 @@ static int mpsse_set_clock(uint32_t freq) { uint32_t system_clock = 0; uint16_t divisor = 0; - uint8_t buf[MPSSE_CMD_SIZE] = {0}; + uint8_t buf[MPSSE_CMD_SIZE] = { 0 }; if (freq > 6000000) { buf[0] = TCK_X5; @@ -307,10 +305,10 @@ static void servo_spi_close(void) int comm_init_servo_spi(const char *device_name) { int status; - uint8_t buf[MPSSE_CMD_SIZE] = {0}; + uint8_t buf[MPSSE_CMD_SIZE] = { 0 }; /* if the user mentioned a device name, use it as serial string */ - const char *serial = strcmp(CROS_EC_DEV_NAME, device_name) ? - device_name : NULL; + const char *serial = + strcmp(CROS_EC_DEV_NAME, device_name) ? device_name : NULL; if (ftdi_init(&ftdi)) return -EC_RES_ERROR; diff --git a/util/comm-usb.c b/util/comm-usb.c index 9b362aa2f4..3d481b5532 100644 --- a/util/comm-usb.c +++ b/util/comm-usb.c @@ -1,4 +1,4 @@ -/* Copyright 2022 The Chromium OS Authors. All rights reserved. +/* Copyright 2022 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -17,12 +17,11 @@ #include "misc_util.h" #include "usb_descriptor.h" -#define USB_ERROR(m, r) \ - fprintf(stderr, "%s:%d, %s returned %d (%s)\n", __FILE__, __LINE__, \ - m, r, libusb_strerror(r)) +#define USB_ERROR(m, r) print_libusb_error(__FILE__, __LINE__, m, r) #ifdef DEBUG -#define debug(fmt, arg...) printf("%s:%d: " fmt, __FILE__, __LINE__, ##arg) +#define debug(fmt, arg...) \ + fprintf(stderr, "%s:%d: " fmt, __FILE__, __LINE__, ##arg) #else #define debug(...) #endif @@ -36,6 +35,16 @@ struct usb_endpoint { struct usb_endpoint uep; +static void print_libusb_error(const char *file, int line, const char *message, + int error_code) +{ + /* + * TODO(b/247573723): Remove cast when libusb is upgraded. + */ + fprintf(stderr, "%s:%d, %s returned %d (%s)\n", file, line, message, + error_code, libusb_strerror((enum libusb_error)error_code)); +} + void comm_usb_exit(void) { debug("Exit libusb.\n"); @@ -53,21 +62,21 @@ void comm_usb_exit(void) * Actual USB transfer function, <allow_less> indicates that a valid response * (e.g. EC_CMD_GET_BUILD_INFO) could be shorter than <inlen>. * - * Returns enum libusb_error (< 0) or -EECRESULT on error, <outlen> on success. + * Returns enum libusb_error (< 0) or -EECRESULT on error. On success, returns + * actually transferred OUT data size or IN data size if read is performed. */ static int do_xfer(struct usb_endpoint *uep, void *outbuf, int outlen, void *inbuf, int inlen, int allow_less) { - int r, actual; /* Send data out */ if (outbuf && outlen) { actual = 0; r = libusb_bulk_transfer(uep->devh, uep->ep_num, - outbuf, outlen, - &actual, 2000); - if (r < 0) { + (uint8_t *)outbuf, outlen, &actual, + 2000); + if (r != 0) { USB_ERROR("libusb_bulk_transfer", r); return r; } @@ -77,15 +86,19 @@ static int do_xfer(struct usb_endpoint *uep, void *outbuf, int outlen, return -EECRESULT; } } - debug("Sent %d bytes, expecting %d bytes.\n", outlen, inlen); + debug("Sent %d bytes, expecting to receive %d bytes.\n", outlen, inlen); /* Read reply back */ if (inbuf && inlen) { actual = 0; + /* + * libusb_bulk_transfer may time out if actual < inlen and + * actual is a multiple of ep->wMaxPacketSize. + */ r = libusb_bulk_transfer(uep->devh, uep->ep_num | USB_DIR_IN, - inbuf, inlen, - &actual, 5000); - if (r < 0) { + (uint8_t *)inbuf, inlen, &actual, + 5000); + if (r != 0) { USB_ERROR("libusb_bulk_transfer", r); return r; } @@ -96,8 +109,10 @@ static int do_xfer(struct usb_endpoint *uep, void *outbuf, int outlen, } } - debug("Received %d bytes.\n", inlen); - return outlen; + debug("Received %d bytes.\n", actual); + + /* actual is useful for allow_less. */ + return actual; } /* Return iface # or -1 if not found. */ @@ -141,29 +156,37 @@ int parse_vidpid(const char *input, uint16_t *vid_ptr, uint16_t *pid_ptr) { char *copy, *s, *e; + int ret = 1; + copy = strdup(input); s = strchr(copy, ':'); - if (!s) - return 0; + if (!s) { + ret = 0; + goto cleanup; + } *s++ = '\0'; e = NULL; *vid_ptr = strtoul(copy, &e, 16); - if (e && *e) - return 0; + if (e && *e) { + ret = 0; + goto cleanup; + } e = NULL; *pid_ptr = strtoul(s, &e, 16); - if (e && *e) - return 0; - - return 1; + if (e && *e) { + ret = 0; + goto cleanup; + } +cleanup: + free(copy); + return ret; } -static libusb_device_handle *check_device(libusb_device *dev, - uint16_t vid, uint16_t pid, - char *serialno) +static libusb_device_handle *check_device(libusb_device *dev, uint16_t vid, + uint16_t pid, char *serialno) { struct libusb_device_descriptor desc; libusb_device_handle *handle = NULL; @@ -181,7 +204,9 @@ static libusb_device_handle *check_device(libusb_device *dev, if (desc.iSerialNumber) { r = libusb_get_string_descriptor_ascii(handle, - desc.iSerialNumber, (unsigned char *)sn, sizeof(sn)); + desc.iSerialNumber, + (unsigned char *)sn, + sizeof(sn)); if (r > 0) snvalid = 1; } @@ -196,8 +221,8 @@ static libusb_device_handle *check_device(libusb_device *dev, return handle; } -static int find_endpoint(uint16_t vid, uint16_t pid, - char *serialno, struct usb_endpoint *uep) +static int find_endpoint(uint16_t vid, uint16_t pid, char *serialno, + struct usb_endpoint *uep) { int iface_num, r, i; libusb_device **devs; @@ -244,8 +269,8 @@ static int find_endpoint(uint16_t vid, uint16_t pid, return -1; } - debug("Found interface %d endpoint=%d, chunk_len=%d\n", - iface_num, uep->ep_num, uep->chunk_len); + debug("Found interface %d endpoint=%d, chunk_len=%d\n", iface_num, + uep->ep_num, uep->chunk_len); libusb_set_auto_detach_kernel_driver(uep->devh, 1); r = libusb_claim_interface(uep->devh, iface_num); @@ -270,9 +295,8 @@ static int sum_bytes(const void *data, int length) return sum; } -static int ec_command_usb(int command, int version, - const void *outdata, int outsize, - void *indata, int insize) +static int ec_command_usb(int command, int version, const void *outdata, + int outsize, void *indata, int insize) { struct ec_host_request *req; struct ec_host_response *res; @@ -283,13 +307,13 @@ static int ec_command_usb(int command, int version, assert(insize == 0 || indata != NULL); req_len = sizeof(*req) + outsize; - req = malloc(req_len); + req = (struct ec_host_request *)malloc(req_len); res_len = sizeof(*res) + insize; - res = malloc(res_len); + res = (struct ec_host_response *)malloc(res_len); if (req == NULL || res == NULL) goto out; - req->struct_version = EC_HOST_REQUEST_VERSION; /* 3 */ + req->struct_version = EC_HOST_REQUEST_VERSION; /* 3 */ req->checksum = 0; req->command = command; req->command_version = version; @@ -308,9 +332,10 @@ static int ec_command_usb(int command, int version, if (indata) memcpy(indata, &res[1], insize); - if (res->result != EC_RES_SUCCESS) { + if (res->result == EC_RES_SUCCESS) + rv = res->data_len; + else rv = -EECRESULT - res->result; - } out: if (req) @@ -338,4 +363,3 @@ int comm_init_usb(uint16_t vid, uint16_t pid) return 0; } - diff --git a/util/comm-usb.h b/util/comm-usb.h index f821a10fe8..b43d1bf66f 100644 --- a/util/comm-usb.h +++ b/util/comm-usb.h @@ -1,4 +1,4 @@ -/* Copyright 2022 The Chromium OS Authors. All rights reserved. +/* Copyright 2022 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -34,4 +34,4 @@ int comm_init_usb(uint16_t vid, uint16_t pid); */ void comm_usb_exit(void); -#endif /* __UTIL_COMM_USB_H */ +#endif /* __UTIL_COMM_USB_H */ diff --git a/util/compare_build.sh b/util/compare_build.sh index 1b6030453a..e70dcdbed2 100755 --- a/util/compare_build.sh +++ b/util/compare_build.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2020 The Chromium OS Authors. All rights reserved. +# Copyright 2020 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -14,6 +14,7 @@ # * all - All boards that are built by the "buildall" target # * fp - All relevant boards for fingerprint # * stm32 - All boards that use an STM32 chip +# * stm32f0 - All boards that use an STM32F0 family of chip # * stm32f4 - All boards that use an STM32F4 family of chip # * stm32h7 - All boards that use an STM32H7 family of chip # * npcx - " @@ -50,7 +51,7 @@ DEFINE_string 'ref2' "HEAD^" 'Git reference (commit, branch, etc)' DEFINE_boolean 'keep' "${FLAGS_FALSE}" \ 'Remove the temp directory after comparison.' 'k' # Integer type can still be passed blank ("") -DEFINE_integer 'jobs' "-1" 'Number of jobs to pass to make' 'j' +DEFINE_integer 'jobs' "$(nproc)" 'Number of jobs to pass to make' 'j' # When compiling both refs for all boards, mem usage was larger than 32GB. # If you don't have more than 32GB, you probably don't want to build both # refs at the same time. Use the -o flag. @@ -61,6 +62,9 @@ DEFINE_boolean 'private' "${FLAGS_PRIVATE_DEFAULT}" \ # Usage: assoc-add-keys <associate_array_name> [item1 [item2...]] assoc-add-keys() { + # Shellcheck doesn't seem to support nameref variables yet. + # See https://github.com/koalaman/shellcheck/issues/1544. + # shellcheck disable=SC2034,SC2178 local -n arr="${1}" shift @@ -71,6 +75,9 @@ assoc-add-keys() { # Usage: assoc-rm-keys <associate_array_name> [item1 [item2...] assoc-rm-keys() { + # Shellcheck doesn't seem to support nameref variables yet. + # See https://github.com/koalaman/shellcheck/issues/1544. + # shellcheck disable=SC2034,SC2178 local -n arr="${1}" shift @@ -102,6 +109,8 @@ boards-with() { # Usage: parse-boards <associate_array_name> [board-grp1 [board-grp2...]] parse-boards() { + # Shellcheck doesn't seem to support nameref variables yet. + # See https://github.com/koalaman/shellcheck/issues/1544. # shellcheck disable=SC2034 local -n boards="$1" shift @@ -116,6 +125,7 @@ parse-boards() { [all]="$(make-print-boards)" [fp]="dartmonkey bloonchipper nucleo-dartmonkey nucleo-h743zi" [stm32]="$(boards-with 'CHIP[[:space:]:=]*stm32')" + [stm32f0]="$(boards-with 'CHIP_VARIANT[[:space:]:=]*stm32f0')" [stm32f4]="$(boards-with 'CHIP_VARIANT[[:space:]:=]*stm32f4')" [stm32h7]="$(boards-with 'CHIP_VARIANT[[:space:]:=]*stm32h7')" [npcx]="$(boards-with 'CHIP[[:space:]:=]*npcx')" @@ -216,6 +226,7 @@ echo "# Preparing Makefile" cat > "${TMP_DIR}/Makefile" <<HEREDOC ORIGIN ?= $(realpath .) CRYPTOC_DIR ?= $(realpath ../../third_party/cryptoc) +ZEPHYR_BASE ?= $(realpath ../../../src/third_party/zephyr/main) BOARDS ?= ${BOARDS[*]} LINKS ?= ${LINKS[*]} @@ -233,6 +244,7 @@ build-%: ec-% \$(MAKE) --no-print-directory -C \$(@:build-%=ec-%) \\ STATIC_VERSION=1 \\ CRYPTOC_DIR=\$(CRYPTOC_DIR) \\ + ZEPHYR_BASE=\$(ZEPHYR_BASE) \\ \$(addprefix proj-,\$(BOARDS)) @printf " MKDIR %s\n" "\$@" @mkdir -p \$@ diff --git a/util/config_allowed.txt b/util/config_allowed.txt index 933f22a83c..7a8e3ffbba 100644 --- a/util/config_allowed.txt +++ b/util/config_allowed.txt @@ -10,7 +10,6 @@ CONFIG_ACCELGYRO_ICM42607_INT_EVENT CONFIG_ACCELGYRO_ICM426XX_INT_EVENT CONFIG_ACCELGYRO_ICM_I2C CONFIG_ACCELGYRO_LSM6DS0 -CONFIG_ACCELGYRO_LSM6DSM CONFIG_ACCELGYRO_SEC_ADDR_FLAGS CONFIG_ACCEL_CAL_KASA_RADIUS_THRES CONFIG_ACCEL_CAL_MAX_TEMP @@ -31,6 +30,7 @@ CONFIG_ACCEL_LNG2DM CONFIG_ACCEL_LSM6DSM_INT_EVENT CONFIG_ACCEL_LSM6DSO_INT_EVENT CONFIG_ACCEL_STD_REF_FRAME_OLD +CONFIG_ADC CONFIG_ADC_BUTTONS CONFIG_ADC_PROFILE CONFIG_ADC_PROFILE_FAST_CONTINUOUS @@ -175,7 +175,6 @@ CONFIG_CHARGE_STATE_DEBUG CONFIG_CHIPSET_ALDERLAKE CONFIG_CHIPSET_APL_GLK CONFIG_CHIPSET_APOLLOLAKE -CONFIG_CHIPSET_BRASWELL CONFIG_CHIPSET_CANNONLAKE CONFIG_CHIPSET_CEZANNE CONFIG_CHIPSET_COMETLAKE @@ -203,8 +202,8 @@ CONFIG_CHIPSET_SKYLAKE CONFIG_CHIPSET_SLP_S3_L_OVERRIDE CONFIG_CHIPSET_STONEY CONFIG_CHIPSET_TIGERLAKE -CONFIG_CHIPSET_X86_RSMRST_DELAY CONFIG_CHIPSET_X86_RSMRST_AFTER_S5 +CONFIG_CHIPSET_X86_RSMRST_DELAY CONFIG_CHIP_DATA_IN_INIT_ROM CONFIG_CHIP_LFW_USE_ROM_SPI CONFIG_CHIP_MEMORY_REGIONS @@ -388,7 +387,6 @@ CONFIG_EC_PROTECTED_STORAGE_OFF CONFIG_EC_PROTECTED_STORAGE_SIZE CONFIG_EC_WRITABLE_STORAGE_OFF CONFIG_EC_WRITABLE_STORAGE_SIZE -CONFIG_EEPROM CONFIG_ENABLE_JTAG_SELECTION CONFIG_EVENT_LOG_SIZE CONFIG_EXPERIMENTAL_CONSOLE @@ -480,13 +478,6 @@ CONFIG_HOSTCMD_ALIGNED CONFIG_HOSTCMD_AP_SET_SKUID CONFIG_HOSTCMD_BUTTON CONFIG_HOSTCMD_DEBUG_MODE -CONFIG_HOSTCMD_ESPI_EC_CHAN_BITMAP -CONFIG_HOSTCMD_ESPI_EC_MAX_FREQ -CONFIG_HOSTCMD_ESPI_EC_MODE -CONFIG_HOSTCMD_ESPI_RESET_SLP_SX_VW_ON_ESPI_RST -CONFIG_HOSTCMD_ESPI_VW_SLP_S3 -CONFIG_HOSTCMD_ESPI_VW_SLP_S4 -CONFIG_HOSTCMD_ESPI_VW_SLP_S5 CONFIG_HOSTCMD_EVENTS CONFIG_HOSTCMD_FLASHPD CONFIG_HOSTCMD_FLASH_SPI_INFO @@ -507,6 +498,10 @@ CONFIG_HOST_ESPI_VW_POWER_SIGNAL CONFIG_HOST_EVENT64 CONFIG_HOST_EVENT64_REPORT_MASK CONFIG_HOST_EVENT_REPORT_MASK +CONFIG_HOST_INTERFACE_ESPI_EC_CHAN_BITMAP +CONFIG_HOST_INTERFACE_ESPI_EC_MAX_FREQ +CONFIG_HOST_INTERFACE_ESPI_EC_MODE +CONFIG_HOST_INTERFACE_ESPI_VW_SLP_S5RFACE_ESPI_ CONFIG_HOSYCMD_BATTERY_V2 CONFIG_HWTIMER_64BIT CONFIG_HW_CRC @@ -582,11 +577,11 @@ CONFIG_KEYBOARD_IRQ_GPIO CONFIG_KEYBOARD_KSO_BASE CONFIG_KEYBOARD_KSO_HIGH_DRIVE CONFIG_KEYBOARD_LANGUAGE_ID +CONFIG_KEYBOARD_MULTIPLE CONFIG_KEYBOARD_POST_SCAN_CLOCKS CONFIG_KEYBOARD_PRINT_SCAN_TIMES CONFIG_KEYBOARD_RUNTIME_KEYS CONFIG_KEYBOARD_SCANCODE_CALLBACK -CONFIG_KEYBOARD_STRICT_DEBOUNCE CONFIG_KEYBOARD_SUPPRESS_NOISE CONFIG_KEYBOARD_TABLET_MODE_SWITCH CONFIG_KEYBOARD_TEST @@ -618,7 +613,6 @@ CONFIG_LN9310 CONFIG_LOADER_MEM_OFF CONFIG_LOADER_SIZE CONFIG_LOADER_STORAGE_OFF -CONFIG_LOG_MAX_LEVEL CONFIG_LOW_POWER_IDLE_LIMITED CONFIG_LOW_POWER_S0 CONFIG_LOW_POWER_USE_LFIOSC @@ -665,7 +659,6 @@ CONFIG_MEC_SRAM_BASE_START CONFIG_MEC_SRAM_SIZE CONFIG_MEC_TEST_EC_RORW_CRC CONFIG_MEMORY_REGIONS -CONFIG_MFT_INPUT_LFCLK CONFIG_MIA_WDT_VEC CONFIG_MKBP_ CONFIG_MKBP_USE_ @@ -675,6 +668,7 @@ CONFIG_MOTION_MIN_SENSE_WAIT_TIME CONFIG_MOTION_SENSE_RESUME_DELAY_US CONFIG_MOTION_SENSE_SUSPEND_DELAY_US CONFIG_MP4245 +CONFIG_MPU CONFIG_NAME CONFIG_NB7V904M_LPM_OVERRIDE CONFIG_NO_PINHOLD @@ -716,14 +710,13 @@ CONFIG_POWER_SIGNAL_INTERRUPT_STORM_DETECT_THRESHOLD CONFIG_POWER_SIGNAL_RUNTIME_CONFIG CONFIG_POWER_TRACK_HOST_SLEEP_STATE CONFIG_PRESERVE_LOGS -CONFIG_PRINTF_LEGACY_LI_FORMAT +CONFIG_PRINTF_LONG_IS_32BITS CONFIG_PRINT_IN_INT CONFIG_PROGRAM_MEMORY_BASE CONFIG_PROGRAM_MEMORY_BASE_LOAD CONFIG_PS2 CONFIG_PSTORE CONFIG_PVD -CONFIG_PWM CONFIG_PWM_INPUT_LFCLK CONFIG_PWR_STATE_DISCHARGE_FULL CONFIG_RAM_BANKS @@ -800,12 +793,9 @@ CONFIG_SHAREDLIB_SIZE CONFIG_SHAREDLIB_STORAGE_OFF CONFIG_SHAREDMEM_MINIMUM_SIZE CONFIG_SHAREDMEM_MINIMUM_SIZE_RWSIG -CONFIG_SHELL_BACKEND_SERIAL_LOG_LEVEL -CONFIG_SHELL_HELP CONFIG_SIMULATED_BUTTON CONFIG_SLEEP_TIMEOUT_MS CONFIG_SMBUS -CONFIG_SOC CONFIG_SOFTWARE_CLZ CONFIG_SOFTWARE_CTZ CONFIG_SOMETHING @@ -857,6 +847,8 @@ CONFIG_STREAM_USART1 CONFIG_STREAM_USART2 CONFIG_STREAM_USART3 CONFIG_STREAM_USART4 +CONFIG_STREAM_USART5 +CONFIG_STREAM_USART9 CONFIG_STREAM_USB CONFIG_SUPPORT_CHIP_HIBERNATION CONFIG_SUPPRESSED_HOST_COMMANDS @@ -867,7 +859,6 @@ CONFIG_SYNC_COMMAND CONFIG_SYNC_INT_EVENT CONFIG_SYNC_QUEUE_SIZE CONFIG_SYSTEM_UNLOCK -CONFIG_SYS_CLOCK_TICKS_PER_SEC CONFIG_SYV682X_HV_ILIM CONFIG_TASK_LIST CONFIG_TASK_PROFILING @@ -897,8 +888,6 @@ CONFIG_TEST_TASK_LIST CONFIG_TEST_USB_PD_TIMER CONFIG_TEST_USB_PE_SM CONFIG_THERMISTOR_NCP15WB -CONFIG_THREAD_MONITOR -CONFIG_THREAD_NAME CONFIG_THROTTLE_AP_ON_BAT_OLTAGE CONFIG_THROTTLE_AP_ON_BAT_VOLTAGE CONFIG_TICK @@ -1010,6 +999,7 @@ CONFIG_USB_PD_IDENTITY_HW_VERS CONFIG_USB_PD_IDENTITY_SW_VERS CONFIG_USB_PD_INITIAL_DRP_STATE CONFIG_USB_PD_INTERNAL_COMP +CONFIG_USB_PD_ITE_ACTIVE_PORT_COUNT CONFIG_USB_PD_LOW_POWER CONFIG_USB_PD_LOW_POWER_IDLE_WHEN_CONNECTED CONFIG_USB_PD_MANUFACTURER_INFO @@ -1062,7 +1052,6 @@ CONFIG_USB_RAM_ACCESS_TYPE CONFIG_USB_RAM_BASE CONFIG_USB_RAM_SIZE CONFIG_USB_REMOTE_WAKEUP -CONFIG_USB_SELF_POWERED CONFIG_USB_SERIALNO CONFIG_USB_SPI CONFIG_USB_SPI_BUFFER_SIZE @@ -1074,7 +1063,6 @@ CONFIG_WATCHDOG_HELP CONFIG_WATCHDOG_MAX_RETRIES CONFIG_WEBUSB_URL CONFIG_WIRELESS -CONFIG_WIRELESS_CHARGER_P9221_R7 CONFIG_WIRELESS_SUSPEND CONFIG_WLAN_POWER_ACTIVE_LOW CONFIG_WOV_FIFO_THRESH_WORDS @@ -1083,6 +1071,5 @@ CONFIG_WP_ACTIVE_HIGH CONFIG_WP_ALWAYS CONFIG_WP_STORAGE_OFF CONFIG_WP_STORAGE_SIZE -CONFIG_X86_64 CONFIG_ZEPHYR CONFIG_xxx diff --git a/util/config_option_check.py b/util/config_option_check.py index 8bd8ecb1f0..25c026afe5 100755 --- a/util/config_option_check.py +++ b/util/config_option_check.py @@ -1,11 +1,7 @@ #!/usr/bin/env python3 -# Copyright 2015 The Chromium OS Authors. All rights reserved. +# Copyright 2015 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -# -# Ignore indention messages, since legacy scripts use 2 spaces instead of 4. -# pylint: disable=bad-indentation,docstring-section-indent -# pylint: disable=docstring-trailing-quotes """Configuration Option Checker. @@ -13,6 +9,7 @@ Script to ensure that all configuration options for the Chrome EC are defined in config.h. """ from __future__ import print_function + import enum import os import re @@ -21,368 +18,398 @@ import sys class Line(object): - """Class for each changed line in diff output. + """Class for each changed line in diff output. - Attributes: - line_num: The integer line number that this line appears in the file. - string: The literal string of this line. - line_type: '+' or '-' indicating if this line was an addition or - deletion. - """ + Attributes: + line_num: The integer line number that this line appears in the file. + string: The literal string of this line. + line_type: '+' or '-' indicating if this line was an addition or + deletion. + """ - def __init__(self, line_num, string, line_type): - """Inits Line with the line number and the actual string.""" - self.line_num = line_num - self.string = string - self.line_type = line_type + def __init__(self, line_num, string, line_type): + """Inits Line with the line number and the actual string.""" + self.line_num = line_num + self.string = string + self.line_type = line_type class Hunk(object): - """Class for a git diff hunk. + """Class for a git diff hunk. - Attributes: - filename: The name of the file that this hunk belongs to. - lines: A list of Line objects that are a part of this hunk. - """ + Attributes: + filename: The name of the file that this hunk belongs to. + lines: A list of Line objects that are a part of this hunk. + """ - def __init__(self, filename, lines): - """Inits Hunk with the filename and the list of lines of the hunk.""" - self.filename = filename - self.lines = lines + def __init__(self, filename, lines): + """Inits Hunk with the filename and the list of lines of the hunk.""" + self.filename = filename + self.lines = lines # Master file which is supposed to include all CONFIG_xxxx descriptions. -CONFIG_FILE = 'include/config.h' +CONFIG_FILE = "include/config.h" # Specific files which the checker should ignore. -ALLOWLIST = [CONFIG_FILE, 'util/config_option_check.py'] +ALLOWLIST = [CONFIG_FILE, "util/config_option_check.py"] # Specific directories which the checker should ignore. -ALLOW_PATTERN = re.compile('zephyr/.*') +ALLOW_PATTERN = re.compile("zephyr/.*") # Specific CONFIG_* flags which the checker should ignore. -ALLOWLIST_CONFIGS = ['CONFIG_ZTEST'] +ALLOWLIST_CONFIGS = ["CONFIG_ZTEST"] + def obtain_current_config_options(): - """Obtains current config options from include/config.h. - - Scans through the main config file defined in CONFIG_FILE for all CONFIG_* - options. - - Returns: - config_options: A list of all the config options in the main CONFIG_FILE. - """ - - config_options = [] - config_option_re = re.compile(r'^#(define|undef)\s+(CONFIG_[A-Z0-9_]+)') - with open(CONFIG_FILE, 'r') as config_file: - for line in config_file: - result = config_option_re.search(line) - if not result: - continue - word = result.groups()[1] - if word not in config_options: - config_options.append(word) - return config_options + """Obtains current config options from include/config.h. + + Scans through the main config file defined in CONFIG_FILE for all CONFIG_* + options. + + Returns: + config_options: A list of all the config options in the main CONFIG_FILE. + """ + + config_options = [] + config_option_re = re.compile(r"^#(define|undef)\s+(CONFIG_[A-Z0-9_]+)") + with open(CONFIG_FILE, "r") as config_file: + for line in config_file: + result = config_option_re.search(line) + if not result: + continue + word = result.groups()[1] + if word not in config_options: + config_options.append(word) + return config_options + def obtain_config_options_in_use(): - """Obtains all the config options in use in the repo. - - Scans through the entire repo looking for all CONFIG_* options actively used. - - Returns: - options_in_use: A set of all the config options in use in the repo. - """ - file_list = [] - cwd = os.getcwd() - config_option_re = re.compile(r'\b(CONFIG_[a-zA-Z0-9_]+)') - config_debug_option_re = re.compile(r'\b(CONFIG_DEBUG_[a-zA-Z0-9_]+)') - options_in_use = set() - for (dirpath, dirnames, filenames) in os.walk(cwd, topdown=True): - # Ignore the build and private directories (taken from .gitignore) - if 'build' in dirnames: - dirnames.remove('build') - if 'private' in dirnames: - dirnames.remove('private') - for f in filenames: - # Ignore hidden files. - if f.startswith('.'): - continue - # Only consider C source, assembler, and Make-style files. - if (os.path.splitext(f)[1] in ('.c', '.h', '.inc', '.S', '.mk') or - 'Makefile' in f): - file_list.append(os.path.join(dirpath, f)) - - # Search through each file and build a set of the CONFIG_* options being - # used. - - for f in file_list: - if CONFIG_FILE in f: - continue - with open(f, 'r') as cur_file: - for line in cur_file: - match = config_option_re.findall(line) - if match: - for option in match: - if not in_comment(f, line, option): - if option not in options_in_use: - options_in_use.add(option) - - # Since debug options can be turned on at any time, assume that they are - # always in use in case any aren't being used. - - with open(CONFIG_FILE, 'r') as config_file: - for line in config_file: - match = config_debug_option_re.findall(line) - if match: - for option in match: - if not in_comment(CONFIG_FILE, line, option): - if option not in options_in_use: - options_in_use.add(option) - - return options_in_use + """Obtains all the config options in use in the repo. + + Scans through the entire repo looking for all CONFIG_* options actively used. + + Returns: + options_in_use: A set of all the config options in use in the repo. + """ + file_list = [] + cwd = os.getcwd() + config_option_re = re.compile(r"\b(CONFIG_[a-zA-Z0-9_]+)") + config_debug_option_re = re.compile(r"\b(CONFIG_DEBUG_[a-zA-Z0-9_]+)") + options_in_use = set() + for (dirpath, dirnames, filenames) in os.walk(cwd, topdown=True): + # Ignore the build and private directories (taken from .gitignore) + if "build" in dirnames: + dirnames.remove("build") + if "private" in dirnames: + dirnames.remove("private") + for f in filenames: + # Ignore hidden files. + if f.startswith("."): + continue + # Only consider C source, assembler, and Make-style files. + if ( + os.path.splitext(f)[1] in (".c", ".h", ".inc", ".S", ".mk") + or "Makefile" in f + ): + file_list.append(os.path.join(dirpath, f)) + + # Search through each file and build a set of the CONFIG_* options being + # used. + + for f in file_list: + if CONFIG_FILE in f: + continue + with open(f, "r") as cur_file: + for line in cur_file: + match = config_option_re.findall(line) + if match: + for option in match: + if not in_comment(f, line, option): + if option not in options_in_use: + options_in_use.add(option) + + # Since debug options can be turned on at any time, assume that they are + # always in use in case any aren't being used. + + with open(CONFIG_FILE, "r") as config_file: + for line in config_file: + match = config_debug_option_re.findall(line) + if match: + for option in match: + if not in_comment(CONFIG_FILE, line, option): + if option not in options_in_use: + options_in_use.add(option) + + return options_in_use + def print_missing_config_options(hunks, config_options): - """Searches thru all the changes in hunks for missing options and prints them. - - Args: - hunks: A list of Hunk objects which represent the hunks from the git - diff output. - config_options: A list of all the config options in the main CONFIG_FILE. - - Returns: - missing_config_option: A boolean indicating if any CONFIG_* options - are missing from the main CONFIG_FILE in this commit or if any CONFIG_* - options removed are no longer being used in the repo. - """ - missing_config_option = False - print_banner = True - deprecated_options = set() - # Determine longest CONFIG_* length to be used for formatting. - max_option_length = max(len(option) for option in config_options) - config_option_re = re.compile(r'\b(CONFIG_[a-zA-Z0-9_]+)') - - # Search for all CONFIG_* options in use in the repo. - options_in_use = obtain_config_options_in_use() - - # Check each hunk's line for a missing config option. - for h in hunks: - for l in h.lines: - # Check for the existence of a CONFIG_* in the line. - match = filter(lambda opt: opt in ALLOWLIST_CONFIGS, - config_option_re.findall(l.string)) - if not match: - continue - - # At this point, an option was found in the line. However, we need to - # verify that it is not within a comment. - violations = set() - - for option in match: - if not in_comment(h.filename, l.string, option): - # Since the CONFIG_* option is not within a comment, we've found a - # violation. We now need to determine if this line is a deletion or - # not. For deletions, we will need to verify if this CONFIG_* option - # is no longer being used in the entire repo. - - if l.line_type == '-': - if option not in options_in_use and option in config_options: - deprecated_options.add(option) - else: - violations.add(option) - - # Check to see if the CONFIG_* option is in the config file and print the - # violations. - for option in match: - if option not in config_options and option in violations: - # Print the banner once. - if print_banner: - print('The following config options were found to be missing ' - 'from %s.\n' - 'Please add new config options there along with ' - 'descriptions.\n\n' % CONFIG_FILE) - print_banner = False + """Searches thru all the changes in hunks for missing options and prints them. + + Args: + hunks: A list of Hunk objects which represent the hunks from the git + diff output. + config_options: A list of all the config options in the main CONFIG_FILE. + + Returns: + missing_config_option: A boolean indicating if any CONFIG_* options + are missing from the main CONFIG_FILE in this commit or if any CONFIG_* + options removed are no longer being used in the repo. + """ + missing_config_option = False + print_banner = True + deprecated_options = set() + # Determine longest CONFIG_* length to be used for formatting. + max_option_length = max(len(option) for option in config_options) + config_option_re = re.compile(r"\b(CONFIG_[a-zA-Z0-9_]+)") + + # Search for all CONFIG_* options in use in the repo. + options_in_use = obtain_config_options_in_use() + + # Check each hunk's line for a missing config option. + for h in hunks: + for l in h.lines: + # Check for the existence of a CONFIG_* in the line. + match = filter( + lambda opt: opt in ALLOWLIST_CONFIGS, + config_option_re.findall(l.string), + ) + if not match: + continue + + # At this point, an option was found in the line. However, we need to + # verify that it is not within a comment. + violations = set() + + for option in match: + if not in_comment(h.filename, l.string, option): + # Since the CONFIG_* option is not within a comment, we've found a + # violation. We now need to determine if this line is a deletion or + # not. For deletions, we will need to verify if this CONFIG_* option + # is no longer being used in the entire repo. + + if l.line_type == "-": + if ( + option not in options_in_use + and option in config_options + ): + deprecated_options.add(option) + else: + violations.add(option) + + # Check to see if the CONFIG_* option is in the config file and print the + # violations. + for option in match: + if option not in config_options and option in violations: + # Print the banner once. + if print_banner: + print( + "The following config options were found to be missing " + "from %s.\n" + "Please add new config options there along with " + "descriptions.\n\n" % CONFIG_FILE + ) + print_banner = False + missing_config_option = True + # Print the misssing config option. + print( + "> %-*s %s:%s" + % (max_option_length, option, h.filename, l.line_num) + ) + + if deprecated_options: + print( + "\n\nThe following config options are being removed and also appear" + " to be the last uses\nof that option. Please remove these " + "options from %s.\n\n" % CONFIG_FILE + ) + for option in deprecated_options: + print("> %s" % option) missing_config_option = True - # Print the misssing config option. - print('> %-*s %s:%s' % (max_option_length, option, - h.filename, - l.line_num)) - if deprecated_options: - print('\n\nThe following config options are being removed and also appear' - ' to be the last uses\nof that option. Please remove these ' - 'options from %s.\n\n' % CONFIG_FILE) - for option in deprecated_options: - print('> %s' % option) - missing_config_option = True + return missing_config_option - return missing_config_option def in_comment(filename, line, substr): - """Checks if given substring appears in a comment. - - Args: - filename: The filename where this line is from. This is used to determine - what kind of comments to look for. - line: String of line to search in. - substr: Substring to search for in the line. - - Returns: - is_in_comment: Boolean indicating if substr was in a comment. - """ - - c_style_ext = ('.c', '.h', '.inc', '.S') - make_style_ext = ('.mk') - is_in_comment = False - - extension = os.path.splitext(filename)[1] - substr_idx = line.find(substr) - - # Different files have different comment syntax; Handle appropriately. - if extension in c_style_ext: - beg_comment_idx = line.find('/*') - end_comment_idx = line.find('*/') - if end_comment_idx == -1: - end_comment_idx = len(line) - - if beg_comment_idx == -1: - # Check to see if this line is from a multi-line comment. - if line.lstrip().startswith('* '): - # It _seems_ like it is. - is_in_comment = True - else: - # Check to see if its actually inside the comment. - if beg_comment_idx < substr_idx < end_comment_idx: - is_in_comment = True - elif extension in make_style_ext or 'Makefile' in filename: - beg_comment_idx = line.find('#') - # Ignore everything to the right of the hash. - if beg_comment_idx < substr_idx and beg_comment_idx != -1: - is_in_comment = True - return is_in_comment + """Checks if given substring appears in a comment. + + Args: + filename: The filename where this line is from. This is used to determine + what kind of comments to look for. + line: String of line to search in. + substr: Substring to search for in the line. + + Returns: + is_in_comment: Boolean indicating if substr was in a comment. + """ + + c_style_ext = (".c", ".h", ".inc", ".S") + make_style_ext = ".mk" + is_in_comment = False + + extension = os.path.splitext(filename)[1] + substr_idx = line.find(substr) + + # Different files have different comment syntax; Handle appropriately. + if extension in c_style_ext: + beg_comment_idx = line.find("/*") + end_comment_idx = line.find("*/") + if end_comment_idx == -1: + end_comment_idx = len(line) + + if beg_comment_idx == -1: + # Check to see if this line is from a multi-line comment. + if line.lstrip().startswith("* "): + # It _seems_ like it is. + is_in_comment = True + else: + # Check to see if its actually inside the comment. + if beg_comment_idx < substr_idx < end_comment_idx: + is_in_comment = True + elif extension in make_style_ext or "Makefile" in filename: + beg_comment_idx = line.find("#") + # Ignore everything to the right of the hash. + if beg_comment_idx < substr_idx and beg_comment_idx != -1: + is_in_comment = True + return is_in_comment + def get_hunks(): - """Gets the hunks of the most recent commit. - - States: - new_file: Searching for a new file in the git diff. - filename_search: Searching for the filename of this hunk. - hunk: Searching for the beginning of a new hunk. - lines: Counting line numbers and searching for changes. - - Returns: - hunks: A list of Hunk objects which represent the hunks in the git diff - output. - """ - - diff = [] - hunks = [] - hunk_lines = [] - line = '' - filename = '' - i = 0 - line_num = 0 - - # Regex patterns - new_file_re = re.compile(r'^diff --git') - filename_re = re.compile(r'^[+]{3} (.*)') - hunk_line_num_re = re.compile(r'^@@ -[0-9]+,[0-9]+ \+([0-9]+),[0-9]+ @@.*') - line_re = re.compile(r'^([+| |-])(.*)') - - # Get the diff output. - proc = subprocess.run(['git', 'diff', '--cached', '-GCONFIG_*', '--no-prefix', - '--no-ext-diff', 'HEAD~1'], - stdout=subprocess.PIPE, - encoding='utf-8', - check=True) - diff = proc.stdout.splitlines() - if not diff: - return [] - line = diff[0] - - state = enum.Enum('state', 'NEW_FILE FILENAME_SEARCH HUNK LINES') - current_state = state.NEW_FILE - - while True: - # Search for the beginning of a new file. - if current_state is state.NEW_FILE: - match = new_file_re.search(line) - if match: - current_state = state.FILENAME_SEARCH - - # Search the diff output for a file name. - elif current_state is state.FILENAME_SEARCH: - # Search for a file name. - match = filename_re.search(line) - if match: - filename = match.groups(1)[0] - if filename in ALLOWLIST or ALLOW_PATTERN.match(filename): - # Skip the file if it's allowlisted. - current_state = state.NEW_FILE - else: - current_state = state.HUNK - - # Search for a hunk. Each hunk starts with a line describing the line - # numbers in the file. - elif current_state is state.HUNK: - hunk_lines = [] - match = hunk_line_num_re.search(line) - if match: - # Extract the line number offset. - line_num = int(match.groups(1)[0]) - current_state = state.LINES - - # Start looking for changes. - elif current_state is state.LINES: - # Check if state needs updating. - new_hunk = hunk_line_num_re.search(line) - new_file = new_file_re.search(line) - if new_hunk: - current_state = state.HUNK - hunks.append(Hunk(filename, hunk_lines)) - continue - elif new_file: - current_state = state.NEW_FILE - hunks.append(Hunk(filename, hunk_lines)) - continue - - match = line_re.search(line) - if match: - line_type = match.groups(1)[0] - # We only care about modifications. - if line_type != ' ': - hunk_lines.append(Line(line_num, match.groups(2)[1], line_type)) - # Deletions don't count towards the line numbers. - if line_type != '-': - line_num += 1 - - # Advance to the next line - try: - i += 1 - line = diff[i] - except IndexError: - # We've reached the end of the diff. Return what we have. - if hunk_lines: - hunks.append(Hunk(filename, hunk_lines)) - return hunks + """Gets the hunks of the most recent commit. + + States: + new_file: Searching for a new file in the git diff. + filename_search: Searching for the filename of this hunk. + hunk: Searching for the beginning of a new hunk. + lines: Counting line numbers and searching for changes. + + Returns: + hunks: A list of Hunk objects which represent the hunks in the git diff + output. + """ + + diff = [] + hunks = [] + hunk_lines = [] + line = "" + filename = "" + i = 0 + line_num = 0 + + # Regex patterns + new_file_re = re.compile(r"^diff --git") + filename_re = re.compile(r"^[+]{3} (.*)") + hunk_line_num_re = re.compile(r"^@@ -[0-9]+,[0-9]+ \+([0-9]+),[0-9]+ @@.*") + line_re = re.compile(r"^([+| |-])(.*)") + + # Get the diff output. + proc = subprocess.run( + [ + "git", + "diff", + "--cached", + "-GCONFIG_*", + "--no-prefix", + "--no-ext-diff", + "HEAD~1", + ], + stdout=subprocess.PIPE, + encoding="utf-8", + check=True, + ) + diff = proc.stdout.splitlines() + if not diff: + return [] + line = diff[0] + + state = enum.Enum("state", "NEW_FILE FILENAME_SEARCH HUNK LINES") + current_state = state.NEW_FILE + + while True: + # Search for the beginning of a new file. + if current_state is state.NEW_FILE: + match = new_file_re.search(line) + if match: + current_state = state.FILENAME_SEARCH + + # Search the diff output for a file name. + elif current_state is state.FILENAME_SEARCH: + # Search for a file name. + match = filename_re.search(line) + if match: + filename = match.groups(1)[0] + if filename in ALLOWLIST or ALLOW_PATTERN.match(filename): + # Skip the file if it's allowlisted. + current_state = state.NEW_FILE + else: + current_state = state.HUNK + + # Search for a hunk. Each hunk starts with a line describing the line + # numbers in the file. + elif current_state is state.HUNK: + hunk_lines = [] + match = hunk_line_num_re.search(line) + if match: + # Extract the line number offset. + line_num = int(match.groups(1)[0]) + current_state = state.LINES + + # Start looking for changes. + elif current_state is state.LINES: + # Check if state needs updating. + new_hunk = hunk_line_num_re.search(line) + new_file = new_file_re.search(line) + if new_hunk: + current_state = state.HUNK + hunks.append(Hunk(filename, hunk_lines)) + continue + elif new_file: + current_state = state.NEW_FILE + hunks.append(Hunk(filename, hunk_lines)) + continue + + match = line_re.search(line) + if match: + line_type = match.groups(1)[0] + # We only care about modifications. + if line_type != " ": + hunk_lines.append( + Line(line_num, match.groups(2)[1], line_type) + ) + # Deletions don't count towards the line numbers. + if line_type != "-": + line_num += 1 + + # Advance to the next line + try: + i += 1 + line = diff[i] + except IndexError: + # We've reached the end of the diff. Return what we have. + if hunk_lines: + hunks.append(Hunk(filename, hunk_lines)) + return hunks + def main(): - """Searches through committed changes for missing config options. - - Checks through committed changes for CONFIG_* options. Then checks to make - sure that all CONFIG_* options used are defined in include/config.h. Finally, - reports any missing config options. - """ - # Obtain the hunks of the commit to search through. - hunks = get_hunks() - # Obtain config options from include/config.h. - config_options = obtain_current_config_options() - # Find any missing config options from the hunks and print them. - missing_opts = print_missing_config_options(hunks, config_options) - - if missing_opts: - print('\nIt may also be possible that you have a typo.') - sys.exit(1) - -if __name__ == '__main__': - main() + """Searches through committed changes for missing config options. + + Checks through committed changes for CONFIG_* options. Then checks to make + sure that all CONFIG_* options used are defined in include/config.h. Finally, + reports any missing config options. + """ + # Obtain the hunks of the commit to search through. + hunks = get_hunks() + # Obtain config options from include/config.h. + config_options = obtain_current_config_options() + # Find any missing config options from the hunks and print them. + missing_opts = print_missing_config_options(hunks, config_options) + + if missing_opts: + print("\nIt may also be possible that you have a typo.") + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/util/cros_ec_dev.h b/util/cros_ec_dev.h index 41930f97dd..3ffed56632 100644 --- a/util/cros_ec_dev.h +++ b/util/cros_ec_dev.h @@ -1,4 +1,4 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. +/* Copyright 2013 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -50,9 +50,9 @@ struct cros_ec_readmem { char *buffer; }; -#define CROS_EC_DEV_IOC ':' -#define CROS_EC_DEV_IOCXCMD _IOWR(':', 0, struct cros_ec_command) -#define CROS_EC_DEV_IOCRDMEM _IOWR(':', 1, struct cros_ec_readmem) +#define CROS_EC_DEV_IOC ':' +#define CROS_EC_DEV_IOCXCMD _IOWR(':', 0, struct cros_ec_command) +#define CROS_EC_DEV_IOCRDMEM _IOWR(':', 1, struct cros_ec_readmem) /* * @version: Command version number (often 0) @@ -84,12 +84,12 @@ struct cros_ec_readmem_v2 { uint8_t buffer[EC_MEMMAP_SIZE]; }; -#define CROS_EC_DEV_IOC_V2 0xEC -#define CROS_EC_DEV_IOCXCMD_V2 _IOWR(CROS_EC_DEV_IOC_V2, 0, \ - struct cros_ec_command_v2) -#define CROS_EC_DEV_IOCRDMEM_V2 _IOWR(CROS_EC_DEV_IOC_V2, 1, \ - struct cros_ec_readmem_v2) -#define CROS_EC_DEV_IOCEVENTMASK_V2 _IO(CROS_EC_DEV_IOC_V2, 2) +#define CROS_EC_DEV_IOC_V2 0xEC +#define CROS_EC_DEV_IOCXCMD_V2 \ + _IOWR(CROS_EC_DEV_IOC_V2, 0, struct cros_ec_command_v2) +#define CROS_EC_DEV_IOCRDMEM_V2 \ + _IOWR(CROS_EC_DEV_IOC_V2, 1, struct cros_ec_readmem_v2) +#define CROS_EC_DEV_IOCEVENTMASK_V2 _IO(CROS_EC_DEV_IOC_V2, 2) #ifdef __cplusplus } diff --git a/util/dt-gpionames/dt.go b/util/dt-gpionames/dt.go index 547d69708f..9e95aeb946 100644 --- a/util/dt-gpionames/dt.go +++ b/util/dt-gpionames/dt.go @@ -1,4 +1,4 @@ -// Copyright 2022 The Chromium OS Authors. All rights reserved. +// Copyright 2022 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/util/dt-gpionames/gpionames.sh b/util/dt-gpionames/gpionames.sh index 92b2bd4580..972dbbacd9 100755 --- a/util/dt-gpionames/gpionames.sh +++ b/util/dt-gpionames/gpionames.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2022 The Chromium OS Authors. All rights reserved. +# Copyright 2022 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/util/ec3po/__init__.py b/util/ec3po/__init__.py index 376ffdba04..b3534114ac 100644 --- a/util/ec3po/__init__.py +++ b/util/ec3po/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2015 The Chromium OS Authors. All rights reserved. +# Copyright 2015 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/util/ec3po/console.py b/util/ec3po/console.py index e71216e3f2..12b31baa60 100755 --- a/util/ec3po/console.py +++ b/util/ec3po/console.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright 2015 The Chromium OS Authors. All rights reserved. +# Copyright 2015 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -17,7 +17,6 @@ from __future__ import print_function import argparse import binascii import ctypes -from datetime import datetime import logging import os import pty @@ -26,26 +25,25 @@ import select import stat import sys import traceback +from datetime import datetime import six +from ec3po import interpreter, threadproc_shim -from ec3po import interpreter -from ec3po import threadproc_shim - - -PROMPT = b'> ' +PROMPT = b"> " CONSOLE_INPUT_LINE_SIZE = 80 # Taken from the CONFIG_* with the same name. CONSOLE_MAX_READ = 100 # Max bytes to read at a time from the user. LOOK_BUFFER_SIZE = 256 # Size of search window when looking for the enhanced EC - # image string. +# image string. # In console_init(), the EC will print a string saying that the EC console is # enabled. Enhanced images will print a slightly different string. These # regular expressions are used to determine at reboot whether the EC image is # enhanced or not. -ENHANCED_IMAGE_RE = re.compile(br'Enhanced Console is enabled ' - br'\(v([0-9]+\.[0-9]+\.[0-9]+)\)') -NON_ENHANCED_IMAGE_RE = re.compile(br'Console is enabled; ') +ENHANCED_IMAGE_RE = re.compile( + rb"Enhanced Console is enabled " rb"\(v([0-9]+\.[0-9]+\.[0-9]+)\)" +) +NON_ENHANCED_IMAGE_RE = re.compile(rb"Console is enabled; ") # The timeouts are really only useful for enhanced EC images, but otherwise just # serve as a delay for non-enhanced EC images. Therefore, we can keep this @@ -54,1118 +52,1225 @@ NON_ENHANCED_IMAGE_RE = re.compile(br'Console is enabled; ') # EC image, we can increase the timeout for stability just in case it takes a # bit longer to receive an ACK for some reason. NON_ENHANCED_EC_INTERROGATION_TIMEOUT = 0.3 # Maximum number of seconds to wait - # for a response to an - # interrogation of a non-enhanced - # EC image. +# for a response to an +# interrogation of a non-enhanced +# EC image. ENHANCED_EC_INTERROGATION_TIMEOUT = 1.0 # Maximum number of seconds to wait for - # a response to an interrogation of an - # enhanced EC image. +# a response to an interrogation of an +# enhanced EC image. # List of modes which control when interrogations are performed with the EC. -INTERROGATION_MODES = [b'never', b'always', b'auto'] +INTERROGATION_MODES = [b"never", b"always", b"auto"] # Format for printing host timestamp -HOST_STRFTIME="%y-%m-%d %H:%M:%S.%f" +HOST_STRFTIME = "%y-%m-%d %H:%M:%S.%f" class EscState(object): - """Class which contains an enumeration for states of ESC sequences.""" - ESC_START = 1 - ESC_BRACKET = 2 - ESC_BRACKET_1 = 3 - ESC_BRACKET_3 = 4 - ESC_BRACKET_8 = 5 - + """Class which contains an enumeration for states of ESC sequences.""" -class ControlKey(object): - """Class which contains codes for various control keys.""" - BACKSPACE = 0x08 - CTRL_A = 0x01 - CTRL_B = 0x02 - CTRL_D = 0x04 - CTRL_E = 0x05 - CTRL_F = 0x06 - CTRL_K = 0x0b - CTRL_N = 0xe - CTRL_P = 0x10 - CARRIAGE_RETURN = 0x0d - ESC = 0x1b + ESC_START = 1 + ESC_BRACKET = 2 + ESC_BRACKET_1 = 3 + ESC_BRACKET_3 = 4 + ESC_BRACKET_8 = 5 -class Console(object): - """Class which provides the console interface between the EC and the user. - - This class essentially represents the console interface between the user and - the EC. It handles all of the console editing behaviour - - Attributes: - logger: A logger for this module. - controller_pty: File descriptor to the controller side of the PTY. Used for - driving output to the user and receiving user input. - user_pty: A string representing the PTY name of the served console. - cmd_pipe: A socket.socket or multiprocessing.Connection object which - represents the console side of the command pipe. This must be a - bidirectional pipe. Console commands and responses utilize this pipe. - dbg_pipe: A socket.socket or multiprocessing.Connection object which - represents the console's read-only side of the debug pipe. This must be a - unidirectional pipe attached to the intepreter. EC debug messages use - this pipe. - oobm_queue: A queue.Queue or multiprocessing.Queue which is used for out of - band management for the interactive console. - input_buffer: A string representing the current input command. - input_buffer_pos: An integer representing the current position in the buffer - to insert a char. - partial_cmd: A string representing the command entered on a line before - pressing the up arrow keys. - esc_state: An integer represeting the current state within an escape - sequence. - line_limit: An integer representing the maximum number of characters on a - line. - history: A list of strings containing the past entered console commands. - history_pos: An integer representing the current history buffer position. - This index is used to show previous commands. - prompt: A string representing the console prompt displayed to the user. - enhanced_ec: A boolean indicating if the EC image that we are currently - communicating with is enhanced or not. Enhanced EC images will support - packed commands and host commands over the UART. This defaults to False - until we perform some handshaking. - interrogation_timeout: A float representing the current maximum seconds to - wait for a response to an interrogation. - receiving_oobm_cmd: A boolean indicating whether or not the console is in - the middle of receiving an out of band command. - pending_oobm_cmd: A string containing the pending OOBM command. - interrogation_mode: A string containing the current mode of whether - interrogations are performed with the EC or not and how often. - raw_debug: Flag to indicate whether per interrupt data should be logged to - debug - output_line_log_buffer: buffer for lines coming from the EC to log to debug - """ - - def __init__(self, controller_pty, user_pty, interface_pty, cmd_pipe, dbg_pipe, - name=None): - """Initalises a Console object with the provided arguments. +class ControlKey(object): + """Class which contains codes for various control keys.""" - Args: - controller_pty: File descriptor to the controller side of the PTY. Used for - driving output to the user and receiving user input. - user_pty: A string representing the PTY name of the served console. - interface_pty: A string representing the PTY name of the served command - interface. - cmd_pipe: A socket.socket or multiprocessing.Connection object which - represents the console side of the command pipe. This must be a - bidirectional pipe. Console commands and responses utilize this pipe. - dbg_pipe: A socket.socket or multiprocessing.Connection object which - represents the console's read-only side of the debug pipe. This must be a - unidirectional pipe attached to the intepreter. EC debug messages use - this pipe. - name: the console source name - """ - # Create a unique logger based on the console name - console_prefix = ('%s - ' % name) if name else '' - logger = logging.getLogger('%sEC3PO.Console' % console_prefix) - self.logger = interpreter.LoggerAdapter(logger, {'pty': user_pty}) - self.controller_pty = controller_pty - self.user_pty = user_pty - self.interface_pty = interface_pty - self.cmd_pipe = cmd_pipe - self.dbg_pipe = dbg_pipe - self.oobm_queue = threadproc_shim.Queue() - self.input_buffer = b'' - self.input_buffer_pos = 0 - self.partial_cmd = b'' - self.esc_state = 0 - self.line_limit = CONSOLE_INPUT_LINE_SIZE - self.history = [] - self.history_pos = 0 - self.prompt = PROMPT - self.enhanced_ec = False - self.interrogation_timeout = NON_ENHANCED_EC_INTERROGATION_TIMEOUT - self.receiving_oobm_cmd = False - self.pending_oobm_cmd = b'' - self.interrogation_mode = b'auto' - self.timestamp_enabled = True - self.look_buffer = b'' - self.raw_debug = False - self.output_line_log_buffer = [] - - def __str__(self): - """Show internal state of Console object as a string.""" - string = [] - string.append('controller_pty: %s' % self.controller_pty) - string.append('user_pty: %s' % self.user_pty) - string.append('interface_pty: %s' % self.interface_pty) - string.append('cmd_pipe: %s' % self.cmd_pipe) - string.append('dbg_pipe: %s' % self.dbg_pipe) - string.append('oobm_queue: %s' % self.oobm_queue) - string.append('input_buffer: %s' % self.input_buffer) - string.append('input_buffer_pos: %d' % self.input_buffer_pos) - string.append('esc_state: %d' % self.esc_state) - string.append('line_limit: %d' % self.line_limit) - string.append('history: %r' % self.history) - string.append('history_pos: %d' % self.history_pos) - string.append('prompt: %r' % self.prompt) - string.append('partial_cmd: %r'% self.partial_cmd) - string.append('interrogation_mode: %r' % self.interrogation_mode) - string.append('look_buffer: %r' % self.look_buffer) - return '\n'.join(string) - - def LogConsoleOutput(self, data): - """Log to debug user MCU output to controller_pty when line is filled. - - The logging also suppresses the Cr50 spinner lines by removing characters - when it sees backspaces. + BACKSPACE = 0x08 + CTRL_A = 0x01 + CTRL_B = 0x02 + CTRL_D = 0x04 + CTRL_E = 0x05 + CTRL_F = 0x06 + CTRL_K = 0x0B + CTRL_N = 0xE + CTRL_P = 0x10 + CARRIAGE_RETURN = 0x0D + ESC = 0x1B - Args: - data: bytes - string received from MCU - """ - data = list(data) - # For compatibility with python2 and python3, standardize on the data - # being a list of integers. This requires one more transformation in py2 - if not isinstance(data[0], int): - data = [ord(c) for c in data] - - # This is a list of already filtered characters (or placeholders). - line = self.output_line_log_buffer - - # TODO(b/177480273): use raw strings here - symbols = { - ord(b'\n'): u'\\n', - ord(b'\r'): u'\\r', - ord(b'\t'): u'\\t' - } - # self.logger.debug(u'%s + %r', u''.join(line), ''.join(data)) - while data: - # Recall, data is a list of integers, namely the byte values sent by - # the MCU. - byte = data.pop(0) - # This means that |byte| is an int. - if byte == ord('\n'): - line.append(symbols[byte]) - if line: - self.logger.debug(u'%s', ''.join(line)) - line = [] - elif byte == ord('\b'): - # Backspace: trim the last character off the buffer - if line: - line.pop(-1) - elif byte in symbols: - line.append(symbols[byte]) - elif byte < ord(' ') or byte > ord('~'): - # Turn any character that isn't printable ASCII into escaped hex. - # ' ' is chr(20), and 0-19 are unprintable control characters. - # '~' is chr(126), and 127 is DELETE. 128-255 are control and Latin-1. - line.append(u'\\x%02x' % byte) - else: - # byte is printable. Thus it is safe to use chr() to get the printable - # character out of it again. - line.append(u'%s' % chr(byte)) - self.output_line_log_buffer = line - - def PrintHistory(self): - """Print the history of entered commands.""" - fd = self.controller_pty - # Make it pretty by figuring out how wide to pad the numbers. - wide = (len(self.history) // 10) + 1 - for i in range(len(self.history)): - line = b' %*d %s\r\n' % (wide, i, self.history[i]) - os.write(fd, line) - - def ShowPreviousCommand(self): - """Shows the previous command from the history list.""" - # There's nothing to do if there's no history at all. - if not self.history: - self.logger.debug('No history to print.') - return - - # Don't do anything if there's no more history to show. - if self.history_pos == 0: - self.logger.debug('No more history to show.') - return - - self.logger.debug('current history position: %d.', self.history_pos) - - # Decrement the history buffer position. - self.history_pos -= 1 - self.logger.debug('new history position.: %d', self.history_pos) - - # Save the text entered on the console if any. - if self.history_pos == len(self.history)-1: - self.logger.debug('saving partial_cmd: %r', self.input_buffer) - self.partial_cmd = self.input_buffer - - # Backspace the line. - for _ in range(self.input_buffer_pos): - self.SendBackspace() - - # Print the last entry in the history buffer. - self.logger.debug('printing previous entry %d - %s', self.history_pos, - self.history[self.history_pos]) - fd = self.controller_pty - prev_cmd = self.history[self.history_pos] - os.write(fd, prev_cmd) - # Update the input buffer. - self.input_buffer = prev_cmd - self.input_buffer_pos = len(prev_cmd) - - def ShowNextCommand(self): - """Shows the next command from the history list.""" - # Don't do anything if there's no history at all. - if not self.history: - self.logger.debug('History buffer is empty.') - return - - fd = self.controller_pty - - self.logger.debug('current history position: %d', self.history_pos) - # Increment the history position. - self.history_pos += 1 - - # Restore the partial cmd. - if self.history_pos == len(self.history): - self.logger.debug('Restoring partial command of %r', self.partial_cmd) - # Backspace the line. - for _ in range(self.input_buffer_pos): - self.SendBackspace() - # Print the partially entered command if any. - os.write(fd, self.partial_cmd) - self.input_buffer = self.partial_cmd - self.input_buffer_pos = len(self.input_buffer) - # Now that we've printed it, clear the partial cmd storage. - self.partial_cmd = b'' - # Reset history position. - self.history_pos = len(self.history) - return - - self.logger.debug('new history position: %d', self.history_pos) - if self.history_pos > len(self.history)-1: - self.logger.debug('No more history to show.') - self.history_pos -= 1 - self.logger.debug('Reset history position to %d', self.history_pos) - return - - # Backspace the line. - for _ in range(self.input_buffer_pos): - self.SendBackspace() - - # Print the newer entry from the history buffer. - self.logger.debug('printing next entry %d - %s', self.history_pos, - self.history[self.history_pos]) - next_cmd = self.history[self.history_pos] - os.write(fd, next_cmd) - # Update the input buffer. - self.input_buffer = next_cmd - self.input_buffer_pos = len(next_cmd) - self.logger.debug('new history position: %d.', self.history_pos) - - def SliceOutChar(self): - """Remove a char from the line and shift everything over 1 column.""" - fd = self.controller_pty - # Remove the character at the input_buffer_pos by slicing it out. - self.input_buffer = self.input_buffer[0:self.input_buffer_pos] + \ - self.input_buffer[self.input_buffer_pos+1:] - # Write the rest of the line - moved_col = os.write(fd, self.input_buffer[self.input_buffer_pos:]) - # Write a space to clear out the last char - moved_col += os.write(fd, b' ') - # Update the input buffer position. - self.input_buffer_pos += moved_col - # Reset the cursor - self.MoveCursor('left', moved_col) - - def HandleEsc(self, byte): - """HandleEsc processes escape sequences. - Args: - byte: An integer representing the current byte in the sequence. +class Console(object): + """Class which provides the console interface between the EC and the user. + + This class essentially represents the console interface between the user and + the EC. It handles all of the console editing behaviour + + Attributes: + logger: A logger for this module. + controller_pty: File descriptor to the controller side of the PTY. Used for + driving output to the user and receiving user input. + user_pty: A string representing the PTY name of the served console. + cmd_pipe: A socket.socket or multiprocessing.Connection object which + represents the console side of the command pipe. This must be a + bidirectional pipe. Console commands and responses utilize this pipe. + dbg_pipe: A socket.socket or multiprocessing.Connection object which + represents the console's read-only side of the debug pipe. This must be a + unidirectional pipe attached to the intepreter. EC debug messages use + this pipe. + oobm_queue: A queue.Queue or multiprocessing.Queue which is used for out of + band management for the interactive console. + input_buffer: A string representing the current input command. + input_buffer_pos: An integer representing the current position in the buffer + to insert a char. + partial_cmd: A string representing the command entered on a line before + pressing the up arrow keys. + esc_state: An integer represeting the current state within an escape + sequence. + line_limit: An integer representing the maximum number of characters on a + line. + history: A list of strings containing the past entered console commands. + history_pos: An integer representing the current history buffer position. + This index is used to show previous commands. + prompt: A string representing the console prompt displayed to the user. + enhanced_ec: A boolean indicating if the EC image that we are currently + communicating with is enhanced or not. Enhanced EC images will support + packed commands and host commands over the UART. This defaults to False + until we perform some handshaking. + interrogation_timeout: A float representing the current maximum seconds to + wait for a response to an interrogation. + receiving_oobm_cmd: A boolean indicating whether or not the console is in + the middle of receiving an out of band command. + pending_oobm_cmd: A string containing the pending OOBM command. + interrogation_mode: A string containing the current mode of whether + interrogations are performed with the EC or not and how often. + raw_debug: Flag to indicate whether per interrupt data should be logged to + debug + output_line_log_buffer: buffer for lines coming from the EC to log to debug """ - # We shouldn't be handling an escape sequence if we haven't seen one. - assert self.esc_state != 0 - - if self.esc_state is EscState.ESC_START: - self.logger.debug('ESC_START') - if byte == ord('['): - self.esc_state = EscState.ESC_BRACKET - return - else: - self.logger.error('Unexpected sequence. %c', byte) - self.esc_state = 0 - - elif self.esc_state is EscState.ESC_BRACKET: - self.logger.debug('ESC_BRACKET') - # Left Arrow key was pressed. - if byte == ord('D'): - self.logger.debug('Left arrow key pressed.') - self.MoveCursor('left', 1) - self.esc_state = 0 # Reset the state. - return - - # Right Arrow key. - elif byte == ord('C'): - self.logger.debug('Right arrow key pressed.') - self.MoveCursor('right', 1) - self.esc_state = 0 # Reset the state. - return - - # Up Arrow key. - elif byte == ord('A'): - self.logger.debug('Up arrow key pressed.') - self.ShowPreviousCommand() - # Reset the state. - self.esc_state = 0 # Reset the state. - return - - # Down Arrow key. - elif byte == ord('B'): - self.logger.debug('Down arrow key pressed.') - self.ShowNextCommand() - # Reset the state. - self.esc_state = 0 # Reset the state. - return - - # For some reason, minicom sends a 1 instead of 7. /shrug - # TODO(aaboagye): Figure out why this happens. - elif byte == ord('1') or byte == ord('7'): - self.esc_state = EscState.ESC_BRACKET_1 - - elif byte == ord('3'): - self.esc_state = EscState.ESC_BRACKET_3 - - elif byte == ord('8'): - self.esc_state = EscState.ESC_BRACKET_8 - - else: - self.logger.error(r'Bad or unhandled escape sequence. got ^[%c\(%d)', - chr(byte), byte) - self.esc_state = 0 - return - - elif self.esc_state is EscState.ESC_BRACKET_1: - self.logger.debug('ESC_BRACKET_1') - # HOME key. - if byte == ord('~'): - self.logger.debug('Home key pressed.') - self.MoveCursor('left', self.input_buffer_pos) - self.esc_state = 0 # Reset the state. - self.logger.debug('ESC sequence complete.') - return - - elif self.esc_state is EscState.ESC_BRACKET_3: - self.logger.debug('ESC_BRACKET_3') - # DEL key. - if byte == ord('~'): - self.logger.debug('Delete key pressed.') - if self.input_buffer_pos != len(self.input_buffer): - self.SliceOutChar() - self.esc_state = 0 # Reset the state. - - elif self.esc_state is EscState.ESC_BRACKET_8: - self.logger.debug('ESC_BRACKET_8') - # END key. - if byte == ord('~'): - self.logger.debug('End key pressed.') - self.MoveCursor('right', - len(self.input_buffer) - self.input_buffer_pos) - self.esc_state = 0 # Reset the state. - self.logger.debug('ESC sequence complete.') - return - - else: - self.logger.error('Unexpected sequence. %c', byte) + def __init__( + self, + controller_pty, + user_pty, + interface_pty, + cmd_pipe, + dbg_pipe, + name=None, + ): + """Initalises a Console object with the provided arguments. + + Args: + controller_pty: File descriptor to the controller side of the PTY. Used for + driving output to the user and receiving user input. + user_pty: A string representing the PTY name of the served console. + interface_pty: A string representing the PTY name of the served command + interface. + cmd_pipe: A socket.socket or multiprocessing.Connection object which + represents the console side of the command pipe. This must be a + bidirectional pipe. Console commands and responses utilize this pipe. + dbg_pipe: A socket.socket or multiprocessing.Connection object which + represents the console's read-only side of the debug pipe. This must be a + unidirectional pipe attached to the intepreter. EC debug messages use + this pipe. + name: the console source name + """ + # Create a unique logger based on the console name + console_prefix = ("%s - " % name) if name else "" + logger = logging.getLogger("%sEC3PO.Console" % console_prefix) + self.logger = interpreter.LoggerAdapter(logger, {"pty": user_pty}) + self.controller_pty = controller_pty + self.user_pty = user_pty + self.interface_pty = interface_pty + self.cmd_pipe = cmd_pipe + self.dbg_pipe = dbg_pipe + self.oobm_queue = threadproc_shim.Queue() + self.input_buffer = b"" + self.input_buffer_pos = 0 + self.partial_cmd = b"" self.esc_state = 0 + self.line_limit = CONSOLE_INPUT_LINE_SIZE + self.history = [] + self.history_pos = 0 + self.prompt = PROMPT + self.enhanced_ec = False + self.interrogation_timeout = NON_ENHANCED_EC_INTERROGATION_TIMEOUT + self.receiving_oobm_cmd = False + self.pending_oobm_cmd = b"" + self.interrogation_mode = b"auto" + self.timestamp_enabled = True + self.look_buffer = b"" + self.raw_debug = False + self.output_line_log_buffer = [] + + def __str__(self): + """Show internal state of Console object as a string.""" + string = [] + string.append("controller_pty: %s" % self.controller_pty) + string.append("user_pty: %s" % self.user_pty) + string.append("interface_pty: %s" % self.interface_pty) + string.append("cmd_pipe: %s" % self.cmd_pipe) + string.append("dbg_pipe: %s" % self.dbg_pipe) + string.append("oobm_queue: %s" % self.oobm_queue) + string.append("input_buffer: %s" % self.input_buffer) + string.append("input_buffer_pos: %d" % self.input_buffer_pos) + string.append("esc_state: %d" % self.esc_state) + string.append("line_limit: %d" % self.line_limit) + string.append("history: %r" % self.history) + string.append("history_pos: %d" % self.history_pos) + string.append("prompt: %r" % self.prompt) + string.append("partial_cmd: %r" % self.partial_cmd) + string.append("interrogation_mode: %r" % self.interrogation_mode) + string.append("look_buffer: %r" % self.look_buffer) + return "\n".join(string) + + def LogConsoleOutput(self, data): + """Log to debug user MCU output to controller_pty when line is filled. + + The logging also suppresses the Cr50 spinner lines by removing characters + when it sees backspaces. + + Args: + data: bytes - string received from MCU + """ + data = list(data) + # For compatibility with python2 and python3, standardize on the data + # being a list of integers. This requires one more transformation in py2 + if not isinstance(data[0], int): + data = [ord(c) for c in data] + + # This is a list of already filtered characters (or placeholders). + line = self.output_line_log_buffer + + # TODO(b/177480273): use raw strings here + symbols = {ord(b"\n"): "\\n", ord(b"\r"): "\\r", ord(b"\t"): "\\t"} + # self.logger.debug(u'%s + %r', u''.join(line), ''.join(data)) + while data: + # Recall, data is a list of integers, namely the byte values sent by + # the MCU. + byte = data.pop(0) + # This means that |byte| is an int. + if byte == ord("\n"): + line.append(symbols[byte]) + if line: + self.logger.debug("%s", "".join(line)) + line = [] + elif byte == ord("\b"): + # Backspace: trim the last character off the buffer + if line: + line.pop(-1) + elif byte in symbols: + line.append(symbols[byte]) + elif byte < ord(" ") or byte > ord("~"): + # Turn any character that isn't printable ASCII into escaped hex. + # ' ' is chr(20), and 0-19 are unprintable control characters. + # '~' is chr(126), and 127 is DELETE. 128-255 are control and Latin-1. + line.append("\\x%02x" % byte) + else: + # byte is printable. Thus it is safe to use chr() to get the printable + # character out of it again. + line.append("%s" % chr(byte)) + self.output_line_log_buffer = line + + def PrintHistory(self): + """Print the history of entered commands.""" + fd = self.controller_pty + # Make it pretty by figuring out how wide to pad the numbers. + wide = (len(self.history) // 10) + 1 + for i in range(len(self.history)): + line = b" %*d %s\r\n" % (wide, i, self.history[i]) + os.write(fd, line) + + def ShowPreviousCommand(self): + """Shows the previous command from the history list.""" + # There's nothing to do if there's no history at all. + if not self.history: + self.logger.debug("No history to print.") + return + + # Don't do anything if there's no more history to show. + if self.history_pos == 0: + self.logger.debug("No more history to show.") + return + + self.logger.debug("current history position: %d.", self.history_pos) + + # Decrement the history buffer position. + self.history_pos -= 1 + self.logger.debug("new history position.: %d", self.history_pos) + + # Save the text entered on the console if any. + if self.history_pos == len(self.history) - 1: + self.logger.debug("saving partial_cmd: %r", self.input_buffer) + self.partial_cmd = self.input_buffer + + # Backspace the line. + for _ in range(self.input_buffer_pos): + self.SendBackspace() + + # Print the last entry in the history buffer. + self.logger.debug( + "printing previous entry %d - %s", + self.history_pos, + self.history[self.history_pos], + ) + fd = self.controller_pty + prev_cmd = self.history[self.history_pos] + os.write(fd, prev_cmd) + # Update the input buffer. + self.input_buffer = prev_cmd + self.input_buffer_pos = len(prev_cmd) + + def ShowNextCommand(self): + """Shows the next command from the history list.""" + # Don't do anything if there's no history at all. + if not self.history: + self.logger.debug("History buffer is empty.") + return + + fd = self.controller_pty + + self.logger.debug("current history position: %d", self.history_pos) + # Increment the history position. + self.history_pos += 1 + + # Restore the partial cmd. + if self.history_pos == len(self.history): + self.logger.debug( + "Restoring partial command of %r", self.partial_cmd + ) + # Backspace the line. + for _ in range(self.input_buffer_pos): + self.SendBackspace() + # Print the partially entered command if any. + os.write(fd, self.partial_cmd) + self.input_buffer = self.partial_cmd + self.input_buffer_pos = len(self.input_buffer) + # Now that we've printed it, clear the partial cmd storage. + self.partial_cmd = b"" + # Reset history position. + self.history_pos = len(self.history) + return + + self.logger.debug("new history position: %d", self.history_pos) + if self.history_pos > len(self.history) - 1: + self.logger.debug("No more history to show.") + self.history_pos -= 1 + self.logger.debug("Reset history position to %d", self.history_pos) + return + + # Backspace the line. + for _ in range(self.input_buffer_pos): + self.SendBackspace() + + # Print the newer entry from the history buffer. + self.logger.debug( + "printing next entry %d - %s", + self.history_pos, + self.history[self.history_pos], + ) + next_cmd = self.history[self.history_pos] + os.write(fd, next_cmd) + # Update the input buffer. + self.input_buffer = next_cmd + self.input_buffer_pos = len(next_cmd) + self.logger.debug("new history position: %d.", self.history_pos) + + def SliceOutChar(self): + """Remove a char from the line and shift everything over 1 column.""" + fd = self.controller_pty + # Remove the character at the input_buffer_pos by slicing it out. + self.input_buffer = ( + self.input_buffer[0 : self.input_buffer_pos] + + self.input_buffer[self.input_buffer_pos + 1 :] + ) + # Write the rest of the line + moved_col = os.write(fd, self.input_buffer[self.input_buffer_pos :]) + # Write a space to clear out the last char + moved_col += os.write(fd, b" ") + # Update the input buffer position. + self.input_buffer_pos += moved_col + # Reset the cursor + self.MoveCursor("left", moved_col) + + def HandleEsc(self, byte): + """HandleEsc processes escape sequences. + + Args: + byte: An integer representing the current byte in the sequence. + """ + # We shouldn't be handling an escape sequence if we haven't seen one. + assert self.esc_state != 0 + + if self.esc_state is EscState.ESC_START: + self.logger.debug("ESC_START") + if byte == ord("["): + self.esc_state = EscState.ESC_BRACKET + return + + else: + self.logger.error("Unexpected sequence. %c", byte) + self.esc_state = 0 + + elif self.esc_state is EscState.ESC_BRACKET: + self.logger.debug("ESC_BRACKET") + # Left Arrow key was pressed. + if byte == ord("D"): + self.logger.debug("Left arrow key pressed.") + self.MoveCursor("left", 1) + self.esc_state = 0 # Reset the state. + return + + # Right Arrow key. + elif byte == ord("C"): + self.logger.debug("Right arrow key pressed.") + self.MoveCursor("right", 1) + self.esc_state = 0 # Reset the state. + return + + # Up Arrow key. + elif byte == ord("A"): + self.logger.debug("Up arrow key pressed.") + self.ShowPreviousCommand() + # Reset the state. + self.esc_state = 0 # Reset the state. + return + + # Down Arrow key. + elif byte == ord("B"): + self.logger.debug("Down arrow key pressed.") + self.ShowNextCommand() + # Reset the state. + self.esc_state = 0 # Reset the state. + return + + # For some reason, minicom sends a 1 instead of 7. /shrug + # TODO(aaboagye): Figure out why this happens. + elif byte == ord("1") or byte == ord("7"): + self.esc_state = EscState.ESC_BRACKET_1 + + elif byte == ord("3"): + self.esc_state = EscState.ESC_BRACKET_3 + + elif byte == ord("8"): + self.esc_state = EscState.ESC_BRACKET_8 + + else: + self.logger.error( + r"Bad or unhandled escape sequence. got ^[%c\(%d)", + chr(byte), + byte, + ) + self.esc_state = 0 + return + + elif self.esc_state is EscState.ESC_BRACKET_1: + self.logger.debug("ESC_BRACKET_1") + # HOME key. + if byte == ord("~"): + self.logger.debug("Home key pressed.") + self.MoveCursor("left", self.input_buffer_pos) + self.esc_state = 0 # Reset the state. + self.logger.debug("ESC sequence complete.") + return + + elif self.esc_state is EscState.ESC_BRACKET_3: + self.logger.debug("ESC_BRACKET_3") + # DEL key. + if byte == ord("~"): + self.logger.debug("Delete key pressed.") + if self.input_buffer_pos != len(self.input_buffer): + self.SliceOutChar() + self.esc_state = 0 # Reset the state. + + elif self.esc_state is EscState.ESC_BRACKET_8: + self.logger.debug("ESC_BRACKET_8") + # END key. + if byte == ord("~"): + self.logger.debug("End key pressed.") + self.MoveCursor( + "right", len(self.input_buffer) - self.input_buffer_pos + ) + self.esc_state = 0 # Reset the state. + self.logger.debug("ESC sequence complete.") + return + + else: + self.logger.error("Unexpected sequence. %c", byte) + self.esc_state = 0 + + else: + self.logger.error("Unexpected sequence. %c", byte) + self.esc_state = 0 + + def ProcessInput(self): + """Captures the input determines what actions to take.""" + # There's nothing to do if the input buffer is empty. + if len(self.input_buffer) == 0: + return + + # Don't store 2 consecutive identical commands in the history. + if ( + self.history + and self.history[-1] != self.input_buffer + or not self.history + ): + self.history.append(self.input_buffer) + + # Split the command up by spaces. + line = self.input_buffer.split(b" ") + self.logger.debug("cmd: %s", self.input_buffer) + cmd = line[0].lower() + + # The 'history' command is a special case that we handle locally. + if cmd == "history": + self.PrintHistory() + return + + # Send the command to the interpreter. + self.logger.debug("Sending command to interpreter.") + self.cmd_pipe.send(self.input_buffer) + + def CheckForEnhancedECImage(self): + """Performs an interrogation of the EC image. + + Send a SYN and expect an ACK. If no ACK or the response is incorrect, then + assume that the current EC image that we are talking to is not enhanced. + + Returns: + is_enhanced: A boolean indicating whether the EC responded to the + interrogation correctly. + + Raises: + EOFError: Allowed to propagate through from self.dbg_pipe.recv(). + """ + # Send interrogation byte and wait for the response. + self.logger.debug("Performing interrogation.") + self.cmd_pipe.send(interpreter.EC_SYN) + + response = "" + if self.dbg_pipe.poll(self.interrogation_timeout): + response = self.dbg_pipe.recv() + self.logger.debug("response: %r", binascii.hexlify(response)) + else: + self.logger.debug("Timed out waiting for EC_ACK") + + # Verify the acknowledgment. + is_enhanced = response == interpreter.EC_ACK + + if is_enhanced: + # Increase the interrogation timeout for stability purposes. + self.interrogation_timeout = ENHANCED_EC_INTERROGATION_TIMEOUT + self.logger.debug( + "Increasing interrogation timeout to %rs.", + self.interrogation_timeout, + ) + else: + # Reduce the timeout in order to reduce the perceivable delay. + self.interrogation_timeout = NON_ENHANCED_EC_INTERROGATION_TIMEOUT + self.logger.debug( + "Reducing interrogation timeout to %rs.", + self.interrogation_timeout, + ) + + return is_enhanced + + def HandleChar(self, byte): + """HandleChar does a certain action when it receives a character. + + Args: + byte: An integer representing the character received from the user. + + Raises: + EOFError: Allowed to propagate through from self.CheckForEnhancedECImage() + i.e. from self.dbg_pipe.recv(). + """ + fd = self.controller_pty + + # Enter the OOBM prompt mode if the user presses '%'. + if byte == ord("%"): + self.logger.debug("Begin OOBM command.") + self.receiving_oobm_cmd = True + # Print a "prompt". + os.write(self.controller_pty, b"\r\n% ") + return + + # Add chars to the pending OOBM command if we're currently receiving one. + if self.receiving_oobm_cmd and byte != ControlKey.CARRIAGE_RETURN: + tmp_bytes = six.int2byte(byte) + self.pending_oobm_cmd += tmp_bytes + self.logger.debug("%s", tmp_bytes) + os.write(self.controller_pty, tmp_bytes) + return + + if byte == ControlKey.CARRIAGE_RETURN: + if self.receiving_oobm_cmd: + # Terminate the command and place it in the OOBM queue. + self.logger.debug("End OOBM command.") + if self.pending_oobm_cmd: + self.oobm_queue.put(self.pending_oobm_cmd) + self.logger.debug( + "Placed %r into OOBM command queue.", + self.pending_oobm_cmd, + ) + + # Reset the state. + os.write(self.controller_pty, b"\r\n" + self.prompt) + self.input_buffer = b"" + self.input_buffer_pos = 0 + self.receiving_oobm_cmd = False + self.pending_oobm_cmd = b"" + return + + if self.interrogation_mode == b"never": + self.logger.debug( + "Skipping interrogation because interrogation mode" + " is set to never." + ) + elif self.interrogation_mode == b"always": + # Only interrogate the EC if the interrogation mode is set to 'always'. + self.enhanced_ec = self.CheckForEnhancedECImage() + self.logger.debug("Enhanced EC image? %r", self.enhanced_ec) + + if not self.enhanced_ec: + # Send everything straight to the EC to handle. + self.cmd_pipe.send(six.int2byte(byte)) + # Reset the input buffer. + self.input_buffer = b"" + self.input_buffer_pos = 0 + self.logger.log(1, "Reset input buffer.") + return + + # Keep handling the ESC sequence if we're in the middle of it. + if self.esc_state != 0: + self.HandleEsc(byte) + return + + # When we're at the end of the line, we should only allow going backwards, + # backspace, carriage return, up, or down. The arrow keys are escape + # sequences, so we let the escape...escape. + if self.input_buffer_pos >= self.line_limit and byte not in [ + ControlKey.CTRL_B, + ControlKey.ESC, + ControlKey.BACKSPACE, + ControlKey.CTRL_A, + ControlKey.CARRIAGE_RETURN, + ControlKey.CTRL_P, + ControlKey.CTRL_N, + ]: + return + + # If the input buffer is full we can't accept new chars. + buffer_full = len(self.input_buffer) >= self.line_limit + + # Carriage_Return/Enter + if byte == ControlKey.CARRIAGE_RETURN: + self.logger.debug("Enter key pressed.") + # Put a carriage return/newline and the print the prompt. + os.write(fd, b"\r\n") + + # TODO(aaboagye): When we control the printing of all output, print the + # prompt AFTER printing all the output. We can't do it yet because we + # don't know how much is coming from the EC. + + # Print the prompt. + os.write(fd, self.prompt) + # Process the input. + self.ProcessInput() + # Now, clear the buffer. + self.input_buffer = b"" + self.input_buffer_pos = 0 + # Reset history buffer pos. + self.history_pos = len(self.history) + # Clear partial command. + self.partial_cmd = b"" + + # Backspace + elif byte == ControlKey.BACKSPACE: + self.logger.debug("Backspace pressed.") + if self.input_buffer_pos > 0: + # Move left 1 column. + self.MoveCursor("left", 1) + # Remove the character at the input_buffer_pos by slicing it out. + self.SliceOutChar() + + self.logger.debug("input_buffer_pos: %d", self.input_buffer_pos) + + # Ctrl+A. Move cursor to beginning of the line + elif byte == ControlKey.CTRL_A: + self.logger.debug("Control+A pressed.") + self.MoveCursor("left", self.input_buffer_pos) + + # Ctrl+B. Move cursor left 1 column. + elif byte == ControlKey.CTRL_B: + self.logger.debug("Control+B pressed.") + self.MoveCursor("left", 1) + + # Ctrl+D. Delete a character. + elif byte == ControlKey.CTRL_D: + self.logger.debug("Control+D pressed.") + if self.input_buffer_pos != len(self.input_buffer): + # Remove the character by slicing it out. + self.SliceOutChar() + + # Ctrl+E. Move cursor to end of the line. + elif byte == ControlKey.CTRL_E: + self.logger.debug("Control+E pressed.") + self.MoveCursor( + "right", len(self.input_buffer) - self.input_buffer_pos + ) + + # Ctrl+F. Move cursor right 1 column. + elif byte == ControlKey.CTRL_F: + self.logger.debug("Control+F pressed.") + self.MoveCursor("right", 1) + + # Ctrl+K. Kill line. + elif byte == ControlKey.CTRL_K: + self.logger.debug("Control+K pressed.") + self.KillLine() + + # Ctrl+N. Next line. + elif byte == ControlKey.CTRL_N: + self.logger.debug("Control+N pressed.") + self.ShowNextCommand() + + # Ctrl+P. Previous line. + elif byte == ControlKey.CTRL_P: + self.logger.debug("Control+P pressed.") + self.ShowPreviousCommand() + + # ESC sequence + elif byte == ControlKey.ESC: + # Starting an ESC sequence + self.esc_state = EscState.ESC_START + + # Only print printable chars. + elif IsPrintable(byte): + # Drop the character if we're full. + if buffer_full: + self.logger.debug("Dropped char: %c(%d)", byte, byte) + return + # Print the character. + os.write(fd, six.int2byte(byte)) + # Print the rest of the line (if any). + extra_bytes_written = os.write( + fd, self.input_buffer[self.input_buffer_pos :] + ) + + # Recreate the input buffer. + self.input_buffer = ( + self.input_buffer[0 : self.input_buffer_pos] + + six.int2byte(byte) + + self.input_buffer[self.input_buffer_pos :] + ) + # Update the input buffer position. + self.input_buffer_pos += 1 + extra_bytes_written + + # Reset the cursor if we wrote any extra bytes. + if extra_bytes_written: + self.MoveCursor("left", extra_bytes_written) + + self.logger.debug("input_buffer_pos: %d", self.input_buffer_pos) + + def MoveCursor(self, direction, count): + """MoveCursor moves the cursor left or right by count columns. + + Args: + direction: A string that should be either 'left' or 'right' representing + the direction to move the cursor on the console. + count: An integer representing how many columns the cursor should be + moved. + + Raises: + AssertionError: If the direction is not equal to 'left' or 'right'. + """ + # If there's nothing to move, we're done. + if not count: + return + fd = self.controller_pty + seq = b"\033[" + str(count).encode("ascii") + if direction == "left": + # Bind the movement. + if count > self.input_buffer_pos: + count = self.input_buffer_pos + seq += b"D" + self.logger.debug("move cursor left %d", count) + self.input_buffer_pos -= count + + elif direction == "right": + # Bind the movement. + if (count + self.input_buffer_pos) > len(self.input_buffer): + count = 0 + seq += b"C" + self.logger.debug("move cursor right %d", count) + self.input_buffer_pos += count + + else: + raise AssertionError( + ("The only valid directions are 'left' and 'right'") + ) + + self.logger.debug("input_buffer_pos: %d", self.input_buffer_pos) + # Move the cursor. + if count != 0: + os.write(fd, seq) + + def KillLine(self): + """Kill the rest of the line based on the input buffer position.""" + # Killing the line is killing all the text to the right. + diff = len(self.input_buffer) - self.input_buffer_pos + self.logger.debug("diff: %d", diff) + # Diff shouldn't be negative, but if it is for some reason, let's try to + # correct the cursor. + if diff < 0: + self.logger.warning( + "Resetting input buffer position to %d...", + len(self.input_buffer), + ) + self.MoveCursor("left", -diff) + return + if diff: + self.MoveCursor("right", diff) + for _ in range(diff): + self.SendBackspace() + self.input_buffer_pos -= diff + self.input_buffer = self.input_buffer[0 : self.input_buffer_pos] + + def SendBackspace(self): + """Backspace a character on the console.""" + os.write(self.controller_pty, b"\033[1D \033[1D") + + def ProcessOOBMQueue(self): + """Retrieve an item from the OOBM queue and process it.""" + item = self.oobm_queue.get() + self.logger.debug("OOBM cmd: %r", item) + cmd = item.split(b" ") + + if cmd[0] == b"loglevel": + # An integer is required in order to set the log level. + if len(cmd) < 2: + self.logger.debug("Insufficient args") + self.PrintOOBMHelp() + return + try: + self.logger.debug("Log level change request.") + new_log_level = int(cmd[1]) + self.logger.logger.setLevel(new_log_level) + self.logger.info("Log level changed to %d.", new_log_level) + + # Forward the request to the interpreter as well. + self.cmd_pipe.send(item) + except ValueError: + # Ignoring the request if an integer was not provided. + self.PrintOOBMHelp() + + elif cmd[0] == b"timestamp": + mode = cmd[1].lower() + self.timestamp_enabled = mode == b"on" + self.logger.info( + "%sabling uart timestamps.", + "En" if self.timestamp_enabled else "Dis", + ) + + elif cmd[0] == b"rawdebug": + mode = cmd[1].lower() + self.raw_debug = mode == b"on" + self.logger.info( + "%sabling per interrupt debug logs.", + "En" if self.raw_debug else "Dis", + ) + + elif cmd[0] == b"interrogate" and len(cmd) >= 2: + enhanced = False + mode = cmd[1] + if len(cmd) >= 3 and cmd[2] == b"enhanced": + enhanced = True + + # Set the mode if correct. + if mode in INTERROGATION_MODES: + self.interrogation_mode = mode + self.logger.debug("Updated interrogation mode to %s.", mode) + + # Update the assumptions of the EC image. + self.enhanced_ec = enhanced + self.logger.debug( + "Enhanced EC image is now %r", self.enhanced_ec + ) + + # Send command to interpreter as well. + self.cmd_pipe.send( + b"enhanced " + str(self.enhanced_ec).encode("ascii") + ) + else: + self.PrintOOBMHelp() + + else: + self.PrintOOBMHelp() + + def PrintOOBMHelp(self): + """Prints out the OOBM help.""" + # Print help syntax. + os.write(self.controller_pty, b"\r\n" + b"Known OOBM commands:\r\n") + os.write( + self.controller_pty, + b" interrogate <never | always | auto> " b"[enhanced]\r\n", + ) + os.write(self.controller_pty, b" loglevel <int>\r\n") + + def CheckBufferForEnhancedImage(self, data): + """Adds data to a look buffer and checks to see for enhanced EC image. + + The EC's console task prints a string upon initialization which says that + "Console is enabled; type HELP for help.". The enhanced EC images print a + different string as a part of their init. This function searches through a + "look" buffer, scanning for the presence of either of those strings and + updating the enhanced_ec state accordingly. + + Args: + data: A string containing the data sent from the interpreter. + """ + self.look_buffer += data + + # Search the buffer for any of the EC image strings. + enhanced_match = re.search(ENHANCED_IMAGE_RE, self.look_buffer) + non_enhanced_match = re.search(NON_ENHANCED_IMAGE_RE, self.look_buffer) + + # Update the state if any matches were found. + if enhanced_match or non_enhanced_match: + if enhanced_match: + self.enhanced_ec = True + elif non_enhanced_match: + self.enhanced_ec = False + + # Inform the interpreter of the result. + self.cmd_pipe.send( + b"enhanced " + str(self.enhanced_ec).encode("ascii") + ) + self.logger.debug("Enhanced EC image? %r", self.enhanced_ec) + + # Clear look buffer since a match was found. + self.look_buffer = b"" + + # Move the sliding window. + self.look_buffer = self.look_buffer[-LOOK_BUFFER_SIZE:] - else: - self.logger.error('Unexpected sequence. %c', byte) - self.esc_state = 0 - - def ProcessInput(self): - """Captures the input determines what actions to take.""" - # There's nothing to do if the input buffer is empty. - if len(self.input_buffer) == 0: - return - - # Don't store 2 consecutive identical commands in the history. - if (self.history and self.history[-1] != self.input_buffer - or not self.history): - self.history.append(self.input_buffer) - - # Split the command up by spaces. - line = self.input_buffer.split(b' ') - self.logger.debug('cmd: %s', self.input_buffer) - cmd = line[0].lower() - - # The 'history' command is a special case that we handle locally. - if cmd == 'history': - self.PrintHistory() - return - - # Send the command to the interpreter. - self.logger.debug('Sending command to interpreter.') - self.cmd_pipe.send(self.input_buffer) - def CheckForEnhancedECImage(self): - """Performs an interrogation of the EC image. +def CanonicalizeTimeString(timestr): + """Canonicalize the timestamp string. - Send a SYN and expect an ACK. If no ACK or the response is incorrect, then - assume that the current EC image that we are talking to is not enhanced. + Args: + timestr: A timestamp string ended with 6 digits msec. Returns: - is_enhanced: A boolean indicating whether the EC responded to the - interrogation correctly. - - Raises: - EOFError: Allowed to propagate through from self.dbg_pipe.recv(). + A string with 3 digits msec and an extra space. """ - # Send interrogation byte and wait for the response. - self.logger.debug('Performing interrogation.') - self.cmd_pipe.send(interpreter.EC_SYN) - - response = '' - if self.dbg_pipe.poll(self.interrogation_timeout): - response = self.dbg_pipe.recv() - self.logger.debug('response: %r', binascii.hexlify(response)) - else: - self.logger.debug('Timed out waiting for EC_ACK') + return timestr[:-3].encode("ascii") + b" " - # Verify the acknowledgment. - is_enhanced = response == interpreter.EC_ACK - - if is_enhanced: - # Increase the interrogation timeout for stability purposes. - self.interrogation_timeout = ENHANCED_EC_INTERROGATION_TIMEOUT - self.logger.debug('Increasing interrogation timeout to %rs.', - self.interrogation_timeout) - else: - # Reduce the timeout in order to reduce the perceivable delay. - self.interrogation_timeout = NON_ENHANCED_EC_INTERROGATION_TIMEOUT - self.logger.debug('Reducing interrogation timeout to %rs.', - self.interrogation_timeout) - - return is_enhanced - - def HandleChar(self, byte): - """HandleChar does a certain action when it receives a character. - - Args: - byte: An integer representing the character received from the user. - Raises: - EOFError: Allowed to propagate through from self.CheckForEnhancedECImage() - i.e. from self.dbg_pipe.recv(). - """ - fd = self.controller_pty - - # Enter the OOBM prompt mode if the user presses '%'. - if byte == ord('%'): - self.logger.debug('Begin OOBM command.') - self.receiving_oobm_cmd = True - # Print a "prompt". - os.write(self.controller_pty, b'\r\n% ') - return - - # Add chars to the pending OOBM command if we're currently receiving one. - if self.receiving_oobm_cmd and byte != ControlKey.CARRIAGE_RETURN: - tmp_bytes = six.int2byte(byte) - self.pending_oobm_cmd += tmp_bytes - self.logger.debug('%s', tmp_bytes) - os.write(self.controller_pty, tmp_bytes) - return - - if byte == ControlKey.CARRIAGE_RETURN: - if self.receiving_oobm_cmd: - # Terminate the command and place it in the OOBM queue. - self.logger.debug('End OOBM command.') - if self.pending_oobm_cmd: - self.oobm_queue.put(self.pending_oobm_cmd) - self.logger.debug('Placed %r into OOBM command queue.', - self.pending_oobm_cmd) - - # Reset the state. - os.write(self.controller_pty, b'\r\n' + self.prompt) - self.input_buffer = b'' - self.input_buffer_pos = 0 - self.receiving_oobm_cmd = False - self.pending_oobm_cmd = b'' - return - - if self.interrogation_mode == b'never': - self.logger.debug('Skipping interrogation because interrogation mode' - ' is set to never.') - elif self.interrogation_mode == b'always': - # Only interrogate the EC if the interrogation mode is set to 'always'. - self.enhanced_ec = self.CheckForEnhancedECImage() - self.logger.debug('Enhanced EC image? %r', self.enhanced_ec) - - if not self.enhanced_ec: - # Send everything straight to the EC to handle. - self.cmd_pipe.send(six.int2byte(byte)) - # Reset the input buffer. - self.input_buffer = b'' - self.input_buffer_pos = 0 - self.logger.log(1, 'Reset input buffer.') - return - - # Keep handling the ESC sequence if we're in the middle of it. - if self.esc_state != 0: - self.HandleEsc(byte) - return - - # When we're at the end of the line, we should only allow going backwards, - # backspace, carriage return, up, or down. The arrow keys are escape - # sequences, so we let the escape...escape. - if (self.input_buffer_pos >= self.line_limit and - byte not in [ControlKey.CTRL_B, ControlKey.ESC, ControlKey.BACKSPACE, - ControlKey.CTRL_A, ControlKey.CARRIAGE_RETURN, - ControlKey.CTRL_P, ControlKey.CTRL_N]): - return - - # If the input buffer is full we can't accept new chars. - buffer_full = len(self.input_buffer) >= self.line_limit - - - # Carriage_Return/Enter - if byte == ControlKey.CARRIAGE_RETURN: - self.logger.debug('Enter key pressed.') - # Put a carriage return/newline and the print the prompt. - os.write(fd, b'\r\n') - - # TODO(aaboagye): When we control the printing of all output, print the - # prompt AFTER printing all the output. We can't do it yet because we - # don't know how much is coming from the EC. - - # Print the prompt. - os.write(fd, self.prompt) - # Process the input. - self.ProcessInput() - # Now, clear the buffer. - self.input_buffer = b'' - self.input_buffer_pos = 0 - # Reset history buffer pos. - self.history_pos = len(self.history) - # Clear partial command. - self.partial_cmd = b'' - - # Backspace - elif byte == ControlKey.BACKSPACE: - self.logger.debug('Backspace pressed.') - if self.input_buffer_pos > 0: - # Move left 1 column. - self.MoveCursor('left', 1) - # Remove the character at the input_buffer_pos by slicing it out. - self.SliceOutChar() - - self.logger.debug('input_buffer_pos: %d', self.input_buffer_pos) - - # Ctrl+A. Move cursor to beginning of the line - elif byte == ControlKey.CTRL_A: - self.logger.debug('Control+A pressed.') - self.MoveCursor('left', self.input_buffer_pos) - - # Ctrl+B. Move cursor left 1 column. - elif byte == ControlKey.CTRL_B: - self.logger.debug('Control+B pressed.') - self.MoveCursor('left', 1) - - # Ctrl+D. Delete a character. - elif byte == ControlKey.CTRL_D: - self.logger.debug('Control+D pressed.') - if self.input_buffer_pos != len(self.input_buffer): - # Remove the character by slicing it out. - self.SliceOutChar() - - # Ctrl+E. Move cursor to end of the line. - elif byte == ControlKey.CTRL_E: - self.logger.debug('Control+E pressed.') - self.MoveCursor('right', - len(self.input_buffer) - self.input_buffer_pos) - - # Ctrl+F. Move cursor right 1 column. - elif byte == ControlKey.CTRL_F: - self.logger.debug('Control+F pressed.') - self.MoveCursor('right', 1) - - # Ctrl+K. Kill line. - elif byte == ControlKey.CTRL_K: - self.logger.debug('Control+K pressed.') - self.KillLine() - - # Ctrl+N. Next line. - elif byte == ControlKey.CTRL_N: - self.logger.debug('Control+N pressed.') - self.ShowNextCommand() - - # Ctrl+P. Previous line. - elif byte == ControlKey.CTRL_P: - self.logger.debug('Control+P pressed.') - self.ShowPreviousCommand() - - # ESC sequence - elif byte == ControlKey.ESC: - # Starting an ESC sequence - self.esc_state = EscState.ESC_START - - # Only print printable chars. - elif IsPrintable(byte): - # Drop the character if we're full. - if buffer_full: - self.logger.debug('Dropped char: %c(%d)', byte, byte) - return - # Print the character. - os.write(fd, six.int2byte(byte)) - # Print the rest of the line (if any). - extra_bytes_written = os.write(fd, - self.input_buffer[self.input_buffer_pos:]) - - # Recreate the input buffer. - self.input_buffer = (self.input_buffer[0:self.input_buffer_pos] + - six.int2byte(byte) + - self.input_buffer[self.input_buffer_pos:]) - # Update the input buffer position. - self.input_buffer_pos += 1 + extra_bytes_written - - # Reset the cursor if we wrote any extra bytes. - if extra_bytes_written: - self.MoveCursor('left', extra_bytes_written) - - self.logger.debug('input_buffer_pos: %d', self.input_buffer_pos) - - def MoveCursor(self, direction, count): - """MoveCursor moves the cursor left or right by count columns. +def IsPrintable(byte): + """Determines if a byte is printable. Args: - direction: A string that should be either 'left' or 'right' representing - the direction to move the cursor on the console. - count: An integer representing how many columns the cursor should be - moved. + byte: An integer potentially representing a printable character. - Raises: - AssertionError: If the direction is not equal to 'left' or 'right'. + Returns: + A boolean indicating whether the byte is a printable character. """ - # If there's nothing to move, we're done. - if not count: - return - fd = self.controller_pty - seq = b'\033[' + str(count).encode('ascii') - if direction == 'left': - # Bind the movement. - if count > self.input_buffer_pos: - count = self.input_buffer_pos - seq += b'D' - self.logger.debug('move cursor left %d', count) - self.input_buffer_pos -= count - - elif direction == 'right': - # Bind the movement. - if (count + self.input_buffer_pos) > len(self.input_buffer): - count = 0 - seq += b'C' - self.logger.debug('move cursor right %d', count) - self.input_buffer_pos += count - - else: - raise AssertionError(('The only valid directions are \'left\' and ' - '\'right\'')) - - self.logger.debug('input_buffer_pos: %d', self.input_buffer_pos) - # Move the cursor. - if count != 0: - os.write(fd, seq) - - def KillLine(self): - """Kill the rest of the line based on the input buffer position.""" - # Killing the line is killing all the text to the right. - diff = len(self.input_buffer) - self.input_buffer_pos - self.logger.debug('diff: %d', diff) - # Diff shouldn't be negative, but if it is for some reason, let's try to - # correct the cursor. - if diff < 0: - self.logger.warning('Resetting input buffer position to %d...', - len(self.input_buffer)) - self.MoveCursor('left', -diff) - return - if diff: - self.MoveCursor('right', diff) - for _ in range(diff): - self.SendBackspace() - self.input_buffer_pos -= diff - self.input_buffer = self.input_buffer[0:self.input_buffer_pos] - - def SendBackspace(self): - """Backspace a character on the console.""" - os.write(self.controller_pty, b'\033[1D \033[1D') - - def ProcessOOBMQueue(self): - """Retrieve an item from the OOBM queue and process it.""" - item = self.oobm_queue.get() - self.logger.debug('OOBM cmd: %r', item) - cmd = item.split(b' ') - - if cmd[0] == b'loglevel': - # An integer is required in order to set the log level. - if len(cmd) < 2: - self.logger.debug('Insufficient args') - self.PrintOOBMHelp() - return - try: - self.logger.debug('Log level change request.') - new_log_level = int(cmd[1]) - self.logger.logger.setLevel(new_log_level) - self.logger.info('Log level changed to %d.', new_log_level) - - # Forward the request to the interpreter as well. - self.cmd_pipe.send(item) - except ValueError: - # Ignoring the request if an integer was not provided. - self.PrintOOBMHelp() - - elif cmd[0] == b'timestamp': - mode = cmd[1].lower() - self.timestamp_enabled = (mode == b'on') - self.logger.info('%sabling uart timestamps.', - 'En' if self.timestamp_enabled else 'Dis') - - elif cmd[0] == b'rawdebug': - mode = cmd[1].lower() - self.raw_debug = (mode == b'on') - self.logger.info('%sabling per interrupt debug logs.', - 'En' if self.raw_debug else 'Dis') - - elif cmd[0] == b'interrogate' and len(cmd) >= 2: - enhanced = False - mode = cmd[1] - if len(cmd) >= 3 and cmd[2] == b'enhanced': - enhanced = True - - # Set the mode if correct. - if mode in INTERROGATION_MODES: - self.interrogation_mode = mode - self.logger.debug('Updated interrogation mode to %s.', mode) - - # Update the assumptions of the EC image. - self.enhanced_ec = enhanced - self.logger.debug('Enhanced EC image is now %r', self.enhanced_ec) - - # Send command to interpreter as well. - self.cmd_pipe.send(b'enhanced ' + str(self.enhanced_ec).encode('ascii')) - else: - self.PrintOOBMHelp() - - else: - self.PrintOOBMHelp() + return byte >= ord(" ") and byte <= ord("~") - def PrintOOBMHelp(self): - """Prints out the OOBM help.""" - # Print help syntax. - os.write(self.controller_pty, b'\r\n' + b'Known OOBM commands:\r\n') - os.write(self.controller_pty, b' interrogate <never | always | auto> ' - b'[enhanced]\r\n') - os.write(self.controller_pty, b' loglevel <int>\r\n') - def CheckBufferForEnhancedImage(self, data): - """Adds data to a look buffer and checks to see for enhanced EC image. - - The EC's console task prints a string upon initialization which says that - "Console is enabled; type HELP for help.". The enhanced EC images print a - different string as a part of their init. This function searches through a - "look" buffer, scanning for the presence of either of those strings and - updating the enhanced_ec state accordingly. +def StartLoop(console, command_active, shutdown_pipe=None): + """Starts the infinite loop of console processing. Args: - data: A string containing the data sent from the interpreter. + console: A Console object that has been properly initialzed. + command_active: ctypes data object or multiprocessing.Value indicating if + servod owns the console, or user owns the console. This prevents input + collisions. + shutdown_pipe: A file object for a pipe or equivalent that becomes readable + (not blocked) to indicate that the loop should exit. Can be None to never + exit the loop. """ - self.look_buffer += data - - # Search the buffer for any of the EC image strings. - enhanced_match = re.search(ENHANCED_IMAGE_RE, self.look_buffer) - non_enhanced_match = re.search(NON_ENHANCED_IMAGE_RE, self.look_buffer) - - # Update the state if any matches were found. - if enhanced_match or non_enhanced_match: - if enhanced_match: - self.enhanced_ec = True - elif non_enhanced_match: - self.enhanced_ec = False - - # Inform the interpreter of the result. - self.cmd_pipe.send(b'enhanced ' + str(self.enhanced_ec).encode('ascii')) - self.logger.debug('Enhanced EC image? %r', self.enhanced_ec) - - # Clear look buffer since a match was found. - self.look_buffer = b'' - - # Move the sliding window. - self.look_buffer = self.look_buffer[-LOOK_BUFFER_SIZE:] - - -def CanonicalizeTimeString(timestr): - """Canonicalize the timestamp string. - - Args: - timestr: A timestamp string ended with 6 digits msec. - - Returns: - A string with 3 digits msec and an extra space. - """ - return timestr[:-3].encode('ascii') + b' ' - - -def IsPrintable(byte): - """Determines if a byte is printable. - - Args: - byte: An integer potentially representing a printable character. - - Returns: - A boolean indicating whether the byte is a printable character. - """ - return byte >= ord(' ') and byte <= ord('~') - - -def StartLoop(console, command_active, shutdown_pipe=None): - """Starts the infinite loop of console processing. - - Args: - console: A Console object that has been properly initialzed. - command_active: ctypes data object or multiprocessing.Value indicating if - servod owns the console, or user owns the console. This prevents input - collisions. - shutdown_pipe: A file object for a pipe or equivalent that becomes readable - (not blocked) to indicate that the loop should exit. Can be None to never - exit the loop. - """ - try: - console.logger.debug('Console is being served on %s.', console.user_pty) - console.logger.debug('Console controller is on %s.', console.controller_pty) - console.logger.debug('Command interface is being served on %s.', - console.interface_pty) - console.logger.debug(console) - - # This checks for HUP to indicate if the user has connected to the pty. - ep = select.epoll() - ep.register(console.controller_pty, select.EPOLLHUP) - - # This is used instead of "break" to avoid exiting the loop in the middle of - # an iteration. - continue_looping = True - - # Used for determining when to print host timestamps - tm_req = True - - while continue_looping: - # Check to see if pts is connected to anything - events = ep.poll(0) - controller_connected = not events - - # Check to see if pipes or the console are ready for reading. - read_list = [console.interface_pty, - console.cmd_pipe, console.dbg_pipe] - if controller_connected: - read_list.append(console.controller_pty) - if shutdown_pipe is not None: - read_list.append(shutdown_pipe) - - # Check if any input is ready, or wait for .1 sec and re-poll if - # a user has connected to the pts. - select_output = select.select(read_list, [], [], .1) - if not select_output: - continue - ready_for_reading = select_output[0] - - for obj in ready_for_reading: - if obj is console.controller_pty: - if not command_active.value: - # Convert to bytes so we can look for non-printable chars such as - # Ctrl+A, Ctrl+E, etc. - try: - line = bytearray(os.read(console.controller_pty, CONSOLE_MAX_READ)) - console.logger.debug('Input from user: %s, locked:%s', - str(line).strip(), command_active.value) - for i in line: - try: - # Handle each character as it arrives. - console.HandleChar(i) - except EOFError: - console.logger.debug( - 'ec3po console received EOF from dbg_pipe in HandleChar()' - ' while reading console.controller_pty') - continue_looping = False - break - except OSError: - console.logger.debug('Ptm read failed, probably user disconnect.') - - elif obj is console.interface_pty: - if command_active.value: - # Convert to bytes so we can look for non-printable chars such as - # Ctrl+A, Ctrl+E, etc. - line = bytearray(os.read(console.interface_pty, CONSOLE_MAX_READ)) - console.logger.debug('Input from interface: %s, locked:%s', - str(line).strip(), command_active.value) - for i in line: - try: - # Handle each character as it arrives. - console.HandleChar(i) - except EOFError: - console.logger.debug( - 'ec3po console received EOF from dbg_pipe in HandleChar()' - ' while reading console.interface_pty') - continue_looping = False - break - - elif obj is console.cmd_pipe: - try: - data = console.cmd_pipe.recv() - except EOFError: - console.logger.debug('ec3po console received EOF from cmd_pipe') - continue_looping = False - else: - # Write it to the user console. - if console.raw_debug: - console.logger.debug('|CMD|-%s->%r', - ('u' if controller_connected else '') + - ('i' if command_active.value else ''), - data.strip()) + try: + console.logger.debug("Console is being served on %s.", console.user_pty) + console.logger.debug( + "Console controller is on %s.", console.controller_pty + ) + console.logger.debug( + "Command interface is being served on %s.", console.interface_pty + ) + console.logger.debug(console) + + # This checks for HUP to indicate if the user has connected to the pty. + ep = select.epoll() + ep.register(console.controller_pty, select.EPOLLHUP) + + # This is used instead of "break" to avoid exiting the loop in the middle of + # an iteration. + continue_looping = True + + # Used for determining when to print host timestamps + tm_req = True + + while continue_looping: + # Check to see if pts is connected to anything + events = ep.poll(0) + controller_connected = not events + + # Check to see if pipes or the console are ready for reading. + read_list = [ + console.interface_pty, + console.cmd_pipe, + console.dbg_pipe, + ] if controller_connected: - os.write(console.controller_pty, data) - if command_active.value: - os.write(console.interface_pty, data) - - elif obj is console.dbg_pipe: - try: - data = console.dbg_pipe.recv() - except EOFError: - console.logger.debug('ec3po console received EOF from dbg_pipe') - continue_looping = False - else: - if console.interrogation_mode == b'auto': - # Search look buffer for enhanced EC image string. - console.CheckBufferForEnhancedImage(data) - # Write it to the user console. - if len(data) > 1 and console.raw_debug: - console.logger.debug('|DBG|-%s->%r', - ('u' if controller_connected else '') + - ('i' if command_active.value else ''), - data.strip()) - console.LogConsoleOutput(data) - if controller_connected: - end = len(data) - 1 - if console.timestamp_enabled: - # A timestamp is required at the beginning of this line - if tm_req is True: - now = datetime.now() - tm = CanonicalizeTimeString(now.strftime(HOST_STRFTIME)) - os.write(console.controller_pty, tm) - tm_req = False - - # Insert timestamps into the middle where appropriate - # except if the last character is a newline - nls_found = data.count(b'\n', 0, end) - now = datetime.now() - tm = CanonicalizeTimeString(now.strftime('\n' + HOST_STRFTIME)) - data_tm = data.replace(b'\n', tm, nls_found) - else: - data_tm = data - - # timestamp required on next input - if data[end] == b'\n'[0]: - tm_req = True - os.write(console.controller_pty, data_tm) - if command_active.value: - os.write(console.interface_pty, data) - - elif obj is shutdown_pipe: - console.logger.debug( - 'ec3po console received shutdown pipe unblocked notification') - continue_looping = False - - while not console.oobm_queue.empty(): - console.logger.debug('OOBM queue ready for reading.') - console.ProcessOOBMQueue() - - except KeyboardInterrupt: - pass - - finally: - ep.unregister(console.controller_pty) - console.dbg_pipe.close() - console.cmd_pipe.close() - os.close(console.controller_pty) - os.close(console.interface_pty) - if shutdown_pipe is not None: - shutdown_pipe.close() - console.logger.debug('Exit ec3po console loop for %s', console.user_pty) + read_list.append(console.controller_pty) + if shutdown_pipe is not None: + read_list.append(shutdown_pipe) + + # Check if any input is ready, or wait for .1 sec and re-poll if + # a user has connected to the pts. + select_output = select.select(read_list, [], [], 0.1) + if not select_output: + continue + ready_for_reading = select_output[0] + + for obj in ready_for_reading: + if obj is console.controller_pty: + if not command_active.value: + # Convert to bytes so we can look for non-printable chars such as + # Ctrl+A, Ctrl+E, etc. + try: + line = bytearray( + os.read( + console.controller_pty, CONSOLE_MAX_READ + ) + ) + console.logger.debug( + "Input from user: %s, locked:%s", + str(line).strip(), + command_active.value, + ) + for i in line: + try: + # Handle each character as it arrives. + console.HandleChar(i) + except EOFError: + console.logger.debug( + "ec3po console received EOF from dbg_pipe in HandleChar()" + " while reading console.controller_pty" + ) + continue_looping = False + break + except OSError: + console.logger.debug( + "Ptm read failed, probably user disconnect." + ) + + elif obj is console.interface_pty: + if command_active.value: + # Convert to bytes so we can look for non-printable chars such as + # Ctrl+A, Ctrl+E, etc. + line = bytearray( + os.read(console.interface_pty, CONSOLE_MAX_READ) + ) + console.logger.debug( + "Input from interface: %s, locked:%s", + str(line).strip(), + command_active.value, + ) + for i in line: + try: + # Handle each character as it arrives. + console.HandleChar(i) + except EOFError: + console.logger.debug( + "ec3po console received EOF from dbg_pipe in HandleChar()" + " while reading console.interface_pty" + ) + continue_looping = False + break + + elif obj is console.cmd_pipe: + try: + data = console.cmd_pipe.recv() + except EOFError: + console.logger.debug( + "ec3po console received EOF from cmd_pipe" + ) + continue_looping = False + else: + # Write it to the user console. + if console.raw_debug: + console.logger.debug( + "|CMD|-%s->%r", + ("u" if controller_connected else "") + + ("i" if command_active.value else ""), + data.strip(), + ) + if controller_connected: + os.write(console.controller_pty, data) + if command_active.value: + os.write(console.interface_pty, data) + + elif obj is console.dbg_pipe: + try: + data = console.dbg_pipe.recv() + except EOFError: + console.logger.debug( + "ec3po console received EOF from dbg_pipe" + ) + continue_looping = False + else: + if console.interrogation_mode == b"auto": + # Search look buffer for enhanced EC image string. + console.CheckBufferForEnhancedImage(data) + # Write it to the user console. + if len(data) > 1 and console.raw_debug: + console.logger.debug( + "|DBG|-%s->%r", + ("u" if controller_connected else "") + + ("i" if command_active.value else ""), + data.strip(), + ) + console.LogConsoleOutput(data) + if controller_connected: + end = len(data) - 1 + if console.timestamp_enabled: + # A timestamp is required at the beginning of this line + if tm_req is True: + now = datetime.now() + tm = CanonicalizeTimeString( + now.strftime(HOST_STRFTIME) + ) + os.write(console.controller_pty, tm) + tm_req = False + + # Insert timestamps into the middle where appropriate + # except if the last character is a newline + nls_found = data.count(b"\n", 0, end) + now = datetime.now() + tm = CanonicalizeTimeString( + now.strftime("\n" + HOST_STRFTIME) + ) + data_tm = data.replace(b"\n", tm, nls_found) + else: + data_tm = data + + # timestamp required on next input + if data[end] == b"\n"[0]: + tm_req = True + os.write(console.controller_pty, data_tm) + if command_active.value: + os.write(console.interface_pty, data) + + elif obj is shutdown_pipe: + console.logger.debug( + "ec3po console received shutdown pipe unblocked notification" + ) + continue_looping = False + + while not console.oobm_queue.empty(): + console.logger.debug("OOBM queue ready for reading.") + console.ProcessOOBMQueue() + + except KeyboardInterrupt: + pass + + finally: + ep.unregister(console.controller_pty) + console.dbg_pipe.close() + console.cmd_pipe.close() + os.close(console.controller_pty) + os.close(console.interface_pty) + if shutdown_pipe is not None: + shutdown_pipe.close() + console.logger.debug("Exit ec3po console loop for %s", console.user_pty) def main(argv): - """Kicks off the EC-3PO interactive console interface and interpreter. - - We create some pipes to communicate with an interpreter, instantiate an - interpreter, create a PTY pair, and begin serving the console interface. - - Args: - argv: A list of strings containing the arguments this module was called - with. - """ - # Set up argument parser. - parser = argparse.ArgumentParser(description=('Start interactive EC console ' - 'and interpreter.')) - parser.add_argument('ec_uart_pty', - help=('The full PTY name that the EC UART' - ' is present on. eg: /dev/pts/12')) - parser.add_argument('--log-level', - default='info', - help='info, debug, warning, error, or critical') - - # Parse arguments. - opts = parser.parse_args(argv) - - # Set logging level. - opts.log_level = opts.log_level.lower() - if opts.log_level == 'info': - log_level = logging.INFO - elif opts.log_level == 'debug': - log_level = logging.DEBUG - elif opts.log_level == 'warning': - log_level = logging.WARNING - elif opts.log_level == 'error': - log_level = logging.ERROR - elif opts.log_level == 'critical': - log_level = logging.CRITICAL - else: - parser.error('Invalid log level. (info, debug, warning, error, critical)') - - # Start logging with a timestamp, module, and log level shown in each log - # entry. - logging.basicConfig(level=log_level, format=('%(asctime)s - %(module)s -' - ' %(levelname)s - %(message)s')) - - # Create some pipes to communicate between the interpreter and the console. - # The command pipe is bidirectional. - cmd_pipe_interactive, cmd_pipe_interp = threadproc_shim.Pipe() - # The debug pipe is unidirectional from interpreter to console only. - dbg_pipe_interactive, dbg_pipe_interp = threadproc_shim.Pipe(duplex=False) - - # Create an interpreter instance. - itpr = interpreter.Interpreter(opts.ec_uart_pty, cmd_pipe_interp, - dbg_pipe_interp, log_level) - - # Spawn an interpreter process. - itpr_process = threadproc_shim.ThreadOrProcess( - target=interpreter.StartLoop, args=(itpr,)) - # Make sure to kill the interpreter when we terminate. - itpr_process.daemon = True - # Start the interpreter. - itpr_process.start() - - # Open a new pseudo-terminal pair - (controller_pty, user_pty) = pty.openpty() - # Set the permissions to 660. - os.chmod(os.ttyname(user_pty), (stat.S_IRGRP | stat.S_IWGRP | - stat.S_IRUSR | stat.S_IWUSR)) - # Create a console. - console = Console(controller_pty, os.ttyname(user_pty), cmd_pipe_interactive, - dbg_pipe_interactive) - # Start serving the console. - v = threadproc_shim.Value(ctypes.c_bool, False) - StartLoop(console, v) - - -if __name__ == '__main__': - main(sys.argv[1:]) + """Kicks off the EC-3PO interactive console interface and interpreter. + + We create some pipes to communicate with an interpreter, instantiate an + interpreter, create a PTY pair, and begin serving the console interface. + + Args: + argv: A list of strings containing the arguments this module was called + with. + """ + # Set up argument parser. + parser = argparse.ArgumentParser( + description=("Start interactive EC console and interpreter.") + ) + parser.add_argument( + "ec_uart_pty", + help=( + "The full PTY name that the EC UART is present on. eg: /dev/pts/12" + ), + ) + parser.add_argument( + "--log-level", + default="info", + help="info, debug, warning, error, or critical", + ) + + # Parse arguments. + opts = parser.parse_args(argv) + + # Set logging level. + opts.log_level = opts.log_level.lower() + if opts.log_level == "info": + log_level = logging.INFO + elif opts.log_level == "debug": + log_level = logging.DEBUG + elif opts.log_level == "warning": + log_level = logging.WARNING + elif opts.log_level == "error": + log_level = logging.ERROR + elif opts.log_level == "critical": + log_level = logging.CRITICAL + else: + parser.error( + "Invalid log level. (info, debug, warning, error, critical)" + ) + + # Start logging with a timestamp, module, and log level shown in each log + # entry. + logging.basicConfig( + level=log_level, + format=("%(asctime)s - %(module)s - %(levelname)s - %(message)s"), + ) + + # Create some pipes to communicate between the interpreter and the console. + # The command pipe is bidirectional. + cmd_pipe_interactive, cmd_pipe_interp = threadproc_shim.Pipe() + # The debug pipe is unidirectional from interpreter to console only. + dbg_pipe_interactive, dbg_pipe_interp = threadproc_shim.Pipe(duplex=False) + + # Create an interpreter instance. + itpr = interpreter.Interpreter( + opts.ec_uart_pty, cmd_pipe_interp, dbg_pipe_interp, log_level + ) + + # Spawn an interpreter process. + itpr_process = threadproc_shim.ThreadOrProcess( + target=interpreter.StartLoop, args=(itpr,) + ) + # Make sure to kill the interpreter when we terminate. + itpr_process.daemon = True + # Start the interpreter. + itpr_process.start() + + # Open a new pseudo-terminal pair + (controller_pty, user_pty) = pty.openpty() + # Set the permissions to 660. + os.chmod( + os.ttyname(user_pty), + (stat.S_IRGRP | stat.S_IWGRP | stat.S_IRUSR | stat.S_IWUSR), + ) + # Create a console. + console = Console( + controller_pty, + os.ttyname(user_pty), + os.ttyname(controller_pty), + cmd_pipe_interactive, + dbg_pipe_interactive, + ) + # Start serving the console. + v = threadproc_shim.Value(ctypes.c_bool, False) + StartLoop(console, v) + + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/util/ec3po/console_unittest.py b/util/ec3po/console_unittest.py index 7e341e7e8d..e2a3d588fd 100755 --- a/util/ec3po/console_unittest.py +++ b/util/ec3po/console_unittest.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright 2015 The Chromium OS Authors. All rights reserved. +# Copyright 2015 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -11,1262 +11,1317 @@ from __future__ import print_function import binascii import logging -import mock import tempfile import unittest +import mock # pylint:disable=import-error import six - -from ec3po import console -from ec3po import interpreter -from ec3po import threadproc_shim +from ec3po import console, interpreter, threadproc_shim ESC_STRING = six.int2byte(console.ControlKey.ESC) + class Keys(object): - """A class that contains the escape sequences for special keys.""" - LEFT_ARROW = [console.ControlKey.ESC, ord('['), ord('D')] - RIGHT_ARROW = [console.ControlKey.ESC, ord('['), ord('C')] - UP_ARROW = [console.ControlKey.ESC, ord('['), ord('A')] - DOWN_ARROW = [console.ControlKey.ESC, ord('['), ord('B')] - HOME = [console.ControlKey.ESC, ord('['), ord('1'), ord('~')] - END = [console.ControlKey.ESC, ord('['), ord('8'), ord('~')] - DEL = [console.ControlKey.ESC, ord('['), ord('3'), ord('~')] + """A class that contains the escape sequences for special keys.""" + + LEFT_ARROW = [console.ControlKey.ESC, ord("["), ord("D")] + RIGHT_ARROW = [console.ControlKey.ESC, ord("["), ord("C")] + UP_ARROW = [console.ControlKey.ESC, ord("["), ord("A")] + DOWN_ARROW = [console.ControlKey.ESC, ord("["), ord("B")] + HOME = [console.ControlKey.ESC, ord("["), ord("1"), ord("~")] + END = [console.ControlKey.ESC, ord("["), ord("8"), ord("~")] + DEL = [console.ControlKey.ESC, ord("["), ord("3"), ord("~")] + class OutputStream(object): - """A class that has methods which return common console output.""" + """A class that has methods which return common console output.""" - @staticmethod - def MoveCursorLeft(count): - """Produces what would be printed to the console if the cursor moved left. + @staticmethod + def MoveCursorLeft(count): + """Produces what would be printed to the console if the cursor moved left. - Args: - count: An integer representing how many columns to move left. + Args: + count: An integer representing how many columns to move left. - Returns: - string: A string which contains what would be printed to the console if - the cursor moved left. - """ - string = ESC_STRING - string += b'[' + str(count).encode('ascii') + b'D' - return string + Returns: + string: A string which contains what would be printed to the console if + the cursor moved left. + """ + string = ESC_STRING + string += b"[" + str(count).encode("ascii") + b"D" + return string - @staticmethod - def MoveCursorRight(count): - """Produces what would be printed to the console if the cursor moved right. + @staticmethod + def MoveCursorRight(count): + """Produces what would be printed to the console if the cursor moved right. - Args: - count: An integer representing how many columns to move right. + Args: + count: An integer representing how many columns to move right. + + Returns: + string: A string which contains what would be printed to the console if + the cursor moved right. + """ + string = ESC_STRING + string += b"[" + str(count).encode("ascii") + b"C" + return string - Returns: - string: A string which contains what would be printed to the console if - the cursor moved right. - """ - string = ESC_STRING - string += b'[' + str(count).encode('ascii') + b'C' - return string -BACKSPACE_STRING = b'' +BACKSPACE_STRING = b"" # Move cursor left 1 column. BACKSPACE_STRING += OutputStream.MoveCursorLeft(1) # Write a space. -BACKSPACE_STRING += b' ' +BACKSPACE_STRING += b" " # Move cursor left 1 column. BACKSPACE_STRING += OutputStream.MoveCursorLeft(1) -def BytesToByteList(string): - """Converts a bytes string to list of bytes. - - Args: - string: A literal bytes to turn into a list of bytes. - - Returns: - A list of integers representing the byte value of each character in the - string. - """ - if six.PY3: - return [c for c in string] - return [ord(c) for c in string] -def CheckConsoleOutput(test_case, exp_console_out): - """Verify what was sent out the console matches what we expect. +def BytesToByteList(string): + """Converts a bytes string to list of bytes. - Args: - test_case: A unittest.TestCase object representing the current unit test. - exp_console_out: A string representing the console output stream. - """ - # Read what was sent out the console. - test_case.tempfile.seek(0) - console_out = test_case.tempfile.read() + Args: + string: A literal bytes to turn into a list of bytes. - test_case.assertEqual(exp_console_out, console_out) + Returns: + A list of integers representing the byte value of each character in the + string. + """ + if six.PY3: + return [c for c in string] + return [ord(c) for c in string] -def CheckInputBuffer(test_case, exp_input_buffer): - """Verify that the input buffer contains what we expect. - - Args: - test_case: A unittest.TestCase object representing the current unit test. - exp_input_buffer: A string containing the contents of the current input - buffer. - """ - test_case.assertEqual(exp_input_buffer, test_case.console.input_buffer, - (b'input buffer does not match expected.\n' - b'expected: |' + exp_input_buffer + b'|\n' - b'got: |' + test_case.console.input_buffer + - b'|\n' + str(test_case.console).encode('ascii'))) -def CheckInputBufferPosition(test_case, exp_pos): - """Verify the input buffer position. +def CheckConsoleOutput(test_case, exp_console_out): + """Verify what was sent out the console matches what we expect. - Args: - test_case: A unittest.TestCase object representing the current unit test. - exp_pos: An integer representing the expected input buffer position. - """ - test_case.assertEqual(exp_pos, test_case.console.input_buffer_pos, - 'input buffer position is incorrect.\ngot: ' + - str(test_case.console.input_buffer_pos) + '\nexp: ' + - str(exp_pos) + '\n' + str(test_case.console)) + Args: + test_case: A unittest.TestCase object representing the current unit test. + exp_console_out: A string representing the console output stream. + """ + # Read what was sent out the console. + test_case.tempfile.seek(0) + console_out = test_case.tempfile.read() -def CheckHistoryBuffer(test_case, exp_history): - """Verify that the items in the history buffer are what we expect. - - Args: - test_case: A unittest.TestCase object representing the current unit test. - exp_history: A list of strings representing the expected contents of the - history buffer. - """ - # First, check to see if the length is what we expect. - test_case.assertEqual(len(exp_history), len(test_case.console.history), - ('The number of items in the history is unexpected.\n' - 'exp: ' + str(len(exp_history)) + '\n' - 'got: ' + str(len(test_case.console.history)) + '\n' - 'internal state:\n' + str(test_case.console))) - - # Next, check the actual contents of the history buffer. - for i in range(len(exp_history)): - test_case.assertEqual(exp_history[i], test_case.console.history[i], - (b'history buffer contents are incorrect.\n' - b'exp: ' + exp_history[i] + b'\n' - b'got: ' + test_case.console.history[i] + b'\n' - b'internal state:\n' + - str(test_case.console).encode('ascii'))) + test_case.assertEqual(exp_console_out, console_out) -class TestConsoleEditingMethods(unittest.TestCase): - """Test case to verify all console editing methods.""" - - def setUp(self): - """Setup the test harness.""" - # Setup logging with a timestamp, the module, and the log level. - logging.basicConfig(level=logging.DEBUG, - format=('%(asctime)s - %(module)s -' - ' %(levelname)s - %(message)s')) - - # Create a temp file and set both the controller and peripheral PTYs to the - # file to create a loopback. - self.tempfile = tempfile.TemporaryFile() - - # Create some mock pipes. These won't be used since we'll mock out sends - # to the interpreter. - mock_pipe_end_0, mock_pipe_end_1 = threadproc_shim.Pipe() - self.console = console.Console(self.tempfile.fileno(), self.tempfile, - tempfile.TemporaryFile(), - mock_pipe_end_0, mock_pipe_end_1, "EC") - - # Console editing methods are only valid for enhanced EC images, therefore - # we have to assume that the "EC" we're talking to is enhanced. By default, - # the console believes that the EC it's communicating with is NOT enhanced - # which is why we have to override it here. - self.console.enhanced_ec = True - self.console.CheckForEnhancedECImage = mock.MagicMock(return_value=True) - - def test_EnteringChars(self): - """Verify that characters are echoed onto the console.""" - test_str = b'abc' - input_stream = BytesToByteList(test_str) - - # Send the characters in. - for byte in input_stream: - self.console.HandleChar(byte) - - # Check the input position. - exp_pos = len(test_str) - CheckInputBufferPosition(self, exp_pos) - - # Verify that the input buffer is correct. - expected_buffer = test_str - CheckInputBuffer(self, expected_buffer) - - # Check console output - exp_console_out = test_str - CheckConsoleOutput(self, exp_console_out) - - def test_EnteringDeletingMoreCharsThanEntered(self): - """Verify that we can press backspace more than we have entered chars.""" - test_str = b'spamspam' - input_stream = BytesToByteList(test_str) - - # Send the characters in. - for byte in input_stream: - self.console.HandleChar(byte) - - # Now backspace 1 more than what we sent. - input_stream = [] - for _ in range(len(test_str) + 1): - input_stream.append(console.ControlKey.BACKSPACE) - - # Send that sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # First, verify that input buffer position is 0. - CheckInputBufferPosition(self, 0) - - # Next, examine the output stream for the correct sequence. - exp_console_out = test_str - for _ in range(len(test_str)): - exp_console_out += BACKSPACE_STRING - - # Now, verify that we got what we expected. - CheckConsoleOutput(self, exp_console_out) - - def test_EnteringMoreThanCharLimit(self): - """Verify that we drop characters when the line is too long.""" - test_str = self.console.line_limit * b'o' # All allowed. - test_str += 5 * b'x' # All should be dropped. - input_stream = BytesToByteList(test_str) - - # Send the characters in. - for byte in input_stream: - self.console.HandleChar(byte) - - # First, we expect that input buffer position should be equal to the line - # limit. - exp_pos = self.console.line_limit - CheckInputBufferPosition(self, exp_pos) - - # The input buffer should only hold until the line limit. - exp_buffer = test_str[0:self.console.line_limit] - CheckInputBuffer(self, exp_buffer) - - # Lastly, check that the extra characters are not printed. - exp_console_out = exp_buffer - CheckConsoleOutput(self, exp_console_out) - - def test_ValidKeysOnLongLine(self): - """Verify that we can still press valid keys if the line is too long.""" - # Fill the line. - test_str = self.console.line_limit * b'o' - exp_console_out = test_str - # Try to fill it even more; these should all be dropped. - test_str += 5 * b'x' - input_stream = BytesToByteList(test_str) - - # We should be able to press the following keys: - # - Backspace - # - Arrow Keys/CTRL+B/CTRL+F/CTRL+P/CTRL+N - # - Delete - # - Home/CTRL+A - # - End/CTRL+E - # - Carriage Return - - # Backspace 1 character - input_stream.append(console.ControlKey.BACKSPACE) - exp_console_out += BACKSPACE_STRING - # Refill the line. - input_stream.extend(BytesToByteList(b'o')) - exp_console_out += b'o' - - # Left arrow key. - input_stream.extend(Keys.LEFT_ARROW) - exp_console_out += OutputStream.MoveCursorLeft(1) - - # Right arrow key. - input_stream.extend(Keys.RIGHT_ARROW) - exp_console_out += OutputStream.MoveCursorRight(1) - - # CTRL+B - input_stream.append(console.ControlKey.CTRL_B) - exp_console_out += OutputStream.MoveCursorLeft(1) - - # CTRL+F - input_stream.append(console.ControlKey.CTRL_F) - exp_console_out += OutputStream.MoveCursorRight(1) - - # Let's press enter now so we can test up and down. - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - exp_console_out += b'\r\n' + self.console.prompt - - # Up arrow key. - input_stream.extend(Keys.UP_ARROW) - exp_console_out += test_str[:self.console.line_limit] - - # Down arrow key. - input_stream.extend(Keys.DOWN_ARROW) - # Since the line was blank, we have to backspace the entire line. - exp_console_out += self.console.line_limit * BACKSPACE_STRING - - # CTRL+P - input_stream.append(console.ControlKey.CTRL_P) - exp_console_out += test_str[:self.console.line_limit] - - # CTRL+N - input_stream.append(console.ControlKey.CTRL_N) - # Since the line was blank, we have to backspace the entire line. - exp_console_out += self.console.line_limit * BACKSPACE_STRING - - # Press the Up arrow key to reprint the long line. - input_stream.extend(Keys.UP_ARROW) - exp_console_out += test_str[:self.console.line_limit] - - # Press the Home key to jump to the beginning of the line. - input_stream.extend(Keys.HOME) - exp_console_out += OutputStream.MoveCursorLeft(self.console.line_limit) - - # Press the End key to jump to the end of the line. - input_stream.extend(Keys.END) - exp_console_out += OutputStream.MoveCursorRight(self.console.line_limit) - - # Press CTRL+A to jump to the beginning of the line. - input_stream.append(console.ControlKey.CTRL_A) - exp_console_out += OutputStream.MoveCursorLeft(self.console.line_limit) - - # Press CTRL+E to jump to the end of the line. - input_stream.extend(Keys.END) - exp_console_out += OutputStream.MoveCursorRight(self.console.line_limit) - - # Move left one column so we can delete a character. - input_stream.extend(Keys.LEFT_ARROW) - exp_console_out += OutputStream.MoveCursorLeft(1) - - # Press the delete key. - input_stream.extend(Keys.DEL) - # This should look like a space, and then move cursor left 1 column since - # we're at the end of line. - exp_console_out += b' ' + OutputStream.MoveCursorLeft(1) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # Verify everything happened correctly. - CheckConsoleOutput(self, exp_console_out) - - def test_BackspaceOnEmptyLine(self): - """Verify that we can backspace on an empty line with no bad effects.""" - # Send a single backspace. - test_str = [console.ControlKey.BACKSPACE] - - # Send the characters in. - for byte in test_str: - self.console.HandleChar(byte) - - # Check the input position. - exp_pos = 0 - CheckInputBufferPosition(self, exp_pos) - - # Check that buffer is empty. - exp_input_buffer = b'' - CheckInputBuffer(self, exp_input_buffer) - - # Check that the console output is empty. - exp_console_out = b'' - CheckConsoleOutput(self, exp_console_out) - - def test_BackspaceWithinLine(self): - """Verify that we shift the chars over when backspacing within a line.""" - # Misspell 'help' - test_str = b'heelp' - input_stream = BytesToByteList(test_str) - # Use the arrow key to go back to fix it. - # Move cursor left 1 column. - input_stream.extend(2*Keys.LEFT_ARROW) - # Backspace once to remove the extra 'e'. - input_stream.append(console.ControlKey.BACKSPACE) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # Verify the input buffer - exp_input_buffer = b'help' - CheckInputBuffer(self, exp_input_buffer) - - # Verify the input buffer position. It should be at 2 (cursor over the 'l') - CheckInputBufferPosition(self, 2) - - # We expect the console output to be the test string, with two moves to the - # left, another move left, and then the rest of the line followed by a - # space. - exp_console_out = test_str - exp_console_out += 2 * OutputStream.MoveCursorLeft(1) - - # Move cursor left 1 column. - exp_console_out += OutputStream.MoveCursorLeft(1) - # Rest of the line and a space. (test_str in this case) - exp_console_out += b'lp ' - # Reset the cursor 2 + 1 to the left. - exp_console_out += OutputStream.MoveCursorLeft(3) - - # Verify console output. - CheckConsoleOutput(self, exp_console_out) - - def test_JumpToBeginningOfLineViaCtrlA(self): - """Verify that we can jump to the beginning of a line with Ctrl+A.""" - # Enter some chars and press CTRL+A - test_str = b'abc' - input_stream = BytesToByteList(test_str) + [console.ControlKey.CTRL_A] - - # Send the characters in. - for byte in input_stream: - self.console.HandleChar(byte) - - # We expect to see our test string followed by a move cursor left. - exp_console_out = test_str - exp_console_out += OutputStream.MoveCursorLeft(len(test_str)) - - # Check to see what whas printed on the console. - CheckConsoleOutput(self, exp_console_out) - - # Check that the input buffer position is now 0. - CheckInputBufferPosition(self, 0) - - # Check input buffer still contains our test string. - CheckInputBuffer(self, test_str) - - def test_JumpToBeginningOfLineViaHomeKey(self): - """Jump to beginning of line via HOME key.""" - test_str = b'version' - input_stream = BytesToByteList(test_str) - input_stream.extend(Keys.HOME) - - # Send out the stream. - for byte in input_stream: - self.console.HandleChar(byte) - - # First, verify that input buffer position is now 0. - CheckInputBufferPosition(self, 0) - - # Next, verify that the input buffer did not change. - CheckInputBuffer(self, test_str) - - # Lastly, check that the cursor moved correctly. - exp_console_out = test_str - exp_console_out += OutputStream.MoveCursorLeft(len(test_str)) - CheckConsoleOutput(self, exp_console_out) - - def test_JumpToEndOfLineViaEndKey(self): - """Jump to the end of the line using the END key.""" - test_str = b'version' - input_stream = BytesToByteList(test_str) - input_stream += [console.ControlKey.CTRL_A] - # Now, jump to the end of the line. - input_stream.extend(Keys.END) - - # Send out the stream. - for byte in input_stream: - self.console.HandleChar(byte) - - # Verify that the input buffer position is correct. This should be at the - # end of the test string. - CheckInputBufferPosition(self, len(test_str)) - - # The expected output should be the test string, followed by a jump to the - # beginning of the line, and lastly a jump to the end of the line. - exp_console_out = test_str - exp_console_out += OutputStream.MoveCursorLeft(len(test_str)) - # Now the jump back to the end of the line. - exp_console_out += OutputStream.MoveCursorRight(len(test_str)) - - # Verify console output stream. - CheckConsoleOutput(self, exp_console_out) - - def test_JumpToEndOfLineViaCtrlE(self): - """Enter some chars and then try to jump to the end. (Should be a no-op)""" - test_str = b'sysinfo' - input_stream = BytesToByteList(test_str) - input_stream.append(console.ControlKey.CTRL_E) - - # Send out the stream - for byte in input_stream: - self.console.HandleChar(byte) - - # Verify that the input buffer position isn't any further than we expect. - # At this point, the position should be at the end of the test string. - CheckInputBufferPosition(self, len(test_str)) - - # Now, let's try to jump to the beginning and then jump back to the end. - input_stream = [console.ControlKey.CTRL_A, console.ControlKey.CTRL_E] - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # Perform the same verification. - CheckInputBufferPosition(self, len(test_str)) - - # Lastly try to jump again, beyond the end. - input_stream = [console.ControlKey.CTRL_E] - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # Perform the same verification. - CheckInputBufferPosition(self, len(test_str)) - - # We expect to see the test string, a jump to the beginning of the line, and - # one jump to the end of the line. - exp_console_out = test_str - # Jump to beginning. - exp_console_out += OutputStream.MoveCursorLeft(len(test_str)) - # Jump back to end. - exp_console_out += OutputStream.MoveCursorRight(len(test_str)) - - # Verify the console output. - CheckConsoleOutput(self, exp_console_out) - - def test_MoveLeftWithArrowKey(self): - """Move cursor left one column with arrow key.""" - test_str = b'tastyspam' - input_stream = BytesToByteList(test_str) - input_stream.extend(Keys.LEFT_ARROW) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # Verify that the input buffer position is 1 less than the length. - CheckInputBufferPosition(self, len(test_str) - 1) - - # Also, verify that the input buffer is not modified. - CheckInputBuffer(self, test_str) - - # We expect the test string, followed by a one column move left. - exp_console_out = test_str + OutputStream.MoveCursorLeft(1) - - # Verify console output. - CheckConsoleOutput(self, exp_console_out) - - def test_MoveLeftWithCtrlB(self): - """Move cursor back one column with Ctrl+B.""" - test_str = b'tastyspam' - input_stream = BytesToByteList(test_str) - input_stream.append(console.ControlKey.CTRL_B) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # Verify that the input buffer position is 1 less than the length. - CheckInputBufferPosition(self, len(test_str) - 1) +def CheckInputBuffer(test_case, exp_input_buffer): + """Verify that the input buffer contains what we expect. - # Also, verify that the input buffer is not modified. - CheckInputBuffer(self, test_str) + Args: + test_case: A unittest.TestCase object representing the current unit test. + exp_input_buffer: A string containing the contents of the current input + buffer. + """ + test_case.assertEqual( + exp_input_buffer, + test_case.console.input_buffer, + ( + b"input buffer does not match expected.\n" + b"expected: |" + exp_input_buffer + b"|\n" + b"got: |" + + test_case.console.input_buffer + + b"|\n" + + str(test_case.console).encode("ascii") + ), + ) - # We expect the test string, followed by a one column move left. - exp_console_out = test_str + OutputStream.MoveCursorLeft(1) - # Verify console output. - CheckConsoleOutput(self, exp_console_out) +def CheckInputBufferPosition(test_case, exp_pos): + """Verify the input buffer position. - def test_MoveRightWithArrowKey(self): - """Move cursor one column to the right with the arrow key.""" - test_str = b'version' - input_stream = BytesToByteList(test_str) - # Jump to beginning of line. - input_stream.append(console.ControlKey.CTRL_A) - # Press right arrow key. - input_stream.extend(Keys.RIGHT_ARROW) + Args: + test_case: A unittest.TestCase object representing the current unit test. + exp_pos: An integer representing the expected input buffer position. + """ + test_case.assertEqual( + exp_pos, + test_case.console.input_buffer_pos, + "input buffer position is incorrect.\ngot: " + + str(test_case.console.input_buffer_pos) + + "\nexp: " + + str(exp_pos) + + "\n" + + str(test_case.console), + ) - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - # Verify that the input buffer position is 1. - CheckInputBufferPosition(self, 1) +def CheckHistoryBuffer(test_case, exp_history): + """Verify that the items in the history buffer are what we expect. - # Also, verify that the input buffer is not modified. - CheckInputBuffer(self, test_str) + Args: + test_case: A unittest.TestCase object representing the current unit test. + exp_history: A list of strings representing the expected contents of the + history buffer. + """ + # First, check to see if the length is what we expect. + test_case.assertEqual( + len(exp_history), + len(test_case.console.history), + ( + "The number of items in the history is unexpected.\n" + "exp: " + str(len(exp_history)) + "\n" + "got: " + str(len(test_case.console.history)) + "\n" + "internal state:\n" + str(test_case.console) + ), + ) + + # Next, check the actual contents of the history buffer. + for i in range(len(exp_history)): + test_case.assertEqual( + exp_history[i], + test_case.console.history[i], + ( + b"history buffer contents are incorrect.\n" + b"exp: " + exp_history[i] + b"\n" + b"got: " + test_case.console.history[i] + b"\n" + b"internal state:\n" + str(test_case.console).encode("ascii") + ), + ) - # We expect the test string, followed by a jump to the beginning of the - # line, and finally a move right 1. - exp_console_out = test_str + OutputStream.MoveCursorLeft(len((test_str))) - - # A move right 1 column. - exp_console_out += OutputStream.MoveCursorRight(1) - - # Verify console output. - CheckConsoleOutput(self, exp_console_out) - - def test_MoveRightWithCtrlF(self): - """Move cursor forward one column with Ctrl+F.""" - test_str = b'panicinfo' - input_stream = BytesToByteList(test_str) - input_stream.append(console.ControlKey.CTRL_A) - # Now, move right one column. - input_stream.append(console.ControlKey.CTRL_F) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # Verify that the input buffer position is 1. - CheckInputBufferPosition(self, 1) - - # Also, verify that the input buffer is not modified. - CheckInputBuffer(self, test_str) - - # We expect the test string, followed by a jump to the beginning of the - # line, and finally a move right 1. - exp_console_out = test_str + OutputStream.MoveCursorLeft(len((test_str))) - - # A move right 1 column. - exp_console_out += OutputStream.MoveCursorRight(1) - - # Verify console output. - CheckConsoleOutput(self, exp_console_out) - - def test_ImpossibleMoveLeftWithArrowKey(self): - """Verify that we can't move left at the beginning of the line.""" - # We shouldn't be able to move left if we're at the beginning of the line. - input_stream = Keys.LEFT_ARROW - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # Nothing should have been output. - exp_console_output = b'' - CheckConsoleOutput(self, exp_console_output) - - # The input buffer position should still be 0. - CheckInputBufferPosition(self, 0) - - # The input buffer itself should be empty. - CheckInputBuffer(self, b'') - - def test_ImpossibleMoveRightWithArrowKey(self): - """Verify that we can't move right at the end of the line.""" - # We shouldn't be able to move right if we're at the end of the line. - input_stream = Keys.RIGHT_ARROW - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # Nothing should have been output. - exp_console_output = b'' - CheckConsoleOutput(self, exp_console_output) - - # The input buffer position should still be 0. - CheckInputBufferPosition(self, 0) - - # The input buffer itself should be empty. - CheckInputBuffer(self, b'') - - def test_KillEntireLine(self): - """Verify that we can kill an entire line with Ctrl+K.""" - test_str = b'accelinfo on' - input_stream = BytesToByteList(test_str) - # Jump to beginning of line and then kill it with Ctrl+K. - input_stream.extend([console.ControlKey.CTRL_A, console.ControlKey.CTRL_K]) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # First, we expect that the input buffer is empty. - CheckInputBuffer(self, b'') - - # The buffer position should be 0. - CheckInputBufferPosition(self, 0) - - # What we expect to see on the console stream should be the following. The - # test string, a jump to the beginning of the line, then jump back to the - # end of the line and replace the line with spaces. - exp_console_out = test_str - # Jump to beginning of line. - exp_console_out += OutputStream.MoveCursorLeft(len(test_str)) - # Jump to end of line. - exp_console_out += OutputStream.MoveCursorRight(len(test_str)) - # Replace line with spaces, which looks like backspaces. - for _ in range(len(test_str)): - exp_console_out += BACKSPACE_STRING - - # Verify the console output. - CheckConsoleOutput(self, exp_console_out) - - def test_KillPartialLine(self): - """Verify that we can kill a portion of a line.""" - test_str = b'accelread 0 1' - input_stream = BytesToByteList(test_str) - len_to_kill = 5 - for _ in range(len_to_kill): - # Move cursor left - input_stream.extend(Keys.LEFT_ARROW) - # Now kill - input_stream.append(console.ControlKey.CTRL_K) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # First, check that the input buffer was truncated. - exp_input_buffer = test_str[:-len_to_kill] - CheckInputBuffer(self, exp_input_buffer) - - # Verify the input buffer position. - CheckInputBufferPosition(self, len(test_str) - len_to_kill) - - # The console output stream that we expect is the test string followed by a - # move left of len_to_kill, then a jump to the end of the line and backspace - # of len_to_kill. - exp_console_out = test_str - for _ in range(len_to_kill): - # Move left 1 column. - exp_console_out += OutputStream.MoveCursorLeft(1) - # Then jump to the end of the line - exp_console_out += OutputStream.MoveCursorRight(len_to_kill) - # Backspace of len_to_kill - for _ in range(len_to_kill): - exp_console_out += BACKSPACE_STRING - - # Verify console output. - CheckConsoleOutput(self, exp_console_out) - - def test_InsertingCharacters(self): - """Verify that we can insert characters within the line.""" - test_str = b'accel 0 1' # Here we forgot the 'read' part in 'accelread' - input_stream = BytesToByteList(test_str) - # We need to move over to the 'l' and add read. - insertion_point = test_str.find(b'l') + 1 - for i in range(len(test_str) - insertion_point): - # Move cursor left. - input_stream.extend(Keys.LEFT_ARROW) - # Now, add in 'read' - added_str = b'read' - input_stream.extend(BytesToByteList(added_str)) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # First, verify that the input buffer is correct. - exp_input_buffer = test_str[:insertion_point] + added_str - exp_input_buffer += test_str[insertion_point:] - CheckInputBuffer(self, exp_input_buffer) - - # Verify that the input buffer position is correct. - exp_input_buffer_pos = insertion_point + len(added_str) - CheckInputBufferPosition(self, exp_input_buffer_pos) - - # The console output stream that we expect is the test string, followed by - # move cursor left until the 'l' was found, the added test string while - # shifting characters around. - exp_console_out = test_str - for i in range(len(test_str) - insertion_point): - # Move cursor left. - exp_console_out += OutputStream.MoveCursorLeft(1) - - # Now for each character, write the rest of the line will be shifted to the - # right one column. - for i in range(len(added_str)): - # Printed character. - exp_console_out += added_str[i:i+1] - # The rest of the line - exp_console_out += test_str[insertion_point:] - # Reset the cursor back left - reset_dist = len(test_str[insertion_point:]) - exp_console_out += OutputStream.MoveCursorLeft(reset_dist) - - # Verify the console output. - CheckConsoleOutput(self, exp_console_out) - - def test_StoreCommandHistory(self): - """Verify that entered commands are stored in the history.""" - test_commands = [] - test_commands.append(b'help') - test_commands.append(b'version') - test_commands.append(b'accelread 0 1') - input_stream = [] - for c in test_commands: - input_stream.extend(BytesToByteList(c)) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # We expect to have the test commands in the history buffer. - exp_history_buf = test_commands - CheckHistoryBuffer(self, exp_history_buf) - - def test_CycleUpThruCommandHistory(self): - """Verify that the UP arrow key will print itmes in the history buffer.""" - # Enter some commands. - test_commands = [b'version', b'accelrange 0', b'battery', b'gettime'] - input_stream = [] - for command in test_commands: - input_stream.extend(BytesToByteList(command)) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Now, hit the UP arrow key to print the previous entries. - for i in range(len(test_commands)): - input_stream.extend(Keys.UP_ARROW) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # The expected output should be test commands with prompts printed in - # between, followed by line kills with the previous test commands printed. - exp_console_out = b'' - for i in range(len(test_commands)): - exp_console_out += test_commands[i] + b'\r\n' + self.console.prompt - - # When we press up, the line should be cleared and print the previous buffer - # entry. - for i in range(len(test_commands)-1, 0, -1): - exp_console_out += test_commands[i] - # Backspace to the beginning. - for i in range(len(test_commands[i])): - exp_console_out += BACKSPACE_STRING - # The last command should just be printed out with no backspacing. - exp_console_out += test_commands[0] - - # Now, verify. - CheckConsoleOutput(self, exp_console_out) - - def test_UpArrowOnEmptyHistory(self): - """Ensure nothing happens if the history is empty.""" - # Press the up arrow key twice. - input_stream = 2 * Keys.UP_ARROW - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # We expect nothing to have happened. - exp_console_out = b'' - exp_input_buffer = b'' - exp_input_buffer_pos = 0 - exp_history_buf = [] - - # Verify. - CheckConsoleOutput(self, exp_console_out) - CheckInputBufferPosition(self, exp_input_buffer_pos) - CheckInputBuffer(self, exp_input_buffer) - CheckHistoryBuffer(self, exp_history_buf) - - def test_UpArrowDoesNotGoOutOfBounds(self): - """Verify that pressing the up arrow many times won't go out of bounds.""" - # Enter one command. - test_str = b'help version' - input_stream = BytesToByteList(test_str) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - # Then press the up arrow key twice. - input_stream.extend(2 * Keys.UP_ARROW) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # Verify that the history buffer is correct. - exp_history_buf = [test_str] - CheckHistoryBuffer(self, exp_history_buf) - - # We expect that the console output should only contain our entered command, - # a new prompt, and then our command aggain. - exp_console_out = test_str + b'\r\n' + self.console.prompt - # Pressing up should reprint the command we entered. - exp_console_out += test_str - - # Verify. - CheckConsoleOutput(self, exp_console_out) - - def test_CycleDownThruCommandHistory(self): - """Verify that we can select entries by hitting the down arrow.""" - # Enter at least 4 commands. - test_commands = [b'version', b'accelrange 0', b'battery', b'gettime'] - input_stream = [] - for command in test_commands: - input_stream.extend(BytesToByteList(command)) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Now, hit the UP arrow key twice to print the previous two entries. - for i in range(2): - input_stream.extend(Keys.UP_ARROW) - - # Now, hit the DOWN arrow key twice to print the newer entries. - input_stream.extend(2*Keys.DOWN_ARROW) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # The expected output should be commands that we entered, followed by - # prompts, then followed by our last two commands in reverse. Then, we - # should see the last entry in the list, followed by the saved partial cmd - # of a blank line. - exp_console_out = b'' - for i in range(len(test_commands)): - exp_console_out += test_commands[i] + b'\r\n' + self.console.prompt - - # When we press up, the line should be cleared and print the previous buffer - # entry. - for i in range(len(test_commands)-1, 1, -1): - exp_console_out += test_commands[i] - # Backspace to the beginning. - for i in range(len(test_commands[i])): +class TestConsoleEditingMethods(unittest.TestCase): + """Test case to verify all console editing methods.""" + + def setUp(self): + """Setup the test harness.""" + # Setup logging with a timestamp, the module, and the log level. + logging.basicConfig( + level=logging.DEBUG, + format=("%(asctime)s - %(module)s - %(levelname)s - %(message)s"), + ) + + # Create a temp file and set both the controller and peripheral PTYs to the + # file to create a loopback. + self.tempfile = tempfile.TemporaryFile() + + # Create some mock pipes. These won't be used since we'll mock out sends + # to the interpreter. + mock_pipe_end_0, mock_pipe_end_1 = threadproc_shim.Pipe() + self.console = console.Console( + self.tempfile.fileno(), + self.tempfile, + tempfile.TemporaryFile(), + mock_pipe_end_0, + mock_pipe_end_1, + "EC", + ) + + # Console editing methods are only valid for enhanced EC images, therefore + # we have to assume that the "EC" we're talking to is enhanced. By default, + # the console believes that the EC it's communicating with is NOT enhanced + # which is why we have to override it here. + self.console.enhanced_ec = True + self.console.CheckForEnhancedECImage = mock.MagicMock(return_value=True) + + def test_EnteringChars(self): + """Verify that characters are echoed onto the console.""" + test_str = b"abc" + input_stream = BytesToByteList(test_str) + + # Send the characters in. + for byte in input_stream: + self.console.HandleChar(byte) + + # Check the input position. + exp_pos = len(test_str) + CheckInputBufferPosition(self, exp_pos) + + # Verify that the input buffer is correct. + expected_buffer = test_str + CheckInputBuffer(self, expected_buffer) + + # Check console output + exp_console_out = test_str + CheckConsoleOutput(self, exp_console_out) + + def test_EnteringDeletingMoreCharsThanEntered(self): + """Verify that we can press backspace more than we have entered chars.""" + test_str = b"spamspam" + input_stream = BytesToByteList(test_str) + + # Send the characters in. + for byte in input_stream: + self.console.HandleChar(byte) + + # Now backspace 1 more than what we sent. + input_stream = [] + for _ in range(len(test_str) + 1): + input_stream.append(console.ControlKey.BACKSPACE) + + # Send that sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # First, verify that input buffer position is 0. + CheckInputBufferPosition(self, 0) + + # Next, examine the output stream for the correct sequence. + exp_console_out = test_str + for _ in range(len(test_str)): + exp_console_out += BACKSPACE_STRING + + # Now, verify that we got what we expected. + CheckConsoleOutput(self, exp_console_out) + + def test_EnteringMoreThanCharLimit(self): + """Verify that we drop characters when the line is too long.""" + test_str = self.console.line_limit * b"o" # All allowed. + test_str += 5 * b"x" # All should be dropped. + input_stream = BytesToByteList(test_str) + + # Send the characters in. + for byte in input_stream: + self.console.HandleChar(byte) + + # First, we expect that input buffer position should be equal to the line + # limit. + exp_pos = self.console.line_limit + CheckInputBufferPosition(self, exp_pos) + + # The input buffer should only hold until the line limit. + exp_buffer = test_str[0 : self.console.line_limit] + CheckInputBuffer(self, exp_buffer) + + # Lastly, check that the extra characters are not printed. + exp_console_out = exp_buffer + CheckConsoleOutput(self, exp_console_out) + + def test_ValidKeysOnLongLine(self): + """Verify that we can still press valid keys if the line is too long.""" + # Fill the line. + test_str = self.console.line_limit * b"o" + exp_console_out = test_str + # Try to fill it even more; these should all be dropped. + test_str += 5 * b"x" + input_stream = BytesToByteList(test_str) + + # We should be able to press the following keys: + # - Backspace + # - Arrow Keys/CTRL+B/CTRL+F/CTRL+P/CTRL+N + # - Delete + # - Home/CTRL+A + # - End/CTRL+E + # - Carriage Return + + # Backspace 1 character + input_stream.append(console.ControlKey.BACKSPACE) exp_console_out += BACKSPACE_STRING + # Refill the line. + input_stream.extend(BytesToByteList(b"o")) + exp_console_out += b"o" + + # Left arrow key. + input_stream.extend(Keys.LEFT_ARROW) + exp_console_out += OutputStream.MoveCursorLeft(1) + + # Right arrow key. + input_stream.extend(Keys.RIGHT_ARROW) + exp_console_out += OutputStream.MoveCursorRight(1) + + # CTRL+B + input_stream.append(console.ControlKey.CTRL_B) + exp_console_out += OutputStream.MoveCursorLeft(1) + + # CTRL+F + input_stream.append(console.ControlKey.CTRL_F) + exp_console_out += OutputStream.MoveCursorRight(1) + + # Let's press enter now so we can test up and down. + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + exp_console_out += b"\r\n" + self.console.prompt + + # Up arrow key. + input_stream.extend(Keys.UP_ARROW) + exp_console_out += test_str[: self.console.line_limit] + + # Down arrow key. + input_stream.extend(Keys.DOWN_ARROW) + # Since the line was blank, we have to backspace the entire line. + exp_console_out += self.console.line_limit * BACKSPACE_STRING + + # CTRL+P + input_stream.append(console.ControlKey.CTRL_P) + exp_console_out += test_str[: self.console.line_limit] + + # CTRL+N + input_stream.append(console.ControlKey.CTRL_N) + # Since the line was blank, we have to backspace the entire line. + exp_console_out += self.console.line_limit * BACKSPACE_STRING + + # Press the Up arrow key to reprint the long line. + input_stream.extend(Keys.UP_ARROW) + exp_console_out += test_str[: self.console.line_limit] + + # Press the Home key to jump to the beginning of the line. + input_stream.extend(Keys.HOME) + exp_console_out += OutputStream.MoveCursorLeft(self.console.line_limit) + + # Press the End key to jump to the end of the line. + input_stream.extend(Keys.END) + exp_console_out += OutputStream.MoveCursorRight(self.console.line_limit) + + # Press CTRL+A to jump to the beginning of the line. + input_stream.append(console.ControlKey.CTRL_A) + exp_console_out += OutputStream.MoveCursorLeft(self.console.line_limit) + + # Press CTRL+E to jump to the end of the line. + input_stream.extend(Keys.END) + exp_console_out += OutputStream.MoveCursorRight(self.console.line_limit) + + # Move left one column so we can delete a character. + input_stream.extend(Keys.LEFT_ARROW) + exp_console_out += OutputStream.MoveCursorLeft(1) + + # Press the delete key. + input_stream.extend(Keys.DEL) + # This should look like a space, and then move cursor left 1 column since + # we're at the end of line. + exp_console_out += b" " + OutputStream.MoveCursorLeft(1) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # Verify everything happened correctly. + CheckConsoleOutput(self, exp_console_out) + + def test_BackspaceOnEmptyLine(self): + """Verify that we can backspace on an empty line with no bad effects.""" + # Send a single backspace. + test_str = [console.ControlKey.BACKSPACE] + + # Send the characters in. + for byte in test_str: + self.console.HandleChar(byte) + + # Check the input position. + exp_pos = 0 + CheckInputBufferPosition(self, exp_pos) + + # Check that buffer is empty. + exp_input_buffer = b"" + CheckInputBuffer(self, exp_input_buffer) + + # Check that the console output is empty. + exp_console_out = b"" + CheckConsoleOutput(self, exp_console_out) + + def test_BackspaceWithinLine(self): + """Verify that we shift the chars over when backspacing within a line.""" + # Misspell 'help' + test_str = b"heelp" + input_stream = BytesToByteList(test_str) + # Use the arrow key to go back to fix it. + # Move cursor left 1 column. + input_stream.extend(2 * Keys.LEFT_ARROW) + # Backspace once to remove the extra 'e'. + input_stream.append(console.ControlKey.BACKSPACE) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # Verify the input buffer + exp_input_buffer = b"help" + CheckInputBuffer(self, exp_input_buffer) + + # Verify the input buffer position. It should be at 2 (cursor over the 'l') + CheckInputBufferPosition(self, 2) + + # We expect the console output to be the test string, with two moves to the + # left, another move left, and then the rest of the line followed by a + # space. + exp_console_out = test_str + exp_console_out += 2 * OutputStream.MoveCursorLeft(1) + + # Move cursor left 1 column. + exp_console_out += OutputStream.MoveCursorLeft(1) + # Rest of the line and a space. (test_str in this case) + exp_console_out += b"lp " + # Reset the cursor 2 + 1 to the left. + exp_console_out += OutputStream.MoveCursorLeft(3) + + # Verify console output. + CheckConsoleOutput(self, exp_console_out) + + def test_JumpToBeginningOfLineViaCtrlA(self): + """Verify that we can jump to the beginning of a line with Ctrl+A.""" + # Enter some chars and press CTRL+A + test_str = b"abc" + input_stream = BytesToByteList(test_str) + [console.ControlKey.CTRL_A] + + # Send the characters in. + for byte in input_stream: + self.console.HandleChar(byte) + + # We expect to see our test string followed by a move cursor left. + exp_console_out = test_str + exp_console_out += OutputStream.MoveCursorLeft(len(test_str)) + + # Check to see what whas printed on the console. + CheckConsoleOutput(self, exp_console_out) + + # Check that the input buffer position is now 0. + CheckInputBufferPosition(self, 0) + + # Check input buffer still contains our test string. + CheckInputBuffer(self, test_str) + + def test_JumpToBeginningOfLineViaHomeKey(self): + """Jump to beginning of line via HOME key.""" + test_str = b"version" + input_stream = BytesToByteList(test_str) + input_stream.extend(Keys.HOME) + + # Send out the stream. + for byte in input_stream: + self.console.HandleChar(byte) + + # First, verify that input buffer position is now 0. + CheckInputBufferPosition(self, 0) + + # Next, verify that the input buffer did not change. + CheckInputBuffer(self, test_str) + + # Lastly, check that the cursor moved correctly. + exp_console_out = test_str + exp_console_out += OutputStream.MoveCursorLeft(len(test_str)) + CheckConsoleOutput(self, exp_console_out) + + def test_JumpToEndOfLineViaEndKey(self): + """Jump to the end of the line using the END key.""" + test_str = b"version" + input_stream = BytesToByteList(test_str) + input_stream += [console.ControlKey.CTRL_A] + # Now, jump to the end of the line. + input_stream.extend(Keys.END) + + # Send out the stream. + for byte in input_stream: + self.console.HandleChar(byte) + + # Verify that the input buffer position is correct. This should be at the + # end of the test string. + CheckInputBufferPosition(self, len(test_str)) + + # The expected output should be the test string, followed by a jump to the + # beginning of the line, and lastly a jump to the end of the line. + exp_console_out = test_str + exp_console_out += OutputStream.MoveCursorLeft(len(test_str)) + # Now the jump back to the end of the line. + exp_console_out += OutputStream.MoveCursorRight(len(test_str)) + + # Verify console output stream. + CheckConsoleOutput(self, exp_console_out) + + def test_JumpToEndOfLineViaCtrlE(self): + """Enter some chars and then try to jump to the end. (Should be a no-op)""" + test_str = b"sysinfo" + input_stream = BytesToByteList(test_str) + input_stream.append(console.ControlKey.CTRL_E) + + # Send out the stream + for byte in input_stream: + self.console.HandleChar(byte) + + # Verify that the input buffer position isn't any further than we expect. + # At this point, the position should be at the end of the test string. + CheckInputBufferPosition(self, len(test_str)) + + # Now, let's try to jump to the beginning and then jump back to the end. + input_stream = [console.ControlKey.CTRL_A, console.ControlKey.CTRL_E] + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # Perform the same verification. + CheckInputBufferPosition(self, len(test_str)) + + # Lastly try to jump again, beyond the end. + input_stream = [console.ControlKey.CTRL_E] + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # Perform the same verification. + CheckInputBufferPosition(self, len(test_str)) + + # We expect to see the test string, a jump to the beginning of the line, and + # one jump to the end of the line. + exp_console_out = test_str + # Jump to beginning. + exp_console_out += OutputStream.MoveCursorLeft(len(test_str)) + # Jump back to end. + exp_console_out += OutputStream.MoveCursorRight(len(test_str)) + + # Verify the console output. + CheckConsoleOutput(self, exp_console_out) + + def test_MoveLeftWithArrowKey(self): + """Move cursor left one column with arrow key.""" + test_str = b"tastyspam" + input_stream = BytesToByteList(test_str) + input_stream.extend(Keys.LEFT_ARROW) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # Verify that the input buffer position is 1 less than the length. + CheckInputBufferPosition(self, len(test_str) - 1) + + # Also, verify that the input buffer is not modified. + CheckInputBuffer(self, test_str) + + # We expect the test string, followed by a one column move left. + exp_console_out = test_str + OutputStream.MoveCursorLeft(1) + + # Verify console output. + CheckConsoleOutput(self, exp_console_out) + + def test_MoveLeftWithCtrlB(self): + """Move cursor back one column with Ctrl+B.""" + test_str = b"tastyspam" + input_stream = BytesToByteList(test_str) + input_stream.append(console.ControlKey.CTRL_B) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # Verify that the input buffer position is 1 less than the length. + CheckInputBufferPosition(self, len(test_str) - 1) + + # Also, verify that the input buffer is not modified. + CheckInputBuffer(self, test_str) + + # We expect the test string, followed by a one column move left. + exp_console_out = test_str + OutputStream.MoveCursorLeft(1) - # When we press down, it should have cleared the last command (which we - # covered with the previous for loop), and then prints the next command. - exp_console_out += test_commands[3] - for i in range(len(test_commands[3])): - exp_console_out += BACKSPACE_STRING - - # Verify console output. - CheckConsoleOutput(self, exp_console_out) - - # Verify input buffer. - exp_input_buffer = b'' # Empty because our partial command was empty. - exp_input_buffer_pos = len(exp_input_buffer) - CheckInputBuffer(self, exp_input_buffer) - CheckInputBufferPosition(self, exp_input_buffer_pos) - - def test_SavingPartialCommandWhenNavigatingHistory(self): - """Verify that partial commands are saved when navigating history.""" - # Enter a command. - test_str = b'accelinfo' - input_stream = BytesToByteList(test_str) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Enter a partial command. - partial_cmd = b'ver' - input_stream.extend(BytesToByteList(partial_cmd)) - - # Hit the UP arrow key. - input_stream.extend(Keys.UP_ARROW) - # Then, the DOWN arrow key. - input_stream.extend(Keys.DOWN_ARROW) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # The expected output should be the command we entered, a prompt, the - # partial command, clearing of the partial command, the command entered, - # clearing of the command entered, and then the partial command. - exp_console_out = test_str + b'\r\n' + self.console.prompt - exp_console_out += partial_cmd - for _ in range(len(partial_cmd)): - exp_console_out += BACKSPACE_STRING - exp_console_out += test_str - for _ in range(len(test_str)): - exp_console_out += BACKSPACE_STRING - exp_console_out += partial_cmd - - # Verify console output. - CheckConsoleOutput(self, exp_console_out) - - # Verify input buffer. - exp_input_buffer = partial_cmd - exp_input_buffer_pos = len(exp_input_buffer) - CheckInputBuffer(self, exp_input_buffer) - CheckInputBufferPosition(self, exp_input_buffer_pos) - - def test_DownArrowOnEmptyHistory(self): - """Ensure nothing happens if the history is empty.""" - # Then press the up down arrow twice. - input_stream = 2 * Keys.DOWN_ARROW - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # We expect nothing to have happened. - exp_console_out = b'' - exp_input_buffer = b'' - exp_input_buffer_pos = 0 - exp_history_buf = [] - - # Verify. - CheckConsoleOutput(self, exp_console_out) - CheckInputBufferPosition(self, exp_input_buffer_pos) - CheckInputBuffer(self, exp_input_buffer) - CheckHistoryBuffer(self, exp_history_buf) - - def test_DeleteCharsUsingDELKey(self): - """Verify that we can delete characters using the DEL key.""" - test_str = b'version' - input_stream = BytesToByteList(test_str) - - # Hit the left arrow key 2 times. - input_stream.extend(2 * Keys.LEFT_ARROW) - - # Press the DEL key. - input_stream.extend(Keys.DEL) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # The expected output should be the command we entered, 2 individual cursor - # moves to the left, and then removing a char and shifting everything to the - # left one column. - exp_console_out = test_str - exp_console_out += 2 * OutputStream.MoveCursorLeft(1) - - # Remove the char by shifting everything to the left one, slicing out the - # remove char. - exp_console_out += test_str[-1:] + b' ' - - # Reset the cursor by moving back 2 columns because of the 'n' and space. - exp_console_out += OutputStream.MoveCursorLeft(2) - - # Verify console output. - CheckConsoleOutput(self, exp_console_out) - - # Verify input buffer. The input buffer should have the char sliced out and - # be positioned where the char was removed. - exp_input_buffer = test_str[:-2] + test_str[-1:] - exp_input_buffer_pos = len(exp_input_buffer) - 1 - CheckInputBuffer(self, exp_input_buffer) - CheckInputBufferPosition(self, exp_input_buffer_pos) - - def test_RepeatedCommandInHistory(self): - """Verify that we don't store 2 consecutive identical commands in history""" - # Enter a few commands. - test_commands = [b'version', b'accelrange 0', b'battery', b'gettime'] - # Repeat the last command. - test_commands.append(test_commands[len(test_commands)-1]) - - input_stream = [] - for command in test_commands: - input_stream.extend(BytesToByteList(command)) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # Verify that the history buffer is correct. The last command, since - # it was repeated, should not have been added to the history. - exp_history_buf = test_commands[0:len(test_commands)-1] - CheckHistoryBuffer(self, exp_history_buf) + # Verify console output. + CheckConsoleOutput(self, exp_console_out) + def test_MoveRightWithArrowKey(self): + """Move cursor one column to the right with the arrow key.""" + test_str = b"version" + input_stream = BytesToByteList(test_str) + # Jump to beginning of line. + input_stream.append(console.ControlKey.CTRL_A) + # Press right arrow key. + input_stream.extend(Keys.RIGHT_ARROW) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # Verify that the input buffer position is 1. + CheckInputBufferPosition(self, 1) -class TestConsoleCompatibility(unittest.TestCase): - """Verify that console can speak to enhanced and non-enhanced EC images.""" - def setUp(self): - """Setup the test harness.""" - # Setup logging with a timestamp, the module, and the log level. - logging.basicConfig(level=logging.DEBUG, - format=('%(asctime)s - %(module)s -' - ' %(levelname)s - %(message)s')) - # Create a temp file and set both the controller and peripheral PTYs to the - # file to create a loopback. - self.tempfile = tempfile.TemporaryFile() - - # Mock out the pipes. - mock_pipe_end_0, mock_pipe_end_1 = mock.MagicMock(), mock.MagicMock() - self.console = console.Console(self.tempfile.fileno(), self.tempfile, - tempfile.TemporaryFile(), - mock_pipe_end_0, mock_pipe_end_1, "EC") - - @mock.patch('ec3po.console.Console.CheckForEnhancedECImage') - def test_ActAsPassThruInNonEnhancedMode(self, mock_check): - """Verify we simply pass everything thru to non-enhanced ECs. + # Also, verify that the input buffer is not modified. + CheckInputBuffer(self, test_str) - Args: - mock_check: A MagicMock object replacing the CheckForEnhancedECImage() - method. - """ - # Set the interrogation mode to always so that we actually interrogate. - self.console.interrogation_mode = b'always' - - # Assume EC interrogations indicate that the image is non-enhanced. - mock_check.return_value = False - - # Press enter, followed by the command, and another enter. - input_stream = [] - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - test_command = b'version' - input_stream.extend(BytesToByteList(test_command)) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # Expected calls to send down the pipe would be each character of the test - # command. - expected_calls = [] - expected_calls.append(mock.call( - six.int2byte(console.ControlKey.CARRIAGE_RETURN))) - for char in test_command: - if six.PY3: - expected_calls.append(mock.call(bytes([char]))) - else: - expected_calls.append(mock.call(char)) - expected_calls.append(mock.call( - six.int2byte(console.ControlKey.CARRIAGE_RETURN))) - - # Verify that the calls happened. - self.console.cmd_pipe.send.assert_has_calls(expected_calls) - - # Since we're acting as a pass-thru, the input buffer should be empty and - # input_buffer_pos is 0. - CheckInputBuffer(self, b'') - CheckInputBufferPosition(self, 0) - - @mock.patch('ec3po.console.Console.CheckForEnhancedECImage') - def test_TransitionFromNonEnhancedToEnhanced(self, mock_check): - """Verify that we transition correctly to enhanced mode. + # We expect the test string, followed by a jump to the beginning of the + # line, and finally a move right 1. + exp_console_out = test_str + OutputStream.MoveCursorLeft( + len((test_str)) + ) + + # A move right 1 column. + exp_console_out += OutputStream.MoveCursorRight(1) + + # Verify console output. + CheckConsoleOutput(self, exp_console_out) + + def test_MoveRightWithCtrlF(self): + """Move cursor forward one column with Ctrl+F.""" + test_str = b"panicinfo" + input_stream = BytesToByteList(test_str) + input_stream.append(console.ControlKey.CTRL_A) + # Now, move right one column. + input_stream.append(console.ControlKey.CTRL_F) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # Verify that the input buffer position is 1. + CheckInputBufferPosition(self, 1) + + # Also, verify that the input buffer is not modified. + CheckInputBuffer(self, test_str) + + # We expect the test string, followed by a jump to the beginning of the + # line, and finally a move right 1. + exp_console_out = test_str + OutputStream.MoveCursorLeft( + len((test_str)) + ) + + # A move right 1 column. + exp_console_out += OutputStream.MoveCursorRight(1) + + # Verify console output. + CheckConsoleOutput(self, exp_console_out) + + def test_ImpossibleMoveLeftWithArrowKey(self): + """Verify that we can't move left at the beginning of the line.""" + # We shouldn't be able to move left if we're at the beginning of the line. + input_stream = Keys.LEFT_ARROW + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # Nothing should have been output. + exp_console_output = b"" + CheckConsoleOutput(self, exp_console_output) + + # The input buffer position should still be 0. + CheckInputBufferPosition(self, 0) + + # The input buffer itself should be empty. + CheckInputBuffer(self, b"") + + def test_ImpossibleMoveRightWithArrowKey(self): + """Verify that we can't move right at the end of the line.""" + # We shouldn't be able to move right if we're at the end of the line. + input_stream = Keys.RIGHT_ARROW + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # Nothing should have been output. + exp_console_output = b"" + CheckConsoleOutput(self, exp_console_output) + + # The input buffer position should still be 0. + CheckInputBufferPosition(self, 0) + + # The input buffer itself should be empty. + CheckInputBuffer(self, b"") + + def test_KillEntireLine(self): + """Verify that we can kill an entire line with Ctrl+K.""" + test_str = b"accelinfo on" + input_stream = BytesToByteList(test_str) + # Jump to beginning of line and then kill it with Ctrl+K. + input_stream.extend( + [console.ControlKey.CTRL_A, console.ControlKey.CTRL_K] + ) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # First, we expect that the input buffer is empty. + CheckInputBuffer(self, b"") + + # The buffer position should be 0. + CheckInputBufferPosition(self, 0) + + # What we expect to see on the console stream should be the following. The + # test string, a jump to the beginning of the line, then jump back to the + # end of the line and replace the line with spaces. + exp_console_out = test_str + # Jump to beginning of line. + exp_console_out += OutputStream.MoveCursorLeft(len(test_str)) + # Jump to end of line. + exp_console_out += OutputStream.MoveCursorRight(len(test_str)) + # Replace line with spaces, which looks like backspaces. + for _ in range(len(test_str)): + exp_console_out += BACKSPACE_STRING + + # Verify the console output. + CheckConsoleOutput(self, exp_console_out) + + def test_KillPartialLine(self): + """Verify that we can kill a portion of a line.""" + test_str = b"accelread 0 1" + input_stream = BytesToByteList(test_str) + len_to_kill = 5 + for _ in range(len_to_kill): + # Move cursor left + input_stream.extend(Keys.LEFT_ARROW) + # Now kill + input_stream.append(console.ControlKey.CTRL_K) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # First, check that the input buffer was truncated. + exp_input_buffer = test_str[:-len_to_kill] + CheckInputBuffer(self, exp_input_buffer) + + # Verify the input buffer position. + CheckInputBufferPosition(self, len(test_str) - len_to_kill) + + # The console output stream that we expect is the test string followed by a + # move left of len_to_kill, then a jump to the end of the line and backspace + # of len_to_kill. + exp_console_out = test_str + for _ in range(len_to_kill): + # Move left 1 column. + exp_console_out += OutputStream.MoveCursorLeft(1) + # Then jump to the end of the line + exp_console_out += OutputStream.MoveCursorRight(len_to_kill) + # Backspace of len_to_kill + for _ in range(len_to_kill): + exp_console_out += BACKSPACE_STRING + + # Verify console output. + CheckConsoleOutput(self, exp_console_out) + + def test_InsertingCharacters(self): + """Verify that we can insert characters within the line.""" + test_str = b"accel 0 1" # Here we forgot the 'read' part in 'accelread' + input_stream = BytesToByteList(test_str) + # We need to move over to the 'l' and add read. + insertion_point = test_str.find(b"l") + 1 + for i in range(len(test_str) - insertion_point): + # Move cursor left. + input_stream.extend(Keys.LEFT_ARROW) + # Now, add in 'read' + added_str = b"read" + input_stream.extend(BytesToByteList(added_str)) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # First, verify that the input buffer is correct. + exp_input_buffer = test_str[:insertion_point] + added_str + exp_input_buffer += test_str[insertion_point:] + CheckInputBuffer(self, exp_input_buffer) + + # Verify that the input buffer position is correct. + exp_input_buffer_pos = insertion_point + len(added_str) + CheckInputBufferPosition(self, exp_input_buffer_pos) + + # The console output stream that we expect is the test string, followed by + # move cursor left until the 'l' was found, the added test string while + # shifting characters around. + exp_console_out = test_str + for i in range(len(test_str) - insertion_point): + # Move cursor left. + exp_console_out += OutputStream.MoveCursorLeft(1) + + # Now for each character, write the rest of the line will be shifted to the + # right one column. + for i in range(len(added_str)): + # Printed character. + exp_console_out += added_str[i : i + 1] + # The rest of the line + exp_console_out += test_str[insertion_point:] + # Reset the cursor back left + reset_dist = len(test_str[insertion_point:]) + exp_console_out += OutputStream.MoveCursorLeft(reset_dist) + + # Verify the console output. + CheckConsoleOutput(self, exp_console_out) + + def test_StoreCommandHistory(self): + """Verify that entered commands are stored in the history.""" + test_commands = [] + test_commands.append(b"help") + test_commands.append(b"version") + test_commands.append(b"accelread 0 1") + input_stream = [] + for c in test_commands: + input_stream.extend(BytesToByteList(c)) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # We expect to have the test commands in the history buffer. + exp_history_buf = test_commands + CheckHistoryBuffer(self, exp_history_buf) + + def test_CycleUpThruCommandHistory(self): + """Verify that the UP arrow key will print itmes in the history buffer.""" + # Enter some commands. + test_commands = [b"version", b"accelrange 0", b"battery", b"gettime"] + input_stream = [] + for command in test_commands: + input_stream.extend(BytesToByteList(command)) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Now, hit the UP arrow key to print the previous entries. + for i in range(len(test_commands)): + input_stream.extend(Keys.UP_ARROW) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # The expected output should be test commands with prompts printed in + # between, followed by line kills with the previous test commands printed. + exp_console_out = b"" + for i in range(len(test_commands)): + exp_console_out += test_commands[i] + b"\r\n" + self.console.prompt + + # When we press up, the line should be cleared and print the previous buffer + # entry. + for i in range(len(test_commands) - 1, 0, -1): + exp_console_out += test_commands[i] + # Backspace to the beginning. + for i in range(len(test_commands[i])): + exp_console_out += BACKSPACE_STRING + + # The last command should just be printed out with no backspacing. + exp_console_out += test_commands[0] + + # Now, verify. + CheckConsoleOutput(self, exp_console_out) + + def test_UpArrowOnEmptyHistory(self): + """Ensure nothing happens if the history is empty.""" + # Press the up arrow key twice. + input_stream = 2 * Keys.UP_ARROW + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # We expect nothing to have happened. + exp_console_out = b"" + exp_input_buffer = b"" + exp_input_buffer_pos = 0 + exp_history_buf = [] + + # Verify. + CheckConsoleOutput(self, exp_console_out) + CheckInputBufferPosition(self, exp_input_buffer_pos) + CheckInputBuffer(self, exp_input_buffer) + CheckHistoryBuffer(self, exp_history_buf) + + def test_UpArrowDoesNotGoOutOfBounds(self): + """Verify that pressing the up arrow many times won't go out of bounds.""" + # Enter one command. + test_str = b"help version" + input_stream = BytesToByteList(test_str) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + # Then press the up arrow key twice. + input_stream.extend(2 * Keys.UP_ARROW) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # Verify that the history buffer is correct. + exp_history_buf = [test_str] + CheckHistoryBuffer(self, exp_history_buf) + + # We expect that the console output should only contain our entered command, + # a new prompt, and then our command aggain. + exp_console_out = test_str + b"\r\n" + self.console.prompt + # Pressing up should reprint the command we entered. + exp_console_out += test_str + + # Verify. + CheckConsoleOutput(self, exp_console_out) + + def test_CycleDownThruCommandHistory(self): + """Verify that we can select entries by hitting the down arrow.""" + # Enter at least 4 commands. + test_commands = [b"version", b"accelrange 0", b"battery", b"gettime"] + input_stream = [] + for command in test_commands: + input_stream.extend(BytesToByteList(command)) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Now, hit the UP arrow key twice to print the previous two entries. + for i in range(2): + input_stream.extend(Keys.UP_ARROW) + + # Now, hit the DOWN arrow key twice to print the newer entries. + input_stream.extend(2 * Keys.DOWN_ARROW) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # The expected output should be commands that we entered, followed by + # prompts, then followed by our last two commands in reverse. Then, we + # should see the last entry in the list, followed by the saved partial cmd + # of a blank line. + exp_console_out = b"" + for i in range(len(test_commands)): + exp_console_out += test_commands[i] + b"\r\n" + self.console.prompt + + # When we press up, the line should be cleared and print the previous buffer + # entry. + for i in range(len(test_commands) - 1, 1, -1): + exp_console_out += test_commands[i] + # Backspace to the beginning. + for i in range(len(test_commands[i])): + exp_console_out += BACKSPACE_STRING + + # When we press down, it should have cleared the last command (which we + # covered with the previous for loop), and then prints the next command. + exp_console_out += test_commands[3] + for i in range(len(test_commands[3])): + exp_console_out += BACKSPACE_STRING + + # Verify console output. + CheckConsoleOutput(self, exp_console_out) + + # Verify input buffer. + exp_input_buffer = b"" # Empty because our partial command was empty. + exp_input_buffer_pos = len(exp_input_buffer) + CheckInputBuffer(self, exp_input_buffer) + CheckInputBufferPosition(self, exp_input_buffer_pos) + + def test_SavingPartialCommandWhenNavigatingHistory(self): + """Verify that partial commands are saved when navigating history.""" + # Enter a command. + test_str = b"accelinfo" + input_stream = BytesToByteList(test_str) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Enter a partial command. + partial_cmd = b"ver" + input_stream.extend(BytesToByteList(partial_cmd)) + + # Hit the UP arrow key. + input_stream.extend(Keys.UP_ARROW) + # Then, the DOWN arrow key. + input_stream.extend(Keys.DOWN_ARROW) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # The expected output should be the command we entered, a prompt, the + # partial command, clearing of the partial command, the command entered, + # clearing of the command entered, and then the partial command. + exp_console_out = test_str + b"\r\n" + self.console.prompt + exp_console_out += partial_cmd + for _ in range(len(partial_cmd)): + exp_console_out += BACKSPACE_STRING + exp_console_out += test_str + for _ in range(len(test_str)): + exp_console_out += BACKSPACE_STRING + exp_console_out += partial_cmd + + # Verify console output. + CheckConsoleOutput(self, exp_console_out) + + # Verify input buffer. + exp_input_buffer = partial_cmd + exp_input_buffer_pos = len(exp_input_buffer) + CheckInputBuffer(self, exp_input_buffer) + CheckInputBufferPosition(self, exp_input_buffer_pos) + + def test_DownArrowOnEmptyHistory(self): + """Ensure nothing happens if the history is empty.""" + # Then press the up down arrow twice. + input_stream = 2 * Keys.DOWN_ARROW + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # We expect nothing to have happened. + exp_console_out = b"" + exp_input_buffer = b"" + exp_input_buffer_pos = 0 + exp_history_buf = [] + + # Verify. + CheckConsoleOutput(self, exp_console_out) + CheckInputBufferPosition(self, exp_input_buffer_pos) + CheckInputBuffer(self, exp_input_buffer) + CheckHistoryBuffer(self, exp_history_buf) + + def test_DeleteCharsUsingDELKey(self): + """Verify that we can delete characters using the DEL key.""" + test_str = b"version" + input_stream = BytesToByteList(test_str) + + # Hit the left arrow key 2 times. + input_stream.extend(2 * Keys.LEFT_ARROW) + + # Press the DEL key. + input_stream.extend(Keys.DEL) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # The expected output should be the command we entered, 2 individual cursor + # moves to the left, and then removing a char and shifting everything to the + # left one column. + exp_console_out = test_str + exp_console_out += 2 * OutputStream.MoveCursorLeft(1) + + # Remove the char by shifting everything to the left one, slicing out the + # remove char. + exp_console_out += test_str[-1:] + b" " + + # Reset the cursor by moving back 2 columns because of the 'n' and space. + exp_console_out += OutputStream.MoveCursorLeft(2) + + # Verify console output. + CheckConsoleOutput(self, exp_console_out) + + # Verify input buffer. The input buffer should have the char sliced out and + # be positioned where the char was removed. + exp_input_buffer = test_str[:-2] + test_str[-1:] + exp_input_buffer_pos = len(exp_input_buffer) - 1 + CheckInputBuffer(self, exp_input_buffer) + CheckInputBufferPosition(self, exp_input_buffer_pos) + + def test_RepeatedCommandInHistory(self): + """Verify that we don't store 2 consecutive identical commands in history""" + # Enter a few commands. + test_commands = [b"version", b"accelrange 0", b"battery", b"gettime"] + # Repeat the last command. + test_commands.append(test_commands[len(test_commands) - 1]) + + input_stream = [] + for command in test_commands: + input_stream.extend(BytesToByteList(command)) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # Verify that the history buffer is correct. The last command, since + # it was repeated, should not have been added to the history. + exp_history_buf = test_commands[0 : len(test_commands) - 1] + CheckHistoryBuffer(self, exp_history_buf) - Args: - mock_check: A MagicMock object replacing the CheckForEnhancedECImage() - method. - """ - # Set the interrogation mode to always so that we actually interrogate. - self.console.interrogation_mode = b'always' - - # First, assume that the EC interrogations indicate an enhanced EC image. - mock_check.return_value = True - # But our current knowledge of the EC image (which was actually the - # 'previous' EC) was a non-enhanced image. - self.console.enhanced_ec = False - - test_command = b'sysinfo' - input_stream = [] - input_stream.extend(BytesToByteList(test_command)) - - expected_calls = [] - # All keystrokes to the console should be directed straight through to the - # EC until we press the enter key. - for char in test_command: - if six.PY3: - expected_calls.append(mock.call(bytes([char]))) - else: - expected_calls.append(mock.call(char)) - - # Press the enter key. - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - # The enter key should not be sent to the pipe since we should negotiate - # to an enhanced EC image. - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # At this point, we should have negotiated to enhanced. - self.assertTrue(self.console.enhanced_ec, msg=('Did not negotiate to ' - 'enhanced EC image.')) - - # The command would have been dropped however, so verify this... - CheckInputBuffer(self, b'') - CheckInputBufferPosition(self, 0) - # ...and repeat the command. - input_stream = BytesToByteList(test_command) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # Since we're enhanced now, we should have sent the entire command as one - # string with no trailing carriage return - expected_calls.append(mock.call(test_command)) - - # Verify all of the calls. - self.console.cmd_pipe.send.assert_has_calls(expected_calls) - - @mock.patch('ec3po.console.Console.CheckForEnhancedECImage') - def test_TransitionFromEnhancedToNonEnhanced(self, mock_check): - """Verify that we transition correctly to non-enhanced mode. - Args: - mock_check: A MagicMock object replacing the CheckForEnhancedECImage() - method. - """ - # Set the interrogation mode to always so that we actually interrogate. - self.console.interrogation_mode = b'always' - - # First, assume that the EC interrogations indicate an non-enhanced EC - # image. - mock_check.return_value = False - # But our current knowledge of the EC image (which was actually the - # 'previous' EC) was an enhanced image. - self.console.enhanced_ec = True - - test_command = b'sysinfo' - input_stream = [] - input_stream.extend(BytesToByteList(test_command)) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # But, we will negotiate to non-enhanced however, dropping this command. - # Verify this. - self.assertFalse(self.console.enhanced_ec, msg=('Did not negotiate to' - 'non-enhanced EC image.')) - CheckInputBuffer(self, b'') - CheckInputBufferPosition(self, 0) - - # The carriage return should have passed through though. - expected_calls = [] - expected_calls.append(mock.call( - six.int2byte(console.ControlKey.CARRIAGE_RETURN))) - - # Since the command was dropped, repeat the command. - input_stream = BytesToByteList(test_command) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # Since we're not enhanced now, we should have sent each character in the - # entire command separately and a carriage return. - for char in test_command: - if six.PY3: - expected_calls.append(mock.call(bytes([char]))) - else: - expected_calls.append(mock.call(char)) - expected_calls.append(mock.call( - six.int2byte(console.ControlKey.CARRIAGE_RETURN))) - - # Verify all of the calls. - self.console.cmd_pipe.send.assert_has_calls(expected_calls) - - def test_EnhancedCheckIfTimedOut(self): - """Verify that the check returns false if it times out.""" - # Make the debug pipe "time out". - self.console.dbg_pipe.poll.return_value = False - self.assertFalse(self.console.CheckForEnhancedECImage()) - - def test_EnhancedCheckIfACKReceived(self): - """Verify that the check returns true if the ACK is received.""" - # Make the debug pipe return EC_ACK. - self.console.dbg_pipe.poll.return_value = True - self.console.dbg_pipe.recv.return_value = interpreter.EC_ACK - self.assertTrue(self.console.CheckForEnhancedECImage()) - - def test_EnhancedCheckIfWrong(self): - """Verify that the check returns false if byte received is wrong.""" - # Make the debug pipe return the wrong byte. - self.console.dbg_pipe.poll.return_value = True - self.console.dbg_pipe.recv.return_value = b'\xff' - self.assertFalse(self.console.CheckForEnhancedECImage()) - - def test_EnhancedCheckUsingBuffer(self): - """Verify that given reboot output, enhanced EC images are detected.""" - enhanced_output_stream = b""" +class TestConsoleCompatibility(unittest.TestCase): + """Verify that console can speak to enhanced and non-enhanced EC images.""" + + def setUp(self): + """Setup the test harness.""" + # Setup logging with a timestamp, the module, and the log level. + logging.basicConfig( + level=logging.DEBUG, + format=("%(asctime)s - %(module)s - %(levelname)s - %(message)s"), + ) + # Create a temp file and set both the controller and peripheral PTYs to the + # file to create a loopback. + self.tempfile = tempfile.TemporaryFile() + + # Mock out the pipes. + mock_pipe_end_0, mock_pipe_end_1 = mock.MagicMock(), mock.MagicMock() + self.console = console.Console( + self.tempfile.fileno(), + self.tempfile, + tempfile.TemporaryFile(), + mock_pipe_end_0, + mock_pipe_end_1, + "EC", + ) + + @mock.patch("ec3po.console.Console.CheckForEnhancedECImage") + def test_ActAsPassThruInNonEnhancedMode(self, mock_check): + """Verify we simply pass everything thru to non-enhanced ECs. + + Args: + mock_check: A MagicMock object replacing the CheckForEnhancedECImage() + method. + """ + # Set the interrogation mode to always so that we actually interrogate. + self.console.interrogation_mode = b"always" + + # Assume EC interrogations indicate that the image is non-enhanced. + mock_check.return_value = False + + # Press enter, followed by the command, and another enter. + input_stream = [] + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + test_command = b"version" + input_stream.extend(BytesToByteList(test_command)) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # Expected calls to send down the pipe would be each character of the test + # command. + expected_calls = [] + expected_calls.append( + mock.call(six.int2byte(console.ControlKey.CARRIAGE_RETURN)) + ) + for char in test_command: + if six.PY3: + expected_calls.append(mock.call(bytes([char]))) + else: + expected_calls.append(mock.call(char)) + expected_calls.append( + mock.call(six.int2byte(console.ControlKey.CARRIAGE_RETURN)) + ) + + # Verify that the calls happened. + self.console.cmd_pipe.send.assert_has_calls(expected_calls) + + # Since we're acting as a pass-thru, the input buffer should be empty and + # input_buffer_pos is 0. + CheckInputBuffer(self, b"") + CheckInputBufferPosition(self, 0) + + @mock.patch("ec3po.console.Console.CheckForEnhancedECImage") + def test_TransitionFromNonEnhancedToEnhanced(self, mock_check): + """Verify that we transition correctly to enhanced mode. + + Args: + mock_check: A MagicMock object replacing the CheckForEnhancedECImage() + method. + """ + # Set the interrogation mode to always so that we actually interrogate. + self.console.interrogation_mode = b"always" + + # First, assume that the EC interrogations indicate an enhanced EC image. + mock_check.return_value = True + # But our current knowledge of the EC image (which was actually the + # 'previous' EC) was a non-enhanced image. + self.console.enhanced_ec = False + + test_command = b"sysinfo" + input_stream = [] + input_stream.extend(BytesToByteList(test_command)) + + expected_calls = [] + # All keystrokes to the console should be directed straight through to the + # EC until we press the enter key. + for char in test_command: + if six.PY3: + expected_calls.append(mock.call(bytes([char]))) + else: + expected_calls.append(mock.call(char)) + + # Press the enter key. + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + # The enter key should not be sent to the pipe since we should negotiate + # to an enhanced EC image. + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # At this point, we should have negotiated to enhanced. + self.assertTrue( + self.console.enhanced_ec, + msg=("Did not negotiate to enhanced EC image."), + ) + + # The command would have been dropped however, so verify this... + CheckInputBuffer(self, b"") + CheckInputBufferPosition(self, 0) + # ...and repeat the command. + input_stream = BytesToByteList(test_command) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # Since we're enhanced now, we should have sent the entire command as one + # string with no trailing carriage return + expected_calls.append(mock.call(test_command)) + + # Verify all of the calls. + self.console.cmd_pipe.send.assert_has_calls(expected_calls) + + @mock.patch("ec3po.console.Console.CheckForEnhancedECImage") + def test_TransitionFromEnhancedToNonEnhanced(self, mock_check): + """Verify that we transition correctly to non-enhanced mode. + + Args: + mock_check: A MagicMock object replacing the CheckForEnhancedECImage() + method. + """ + # Set the interrogation mode to always so that we actually interrogate. + self.console.interrogation_mode = b"always" + + # First, assume that the EC interrogations indicate an non-enhanced EC + # image. + mock_check.return_value = False + # But our current knowledge of the EC image (which was actually the + # 'previous' EC) was an enhanced image. + self.console.enhanced_ec = True + + test_command = b"sysinfo" + input_stream = [] + input_stream.extend(BytesToByteList(test_command)) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # But, we will negotiate to non-enhanced however, dropping this command. + # Verify this. + self.assertFalse( + self.console.enhanced_ec, + msg=("Did not negotiate to non-enhanced EC image."), + ) + CheckInputBuffer(self, b"") + CheckInputBufferPosition(self, 0) + + # The carriage return should have passed through though. + expected_calls = [] + expected_calls.append( + mock.call(six.int2byte(console.ControlKey.CARRIAGE_RETURN)) + ) + + # Since the command was dropped, repeat the command. + input_stream = BytesToByteList(test_command) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # Since we're not enhanced now, we should have sent each character in the + # entire command separately and a carriage return. + for char in test_command: + if six.PY3: + expected_calls.append(mock.call(bytes([char]))) + else: + expected_calls.append(mock.call(char)) + expected_calls.append( + mock.call(six.int2byte(console.ControlKey.CARRIAGE_RETURN)) + ) + + # Verify all of the calls. + self.console.cmd_pipe.send.assert_has_calls(expected_calls) + + def test_EnhancedCheckIfTimedOut(self): + """Verify that the check returns false if it times out.""" + # Make the debug pipe "time out". + self.console.dbg_pipe.poll.return_value = False + self.assertFalse(self.console.CheckForEnhancedECImage()) + + def test_EnhancedCheckIfACKReceived(self): + """Verify that the check returns true if the ACK is received.""" + # Make the debug pipe return EC_ACK. + self.console.dbg_pipe.poll.return_value = True + self.console.dbg_pipe.recv.return_value = interpreter.EC_ACK + self.assertTrue(self.console.CheckForEnhancedECImage()) + + def test_EnhancedCheckIfWrong(self): + """Verify that the check returns false if byte received is wrong.""" + # Make the debug pipe return the wrong byte. + self.console.dbg_pipe.poll.return_value = True + self.console.dbg_pipe.recv.return_value = b"\xff" + self.assertFalse(self.console.CheckForEnhancedECImage()) + + def test_EnhancedCheckUsingBuffer(self): + """Verify that given reboot output, enhanced EC images are detected.""" + enhanced_output_stream = b""" --- UART initialized after reboot --- [Reset cause: reset-pin soft] [Image: RO, jerry_v1.1.4363-2af8572-dirty 2016-02-23 13:26:20 aaboagye@lithium.mtv.corp.google.com] @@ -1295,19 +1350,19 @@ Enhanced Console is enabled (v1.0.0); type HELP for help. [0.224060 hash done 41dac382e3a6e3d2ea5b4d789c1bc46525cae7cc5ff6758f0de8d8369b506f57] [0.375150 POWER_GOOD seen] """ - for line in enhanced_output_stream.split(b'\n'): - self.console.CheckBufferForEnhancedImage(line) + for line in enhanced_output_stream.split(b"\n"): + self.console.CheckBufferForEnhancedImage(line) - # Since the enhanced console string was present in the output, the console - # should have caught it. - self.assertTrue(self.console.enhanced_ec) + # Since the enhanced console string was present in the output, the console + # should have caught it. + self.assertTrue(self.console.enhanced_ec) - # Also should check that the command was sent to the interpreter. - self.console.cmd_pipe.send.assert_called_once_with(b'enhanced True') + # Also should check that the command was sent to the interpreter. + self.console.cmd_pipe.send.assert_called_once_with(b"enhanced True") - # Now test the non-enhanced EC image. - self.console.cmd_pipe.reset_mock() - non_enhanced_output_stream = b""" + # Now test the non-enhanced EC image. + self.console.cmd_pipe.reset_mock() + non_enhanced_output_stream = b""" --- UART initialized after reboot --- [Reset cause: reset-pin soft] [Image: RO, jerry_v1.1.4363-2af8572-dirty 2016-02-23 13:03:15 aaboagye@lithium.mtv.corp.google.com] @@ -1331,239 +1386,254 @@ Console is enabled; type HELP for help. [0.010285 power on 2] [0.010385 power state 5 = S5->S3, in 0x0000] """ - for line in non_enhanced_output_stream.split(b'\n'): - self.console.CheckBufferForEnhancedImage(line) + for line in non_enhanced_output_stream.split(b"\n"): + self.console.CheckBufferForEnhancedImage(line) - # Since the default console string is present in the output, it should be - # determined to be non enhanced now. - self.assertFalse(self.console.enhanced_ec) + # Since the default console string is present in the output, it should be + # determined to be non enhanced now. + self.assertFalse(self.console.enhanced_ec) - # Check that command was also sent to the interpreter. - self.console.cmd_pipe.send.assert_called_once_with(b'enhanced False') + # Check that command was also sent to the interpreter. + self.console.cmd_pipe.send.assert_called_once_with(b"enhanced False") class TestOOBMConsoleCommands(unittest.TestCase): - """Verify that OOBM console commands work correctly.""" - def setUp(self): - """Setup the test harness.""" - # Setup logging with a timestamp, the module, and the log level. - logging.basicConfig(level=logging.DEBUG, - format=('%(asctime)s - %(module)s -' - ' %(levelname)s - %(message)s')) - # Create a temp file and set both the controller and peripheral PTYs to the - # file to create a loopback. - self.tempfile = tempfile.TemporaryFile() - - # Mock out the pipes. - mock_pipe_end_0, mock_pipe_end_1 = mock.MagicMock(), mock.MagicMock() - self.console = console.Console(self.tempfile.fileno(), self.tempfile, - tempfile.TemporaryFile(), - mock_pipe_end_0, mock_pipe_end_1, "EC") - self.console.oobm_queue = mock.MagicMock() - - @mock.patch('ec3po.console.Console.CheckForEnhancedECImage') - def test_InterrogateCommand(self, mock_check): - """Verify that 'interrogate' command works as expected. - - Args: - mock_check: A MagicMock object replacing the CheckForEnhancedECIMage() - method. - """ - input_stream = [] - expected_calls = [] - mock_check.side_effect = [False] - - # 'interrogate never' should disable the interrogation from happening at - # all. - cmd = b'interrogate never' - # Enter the OOBM prompt. - input_stream.extend(BytesToByteList(b'%')) - # Type the command - input_stream.extend(BytesToByteList(cmd)) - # Press enter. - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - input_stream = [] - - # The OOBM queue should have been called with the command being put. - expected_calls.append(mock.call.put(cmd)) - self.console.oobm_queue.assert_has_calls(expected_calls) - - # Process the OOBM queue. - self.console.oobm_queue.get.side_effect = [cmd] - self.console.ProcessOOBMQueue() - - # Type out a few commands. - input_stream.extend(BytesToByteList(b'version')) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - input_stream.extend(BytesToByteList(b'flashinfo')) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - input_stream.extend(BytesToByteList(b'sysinfo')) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # The Check function should NOT have been called at all. - mock_check.assert_not_called() - - # The EC image should be assumed to be not enhanced. - self.assertFalse(self.console.enhanced_ec, 'The image should be assumed to' - ' be NOT enhanced.') - - # Reset the mocks. - mock_check.reset_mock() - self.console.oobm_queue.reset_mock() - - # 'interrogate auto' should not interrogate at all. It should only be - # scanning the output stream for the 'console is enabled' strings. - cmd = b'interrogate auto' - # Enter the OOBM prompt. - input_stream.extend(BytesToByteList(b'%')) - # Type the command - input_stream.extend(BytesToByteList(cmd)) - # Press enter. - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - input_stream = [] - expected_calls = [] - - # The OOBM queue should have been called with the command being put. - expected_calls.append(mock.call.put(cmd)) - self.console.oobm_queue.assert_has_calls(expected_calls) - - # Process the OOBM queue. - self.console.oobm_queue.get.side_effect = [cmd] - self.console.ProcessOOBMQueue() - - # Type out a few commands. - input_stream.extend(BytesToByteList(b'version')) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - input_stream.extend(BytesToByteList(b'flashinfo')) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - input_stream.extend(BytesToByteList(b'sysinfo')) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # The Check function should NOT have been called at all. - mock_check.assert_not_called() - - # The EC image should be assumed to be not enhanced. - self.assertFalse(self.console.enhanced_ec, 'The image should be assumed to' - ' be NOT enhanced.') - - # Reset the mocks. - mock_check.reset_mock() - self.console.oobm_queue.reset_mock() - - # 'interrogate always' should, like its name implies, interrogate always - # after each press of the enter key. This was the former way of doing - # interrogation. - cmd = b'interrogate always' - # Enter the OOBM prompt. - input_stream.extend(BytesToByteList(b'%')) - # Type the command - input_stream.extend(BytesToByteList(cmd)) - # Press enter. - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - input_stream = [] - expected_calls = [] - - # The OOBM queue should have been called with the command being put. - expected_calls.append(mock.call.put(cmd)) - self.console.oobm_queue.assert_has_calls(expected_calls) - - # Process the OOBM queue. - self.console.oobm_queue.get.side_effect = [cmd] - self.console.ProcessOOBMQueue() - - # The Check method should be called 3 times here. - mock_check.side_effect = [False, False, False] - - # Type out a few commands. - input_stream.extend(BytesToByteList(b'help list')) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - input_stream.extend(BytesToByteList(b'taskinfo')) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - input_stream.extend(BytesToByteList(b'hibdelay')) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # The Check method should have been called 3 times here. - expected_calls = [mock.call(), mock.call(), mock.call()] - mock_check.assert_has_calls(expected_calls) - - # The EC image should be assumed to be not enhanced. - self.assertFalse(self.console.enhanced_ec, 'The image should be assumed to' - ' be NOT enhanced.') - - # Now, let's try to assume that the image is enhanced while still disabling - # interrogation. - mock_check.reset_mock() - self.console.oobm_queue.reset_mock() - input_stream = [] - cmd = b'interrogate never enhanced' - # Enter the OOBM prompt. - input_stream.extend(BytesToByteList(b'%')) - # Type the command - input_stream.extend(BytesToByteList(cmd)) - # Press enter. - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - input_stream = [] - expected_calls = [] - - # The OOBM queue should have been called with the command being put. - expected_calls.append(mock.call.put(cmd)) - self.console.oobm_queue.assert_has_calls(expected_calls) - - # Process the OOBM queue. - self.console.oobm_queue.get.side_effect = [cmd] - self.console.ProcessOOBMQueue() - - # Type out a few commands. - input_stream.extend(BytesToByteList(b'chgstate')) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - input_stream.extend(BytesToByteList(b'hash')) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - input_stream.extend(BytesToByteList(b'sysjump rw')) - input_stream.append(console.ControlKey.CARRIAGE_RETURN) - - # Send the sequence out. - for byte in input_stream: - self.console.HandleChar(byte) - - # The check method should have never been called. - mock_check.assert_not_called() - - # The EC image should be assumed to be enhanced. - self.assertTrue(self.console.enhanced_ec, 'The image should be' - ' assumed to be enhanced.') - - -if __name__ == '__main__': - unittest.main() + """Verify that OOBM console commands work correctly.""" + + def setUp(self): + """Setup the test harness.""" + # Setup logging with a timestamp, the module, and the log level. + logging.basicConfig( + level=logging.DEBUG, + format=("%(asctime)s - %(module)s - %(levelname)s - %(message)s"), + ) + # Create a temp file and set both the controller and peripheral PTYs to the + # file to create a loopback. + self.tempfile = tempfile.TemporaryFile() + + # Mock out the pipes. + mock_pipe_end_0, mock_pipe_end_1 = mock.MagicMock(), mock.MagicMock() + self.console = console.Console( + self.tempfile.fileno(), + self.tempfile, + tempfile.TemporaryFile(), + mock_pipe_end_0, + mock_pipe_end_1, + "EC", + ) + self.console.oobm_queue = mock.MagicMock() + + @mock.patch("ec3po.console.Console.CheckForEnhancedECImage") + def test_InterrogateCommand(self, mock_check): + """Verify that 'interrogate' command works as expected. + + Args: + mock_check: A MagicMock object replacing the CheckForEnhancedECIMage() + method. + """ + input_stream = [] + expected_calls = [] + mock_check.side_effect = [False] + + # 'interrogate never' should disable the interrogation from happening at + # all. + cmd = b"interrogate never" + # Enter the OOBM prompt. + input_stream.extend(BytesToByteList(b"%")) + # Type the command + input_stream.extend(BytesToByteList(cmd)) + # Press enter. + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + input_stream = [] + + # The OOBM queue should have been called with the command being put. + expected_calls.append(mock.call.put(cmd)) + self.console.oobm_queue.assert_has_calls(expected_calls) + + # Process the OOBM queue. + self.console.oobm_queue.get.side_effect = [cmd] + self.console.ProcessOOBMQueue() + + # Type out a few commands. + input_stream.extend(BytesToByteList(b"version")) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + input_stream.extend(BytesToByteList(b"flashinfo")) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + input_stream.extend(BytesToByteList(b"sysinfo")) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # The Check function should NOT have been called at all. + mock_check.assert_not_called() + + # The EC image should be assumed to be not enhanced. + self.assertFalse( + self.console.enhanced_ec, + "The image should be assumed to be NOT enhanced.", + ) + + # Reset the mocks. + mock_check.reset_mock() + self.console.oobm_queue.reset_mock() + + # 'interrogate auto' should not interrogate at all. It should only be + # scanning the output stream for the 'console is enabled' strings. + cmd = b"interrogate auto" + # Enter the OOBM prompt. + input_stream.extend(BytesToByteList(b"%")) + # Type the command + input_stream.extend(BytesToByteList(cmd)) + # Press enter. + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + input_stream = [] + expected_calls = [] + + # The OOBM queue should have been called with the command being put. + expected_calls.append(mock.call.put(cmd)) + self.console.oobm_queue.assert_has_calls(expected_calls) + + # Process the OOBM queue. + self.console.oobm_queue.get.side_effect = [cmd] + self.console.ProcessOOBMQueue() + + # Type out a few commands. + input_stream.extend(BytesToByteList(b"version")) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + input_stream.extend(BytesToByteList(b"flashinfo")) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + input_stream.extend(BytesToByteList(b"sysinfo")) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # The Check function should NOT have been called at all. + mock_check.assert_not_called() + + # The EC image should be assumed to be not enhanced. + self.assertFalse( + self.console.enhanced_ec, + "The image should be assumed to be NOT enhanced.", + ) + + # Reset the mocks. + mock_check.reset_mock() + self.console.oobm_queue.reset_mock() + + # 'interrogate always' should, like its name implies, interrogate always + # after each press of the enter key. This was the former way of doing + # interrogation. + cmd = b"interrogate always" + # Enter the OOBM prompt. + input_stream.extend(BytesToByteList(b"%")) + # Type the command + input_stream.extend(BytesToByteList(cmd)) + # Press enter. + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + input_stream = [] + expected_calls = [] + + # The OOBM queue should have been called with the command being put. + expected_calls.append(mock.call.put(cmd)) + self.console.oobm_queue.assert_has_calls(expected_calls) + + # Process the OOBM queue. + self.console.oobm_queue.get.side_effect = [cmd] + self.console.ProcessOOBMQueue() + + # The Check method should be called 3 times here. + mock_check.side_effect = [False, False, False] + + # Type out a few commands. + input_stream.extend(BytesToByteList(b"help list")) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + input_stream.extend(BytesToByteList(b"taskinfo")) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + input_stream.extend(BytesToByteList(b"hibdelay")) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # The Check method should have been called 3 times here. + expected_calls = [mock.call(), mock.call(), mock.call()] + mock_check.assert_has_calls(expected_calls) + + # The EC image should be assumed to be not enhanced. + self.assertFalse( + self.console.enhanced_ec, + "The image should be assumed to be NOT enhanced.", + ) + + # Now, let's try to assume that the image is enhanced while still disabling + # interrogation. + mock_check.reset_mock() + self.console.oobm_queue.reset_mock() + input_stream = [] + cmd = b"interrogate never enhanced" + # Enter the OOBM prompt. + input_stream.extend(BytesToByteList(b"%")) + # Type the command + input_stream.extend(BytesToByteList(cmd)) + # Press enter. + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + input_stream = [] + expected_calls = [] + + # The OOBM queue should have been called with the command being put. + expected_calls.append(mock.call.put(cmd)) + self.console.oobm_queue.assert_has_calls(expected_calls) + + # Process the OOBM queue. + self.console.oobm_queue.get.side_effect = [cmd] + self.console.ProcessOOBMQueue() + + # Type out a few commands. + input_stream.extend(BytesToByteList(b"chgstate")) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + input_stream.extend(BytesToByteList(b"hash")) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + input_stream.extend(BytesToByteList(b"sysjump rw")) + input_stream.append(console.ControlKey.CARRIAGE_RETURN) + + # Send the sequence out. + for byte in input_stream: + self.console.HandleChar(byte) + + # The check method should have never been called. + mock_check.assert_not_called() + + # The EC image should be assumed to be enhanced. + self.assertTrue( + self.console.enhanced_ec, + "The image should be assumed to be enhanced.", + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/util/ec3po/interpreter.py b/util/ec3po/interpreter.py index 4e151083bd..8d21af247a 100644 --- a/util/ec3po/interpreter.py +++ b/util/ec3po/interpreter.py @@ -1,4 +1,4 @@ -# Copyright 2015 The Chromium OS Authors. All rights reserved. +# Copyright 2015 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -25,443 +25,457 @@ import traceback import six - COMMAND_RETRIES = 3 # Number of attempts to retry a command. EC_MAX_READ = 1024 # Max bytes to read at a time from the EC. -EC_SYN = b'\xec' # Byte indicating EC interrogation. -EC_ACK = b'\xc0' # Byte representing correct EC response to interrogation. +EC_SYN = b"\xec" # Byte indicating EC interrogation. +EC_ACK = b"\xc0" # Byte representing correct EC response to interrogation. class LoggerAdapter(logging.LoggerAdapter): - """Class which provides a small adapter for the logger.""" + """Class which provides a small adapter for the logger.""" - def process(self, msg, kwargs): - """Prepends the served PTY to the beginning of the log message.""" - return '%s - %s' % (self.extra['pty'], msg), kwargs + def process(self, msg, kwargs): + """Prepends the served PTY to the beginning of the log message.""" + return "%s - %s" % (self.extra["pty"], msg), kwargs class Interpreter(object): - """Class which provides the interpretation layer between the EC and user. - - This class essentially performs all of the intepretation for the EC and the - user. It handles all of the automatic command retrying as well as the - formation of commands for EC images which support that. - - Attributes: - logger: A logger for this module. - ec_uart_pty: An opened file object to the raw EC UART PTY. - ec_uart_pty_name: A string containing the name of the raw EC UART PTY. - cmd_pipe: A socket.socket or multiprocessing.Connection object which - represents the Interpreter side of the command pipe. This must be a - bidirectional pipe. Commands and responses will utilize this pipe. - dbg_pipe: A socket.socket or multiprocessing.Connection object which - represents the Interpreter side of the debug pipe. This must be a - unidirectional pipe with write capabilities. EC debug output will utilize - this pipe. - cmd_retries: An integer representing the number of attempts the console - should retry commands if it receives an error. - log_level: An integer representing the numeric value of the log level. - inputs: A list of objects that the intpreter selects for reading. - Initially, these are the EC UART and the command pipe. - outputs: A list of objects that the interpreter selects for writing. - ec_cmd_queue: A FIFO queue used for sending commands down to the EC UART. - last_cmd: A string that represents the last command sent to the EC. If an - error is encountered, the interpreter will attempt to retry this command - up to COMMAND_RETRIES. - enhanced_ec: A boolean indicating if the EC image that we are currently - communicating with is enhanced or not. Enhanced EC images will support - packed commands and host commands over the UART. This defaults to False - and is changed depending on the result of an interrogation. - interrogating: A boolean indicating if we are in the middle of interrogating - the EC. - connected: A boolean indicating if the interpreter is actually connected to - the UART and listening. - """ - def __init__(self, ec_uart_pty, cmd_pipe, dbg_pipe, log_level=logging.INFO, - name=None): - """Intializes an Interpreter object with the provided args. + """Class which provides the interpretation layer between the EC and user. - Args: - ec_uart_pty: A string representing the EC UART to connect to. + This class essentially performs all of the intepretation for the EC and the + user. It handles all of the automatic command retrying as well as the + formation of commands for EC images which support that. + + Attributes: + logger: A logger for this module. + ec_uart_pty: An opened file object to the raw EC UART PTY. + ec_uart_pty_name: A string containing the name of the raw EC UART PTY. cmd_pipe: A socket.socket or multiprocessing.Connection object which represents the Interpreter side of the command pipe. This must be a bidirectional pipe. Commands and responses will utilize this pipe. dbg_pipe: A socket.socket or multiprocessing.Connection object which represents the Interpreter side of the debug pipe. This must be a - unidirectional pipe with write capabilities. EC debug output will - utilize this pipe. + unidirectional pipe with write capabilities. EC debug output will utilize + this pipe. cmd_retries: An integer representing the number of attempts the console should retry commands if it receives an error. - log_level: An optional integer representing the numeric value of the log - level. By default, the log level will be logging.INFO (20). - name: the console source name - """ - # Create a unique logger based on the interpreter name - interpreter_prefix = ('%s - ' % name) if name else '' - logger = logging.getLogger('%sEC3PO.Interpreter' % interpreter_prefix) - self.logger = LoggerAdapter(logger, {'pty': ec_uart_pty}) - # TODO(https://crbug.com/1162189): revist the 2 TODOs below - # TODO(https://bugs.python.org/issue27805, python3.7+): revert to ab+ - # TODO(https://bugs.python.org/issue20074): removing buffering=0 if/when - # that gets fixed, or keep two pty: one for reading and one for writing - self.ec_uart_pty = open(ec_uart_pty, 'r+b', buffering=0) - self.ec_uart_pty_name = ec_uart_pty - self.cmd_pipe = cmd_pipe - self.dbg_pipe = dbg_pipe - self.cmd_retries = COMMAND_RETRIES - self.log_level = log_level - self.inputs = [self.ec_uart_pty, self.cmd_pipe] - self.outputs = [] - self.ec_cmd_queue = six.moves.queue.Queue() - self.last_cmd = b'' - self.enhanced_ec = False - self.interrogating = False - self.connected = True - - def __str__(self): - """Show internal state of the Interpreter object. - - Returns: - A string that shows the values of the attributes. - """ - string = [] - string.append('%r' % self) - string.append('ec_uart_pty: %s' % self.ec_uart_pty) - string.append('cmd_pipe: %r' % self.cmd_pipe) - string.append('dbg_pipe: %r' % self.dbg_pipe) - string.append('cmd_retries: %d' % self.cmd_retries) - string.append('log_level: %d' % self.log_level) - string.append('inputs: %r' % self.inputs) - string.append('outputs: %r' % self.outputs) - string.append('ec_cmd_queue: %r' % self.ec_cmd_queue) - string.append('last_cmd: \'%s\'' % self.last_cmd) - string.append('enhanced_ec: %r' % self.enhanced_ec) - string.append('interrogating: %r' % self.interrogating) - return '\n'.join(string) - - def EnqueueCmd(self, command): - """Enqueue a command to be sent to the EC UART. - - Args: - command: A string which contains the command to be sent. + log_level: An integer representing the numeric value of the log level. + inputs: A list of objects that the intpreter selects for reading. + Initially, these are the EC UART and the command pipe. + outputs: A list of objects that the interpreter selects for writing. + ec_cmd_queue: A FIFO queue used for sending commands down to the EC UART. + last_cmd: A string that represents the last command sent to the EC. If an + error is encountered, the interpreter will attempt to retry this command + up to COMMAND_RETRIES. + enhanced_ec: A boolean indicating if the EC image that we are currently + communicating with is enhanced or not. Enhanced EC images will support + packed commands and host commands over the UART. This defaults to False + and is changed depending on the result of an interrogation. + interrogating: A boolean indicating if we are in the middle of interrogating + the EC. + connected: A boolean indicating if the interpreter is actually connected to + the UART and listening. """ - self.ec_cmd_queue.put(command) - self.logger.log(1, 'Commands now in queue: %d', self.ec_cmd_queue.qsize()) - # Add the EC UART as an output to be serviced. - if self.connected and self.ec_uart_pty not in self.outputs: - self.outputs.append(self.ec_uart_pty) - - def PackCommand(self, raw_cmd): - r"""Packs a command for use with error checking. - - For error checking, we pack console commands in a particular format. The - format is as follows: - - &&[x][x][x][x]&{cmd}\n\n - ^ ^ ^^ ^^ ^ ^-- 2 newlines. - | | || || |-- the raw console command. - | | || ||-- 1 ampersand. - | | ||____|--- 2 hex digits representing the CRC8 of cmd. - | |____|-- 2 hex digits reprsenting the length of cmd. - |-- 2 ampersands - - Args: - raw_cmd: A pre-packed string which contains the raw command. - - Returns: - A string which contains the packed command. - """ - # Don't pack a single carriage return. - if raw_cmd != b'\r': - # The command format is as follows. - # &&[x][x][x][x]&{cmd}\n\n - packed_cmd = [] - packed_cmd.append(b'&&') - # The first pair of hex digits are the length of the command. - packed_cmd.append(b'%02x' % len(raw_cmd)) - # Then the CRC8 of cmd. - packed_cmd.append(b'%02x' % Crc8(raw_cmd)) - packed_cmd.append(b'&') - # Now, the raw command followed by 2 newlines. - packed_cmd.append(raw_cmd) - packed_cmd.append(b'\n\n') - return b''.join(packed_cmd) - else: - return raw_cmd - - def ProcessCommand(self, command): - """Captures the input determines what actions to take. - - Args: - command: A string representing the command sent by the user. - """ - if command == b'disconnect': - if self.connected: - self.logger.debug('UART disconnect request.') - # Drop all pending commands if any. - while not self.ec_cmd_queue.empty(): - c = self.ec_cmd_queue.get() - self.logger.debug('dropped: \'%s\'', c) - if self.enhanced_ec: - # Reset retry state. - self.cmd_retries = COMMAND_RETRIES - self.last_cmd = b'' - # Get the UART that the interpreter is attached to. - fileobj = self.ec_uart_pty - self.logger.debug('fileobj: %r', fileobj) - # Remove the descriptor from the inputs and outputs. - self.inputs.remove(fileobj) - if fileobj in self.outputs: - self.outputs.remove(fileobj) - self.logger.debug('Removed fileobj. Remaining inputs: %r', self.inputs) - # Close the file. - fileobj.close() - # Mark the interpreter as disconnected now. - self.connected = False - self.logger.debug('Disconnected from %s.', self.ec_uart_pty_name) - return - - elif command == b'reconnect': - if not self.connected: - self.logger.debug('UART reconnect request.') - # Reopen the PTY. + def __init__( + self, ec_uart_pty, cmd_pipe, dbg_pipe, log_level=logging.INFO, name=None + ): + """Intializes an Interpreter object with the provided args. + + Args: + ec_uart_pty: A string representing the EC UART to connect to. + cmd_pipe: A socket.socket or multiprocessing.Connection object which + represents the Interpreter side of the command pipe. This must be a + bidirectional pipe. Commands and responses will utilize this pipe. + dbg_pipe: A socket.socket or multiprocessing.Connection object which + represents the Interpreter side of the debug pipe. This must be a + unidirectional pipe with write capabilities. EC debug output will + utilize this pipe. + cmd_retries: An integer representing the number of attempts the console + should retry commands if it receives an error. + log_level: An optional integer representing the numeric value of the log + level. By default, the log level will be logging.INFO (20). + name: the console source name + """ + # Create a unique logger based on the interpreter name + interpreter_prefix = ("%s - " % name) if name else "" + logger = logging.getLogger("%sEC3PO.Interpreter" % interpreter_prefix) + self.logger = LoggerAdapter(logger, {"pty": ec_uart_pty}) + # TODO(https://crbug.com/1162189): revist the 2 TODOs below # TODO(https://bugs.python.org/issue27805, python3.7+): revert to ab+ # TODO(https://bugs.python.org/issue20074): removing buffering=0 if/when # that gets fixed, or keep two pty: one for reading and one for writing - fileobj = open(self.ec_uart_pty_name, 'r+b', buffering=0) - self.logger.debug('fileobj: %r', fileobj) - self.ec_uart_pty = fileobj - # Add the descriptor to the inputs. - self.inputs.append(fileobj) - self.logger.debug('fileobj added. curr inputs: %r', self.inputs) - # Mark the interpreter as connected now. - self.connected = True - self.logger.debug('Connected to %s.', self.ec_uart_pty_name) - return - - elif command.startswith(b'enhanced'): - self.enhanced_ec = command.split(b' ')[1] == b'True' - return - - # Ignore any other commands while in the disconnected state. - self.logger.log(1, 'command: \'%s\'', command) - if not self.connected: - self.logger.debug('Ignoring command because currently disconnected.') - return - - # Remove leading and trailing spaces only if this is an enhanced EC image. - # For non-enhanced EC images, commands will be single characters at a time - # and can be spaces. - if self.enhanced_ec: - command = command.strip(b' ') - - # There's nothing to do if the command is empty. - if len(command) == 0: - return - - # Handle log level change requests. - if command.startswith(b'loglevel'): - self.logger.debug('Log level change request.') - new_log_level = int(command.split(b' ')[1]) - self.logger.logger.setLevel(new_log_level) - self.logger.info('Log level changed to %d.', new_log_level) - return - - # Check for interrogation command. - if command == EC_SYN: - # User is requesting interrogation. Send SYN as is. - self.logger.debug('User requesting interrogation.') - self.interrogating = True - # Assume the EC isn't enhanced until we get a response. - self.enhanced_ec = False - elif self.enhanced_ec: - # Enhanced EC images require the plaintext commands to be packed. - command = self.PackCommand(command) - # TODO(aaboagye): Make a dict of commands and keys and eventually, - # handle partial matching based on unique prefixes. - - self.EnqueueCmd(command) - - def HandleCmdRetries(self): - """Attempts to retry commands if possible.""" - if self.cmd_retries > 0: - # The EC encountered an error. We'll have to retry again. - self.logger.warning('Retrying command...') - self.cmd_retries -= 1 - self.logger.warning('Retries remaining: %d', self.cmd_retries) - # Retry the command and add the EC UART to the writers again. - self.EnqueueCmd(self.last_cmd) - self.outputs.append(self.ec_uart_pty) - else: - # We're out of retries, so just give up. - self.logger.error('Command failed. No retries left.') - # Clear the command in progress. - self.last_cmd = b'' - # Reset the retry count. - self.cmd_retries = COMMAND_RETRIES - - def SendCmdToEC(self): - """Sends a command to the EC.""" - # If we're retrying a command, just try to send it again. - if self.cmd_retries < COMMAND_RETRIES: - cmd = self.last_cmd - else: - # If we're not retrying, we should not be writing to the EC if we have no - # items in our command queue. - assert not self.ec_cmd_queue.empty() - # Get the command to send. - cmd = self.ec_cmd_queue.get() - - # Send the command. - self.ec_uart_pty.write(cmd) - self.ec_uart_pty.flush() - self.logger.log(1, 'Sent command to EC.') - - if self.enhanced_ec and cmd != EC_SYN: - # Now, that we've sent the command, store the current command as the last - # command sent. If we encounter an error string, we will attempt to retry - # this command. - if cmd != self.last_cmd: - self.last_cmd = cmd - # Reset the retry count. + self.ec_uart_pty = open(ec_uart_pty, "r+b", buffering=0) + self.ec_uart_pty_name = ec_uart_pty + self.cmd_pipe = cmd_pipe + self.dbg_pipe = dbg_pipe self.cmd_retries = COMMAND_RETRIES + self.log_level = log_level + self.inputs = [self.ec_uart_pty, self.cmd_pipe] + self.outputs = [] + self.ec_cmd_queue = six.moves.queue.Queue() + self.last_cmd = b"" + self.enhanced_ec = False + self.interrogating = False + self.connected = True - # If no command is pending to be sent, then we can remove the EC UART from - # writers. Might need better checking for command retry logic in here. - if self.ec_cmd_queue.empty(): - # Remove the EC UART from the writers while we wait for a response. - self.logger.debug('Removing EC UART from writers.') - self.outputs.remove(self.ec_uart_pty) - - def HandleECData(self): - """Handle any debug prints from the EC.""" - self.logger.log(1, 'EC has data') - # Read what the EC sent us. - data = os.read(self.ec_uart_pty.fileno(), EC_MAX_READ) - self.logger.log(1, 'got: \'%s\'', binascii.hexlify(data)) - if b'&E' in data and self.enhanced_ec: - # We received an error, so we should retry it if possible. - self.logger.warning('Error string found in data.') - self.HandleCmdRetries() - return - - # If we were interrogating, check the response and update our knowledge - # of the current EC image. - if self.interrogating: - self.enhanced_ec = data == EC_ACK - if self.enhanced_ec: - self.logger.debug('The current EC image seems enhanced.') - else: - self.logger.debug('The current EC image does NOT seem enhanced.') - # Done interrogating. - self.interrogating = False - # For now, just forward everything the EC sends us. - self.logger.log(1, 'Forwarding to user...') - self.dbg_pipe.send(data) - - def HandleUserData(self): - """Handle any incoming commands from the user. - - Raises: - EOFError: Allowed to propagate through from self.cmd_pipe.recv(). - """ - self.logger.log(1, 'Command data available. Begin processing.') - data = self.cmd_pipe.recv() - # Process the command. - self.ProcessCommand(data) + def __str__(self): + """Show internal state of the Interpreter object. + + Returns: + A string that shows the values of the attributes. + """ + string = [] + string.append("%r" % self) + string.append("ec_uart_pty: %s" % self.ec_uart_pty) + string.append("cmd_pipe: %r" % self.cmd_pipe) + string.append("dbg_pipe: %r" % self.dbg_pipe) + string.append("cmd_retries: %d" % self.cmd_retries) + string.append("log_level: %d" % self.log_level) + string.append("inputs: %r" % self.inputs) + string.append("outputs: %r" % self.outputs) + string.append("ec_cmd_queue: %r" % self.ec_cmd_queue) + string.append("last_cmd: '%s'" % self.last_cmd) + string.append("enhanced_ec: %r" % self.enhanced_ec) + string.append("interrogating: %r" % self.interrogating) + return "\n".join(string) + + def EnqueueCmd(self, command): + """Enqueue a command to be sent to the EC UART. + + Args: + command: A string which contains the command to be sent. + """ + self.ec_cmd_queue.put(command) + self.logger.log( + 1, "Commands now in queue: %d", self.ec_cmd_queue.qsize() + ) + + # Add the EC UART as an output to be serviced. + if self.connected and self.ec_uart_pty not in self.outputs: + self.outputs.append(self.ec_uart_pty) + + def PackCommand(self, raw_cmd): + r"""Packs a command for use with error checking. + + For error checking, we pack console commands in a particular format. The + format is as follows: + + &&[x][x][x][x]&{cmd}\n\n + ^ ^ ^^ ^^ ^ ^-- 2 newlines. + | | || || |-- the raw console command. + | | || ||-- 1 ampersand. + | | ||____|--- 2 hex digits representing the CRC8 of cmd. + | |____|-- 2 hex digits reprsenting the length of cmd. + |-- 2 ampersands + + Args: + raw_cmd: A pre-packed string which contains the raw command. + + Returns: + A string which contains the packed command. + """ + # Don't pack a single carriage return. + if raw_cmd != b"\r": + # The command format is as follows. + # &&[x][x][x][x]&{cmd}\n\n + packed_cmd = [] + packed_cmd.append(b"&&") + # The first pair of hex digits are the length of the command. + packed_cmd.append(b"%02x" % len(raw_cmd)) + # Then the CRC8 of cmd. + packed_cmd.append(b"%02x" % Crc8(raw_cmd)) + packed_cmd.append(b"&") + # Now, the raw command followed by 2 newlines. + packed_cmd.append(raw_cmd) + packed_cmd.append(b"\n\n") + return b"".join(packed_cmd) + else: + return raw_cmd + + def ProcessCommand(self, command): + """Captures the input determines what actions to take. + + Args: + command: A string representing the command sent by the user. + """ + if command == b"disconnect": + if self.connected: + self.logger.debug("UART disconnect request.") + # Drop all pending commands if any. + while not self.ec_cmd_queue.empty(): + c = self.ec_cmd_queue.get() + self.logger.debug("dropped: '%s'", c) + if self.enhanced_ec: + # Reset retry state. + self.cmd_retries = COMMAND_RETRIES + self.last_cmd = b"" + # Get the UART that the interpreter is attached to. + fileobj = self.ec_uart_pty + self.logger.debug("fileobj: %r", fileobj) + # Remove the descriptor from the inputs and outputs. + self.inputs.remove(fileobj) + if fileobj in self.outputs: + self.outputs.remove(fileobj) + self.logger.debug( + "Removed fileobj. Remaining inputs: %r", self.inputs + ) + # Close the file. + fileobj.close() + # Mark the interpreter as disconnected now. + self.connected = False + self.logger.debug( + "Disconnected from %s.", self.ec_uart_pty_name + ) + return + + elif command == b"reconnect": + if not self.connected: + self.logger.debug("UART reconnect request.") + # Reopen the PTY. + # TODO(https://bugs.python.org/issue27805, python3.7+): revert to ab+ + # TODO(https://bugs.python.org/issue20074): removing buffering=0 if/when + # that gets fixed, or keep two pty: one for reading and one for writing + fileobj = open(self.ec_uart_pty_name, "r+b", buffering=0) + self.logger.debug("fileobj: %r", fileobj) + self.ec_uart_pty = fileobj + # Add the descriptor to the inputs. + self.inputs.append(fileobj) + self.logger.debug("fileobj added. curr inputs: %r", self.inputs) + # Mark the interpreter as connected now. + self.connected = True + self.logger.debug("Connected to %s.", self.ec_uart_pty_name) + return + + elif command.startswith(b"enhanced"): + self.enhanced_ec = command.split(b" ")[1] == b"True" + return + + # Ignore any other commands while in the disconnected state. + self.logger.log(1, "command: '%s'", command) + if not self.connected: + self.logger.debug( + "Ignoring command because currently disconnected." + ) + return + + # Remove leading and trailing spaces only if this is an enhanced EC image. + # For non-enhanced EC images, commands will be single characters at a time + # and can be spaces. + if self.enhanced_ec: + command = command.strip(b" ") + + # There's nothing to do if the command is empty. + if len(command) == 0: + return + + # Handle log level change requests. + if command.startswith(b"loglevel"): + self.logger.debug("Log level change request.") + new_log_level = int(command.split(b" ")[1]) + self.logger.logger.setLevel(new_log_level) + self.logger.info("Log level changed to %d.", new_log_level) + return + + # Check for interrogation command. + if command == EC_SYN: + # User is requesting interrogation. Send SYN as is. + self.logger.debug("User requesting interrogation.") + self.interrogating = True + # Assume the EC isn't enhanced until we get a response. + self.enhanced_ec = False + elif self.enhanced_ec: + # Enhanced EC images require the plaintext commands to be packed. + command = self.PackCommand(command) + # TODO(aaboagye): Make a dict of commands and keys and eventually, + # handle partial matching based on unique prefixes. + + self.EnqueueCmd(command) + + def HandleCmdRetries(self): + """Attempts to retry commands if possible.""" + if self.cmd_retries > 0: + # The EC encountered an error. We'll have to retry again. + self.logger.warning("Retrying command...") + self.cmd_retries -= 1 + self.logger.warning("Retries remaining: %d", self.cmd_retries) + # Retry the command and add the EC UART to the writers again. + self.EnqueueCmd(self.last_cmd) + self.outputs.append(self.ec_uart_pty) + else: + # We're out of retries, so just give up. + self.logger.error("Command failed. No retries left.") + # Clear the command in progress. + self.last_cmd = b"" + # Reset the retry count. + self.cmd_retries = COMMAND_RETRIES + + def SendCmdToEC(self): + """Sends a command to the EC.""" + # If we're retrying a command, just try to send it again. + if self.cmd_retries < COMMAND_RETRIES: + cmd = self.last_cmd + else: + # If we're not retrying, we should not be writing to the EC if we have no + # items in our command queue. + assert not self.ec_cmd_queue.empty() + # Get the command to send. + cmd = self.ec_cmd_queue.get() + + # Send the command. + self.ec_uart_pty.write(cmd) + self.ec_uart_pty.flush() + self.logger.log(1, "Sent command to EC.") + + if self.enhanced_ec and cmd != EC_SYN: + # Now, that we've sent the command, store the current command as the last + # command sent. If we encounter an error string, we will attempt to retry + # this command. + if cmd != self.last_cmd: + self.last_cmd = cmd + # Reset the retry count. + self.cmd_retries = COMMAND_RETRIES + + # If no command is pending to be sent, then we can remove the EC UART from + # writers. Might need better checking for command retry logic in here. + if self.ec_cmd_queue.empty(): + # Remove the EC UART from the writers while we wait for a response. + self.logger.debug("Removing EC UART from writers.") + self.outputs.remove(self.ec_uart_pty) + + def HandleECData(self): + """Handle any debug prints from the EC.""" + self.logger.log(1, "EC has data") + # Read what the EC sent us. + data = os.read(self.ec_uart_pty.fileno(), EC_MAX_READ) + self.logger.log(1, "got: '%s'", binascii.hexlify(data)) + if b"&E" in data and self.enhanced_ec: + # We received an error, so we should retry it if possible. + self.logger.warning("Error string found in data.") + self.HandleCmdRetries() + return + + # If we were interrogating, check the response and update our knowledge + # of the current EC image. + if self.interrogating: + self.enhanced_ec = data == EC_ACK + if self.enhanced_ec: + self.logger.debug("The current EC image seems enhanced.") + else: + self.logger.debug( + "The current EC image does NOT seem enhanced." + ) + # Done interrogating. + self.interrogating = False + # For now, just forward everything the EC sends us. + self.logger.log(1, "Forwarding to user...") + self.dbg_pipe.send(data) + + def HandleUserData(self): + """Handle any incoming commands from the user. + + Raises: + EOFError: Allowed to propagate through from self.cmd_pipe.recv(). + """ + self.logger.log(1, "Command data available. Begin processing.") + data = self.cmd_pipe.recv() + # Process the command. + self.ProcessCommand(data) def Crc8(data): - """Calculates the CRC8 of data. + """Calculates the CRC8 of data. - The generator polynomial used is: x^8 + x^2 + x + 1. - This is the same implementation that is used in the EC. + The generator polynomial used is: x^8 + x^2 + x + 1. + This is the same implementation that is used in the EC. - Args: - data: A string of data that we wish to calculate the CRC8 on. + Args: + data: A string of data that we wish to calculate the CRC8 on. - Returns: - crc >> 8: An integer representing the CRC8 value. - """ - crc = 0 - for byte in six.iterbytes(data): - crc ^= (byte << 8) - for _ in range(8): - if crc & 0x8000: - crc ^= (0x1070 << 3) - crc <<= 1 - return crc >> 8 + Returns: + crc >> 8: An integer representing the CRC8 value. + """ + crc = 0 + for byte in six.iterbytes(data): + crc ^= byte << 8 + for _ in range(8): + if crc & 0x8000: + crc ^= 0x1070 << 3 + crc <<= 1 + return crc >> 8 def StartLoop(interp, shutdown_pipe=None): - """Starts an infinite loop of servicing the user and the EC. - - StartLoop checks to see if there are any commands to process, processing them - if any, and forwards EC output to the user. - - When sending a command to the EC, we send the command once and check the - response to see if the EC encountered an error when receiving the command. An - error condition is reported to the interpreter by a string with at least one - '&' and 'E'. The full string is actually '&&EE', however it's possible that - the leading ampersand or trailing 'E' could be dropped. If an error is - encountered, the interpreter will retry up to the amount configured. - - Args: - interp: An Interpreter object that has been properly initialised. - shutdown_pipe: A file object for a pipe or equivalent that becomes readable - (not blocked) to indicate that the loop should exit. Can be None to never - exit the loop. - """ - try: - # This is used instead of "break" to avoid exiting the loop in the middle of - # an iteration. - continue_looping = True - - while continue_looping: - # The inputs list is created anew in each loop iteration because the - # Interpreter class sometimes modifies the interp.inputs list. - if shutdown_pipe is None: - inputs = interp.inputs - else: - inputs = list(interp.inputs) - inputs.append(shutdown_pipe) - - readable, writeable, _ = select.select(inputs, interp.outputs, []) - - for obj in readable: - # Handle any debug prints from the EC. - if obj is interp.ec_uart_pty: - interp.HandleECData() - - # Handle any commands from the user. - elif obj is interp.cmd_pipe: - try: - interp.HandleUserData() - except EOFError: - interp.logger.debug( - 'ec3po interpreter received EOF from cmd_pipe in ' - 'HandleUserData()') - continue_looping = False - - elif obj is shutdown_pipe: - interp.logger.debug( - 'ec3po interpreter received shutdown pipe unblocked notification') - continue_looping = False - - for obj in writeable: - # Send a command to the EC. - if obj is interp.ec_uart_pty: - interp.SendCmdToEC() - - except KeyboardInterrupt: - pass - - finally: - interp.cmd_pipe.close() - interp.dbg_pipe.close() - interp.ec_uart_pty.close() - if shutdown_pipe is not None: - shutdown_pipe.close() - interp.logger.debug('Exit ec3po interpreter loop for %s', - interp.ec_uart_pty_name) + """Starts an infinite loop of servicing the user and the EC. + + StartLoop checks to see if there are any commands to process, processing them + if any, and forwards EC output to the user. + + When sending a command to the EC, we send the command once and check the + response to see if the EC encountered an error when receiving the command. An + error condition is reported to the interpreter by a string with at least one + '&' and 'E'. The full string is actually '&&EE', however it's possible that + the leading ampersand or trailing 'E' could be dropped. If an error is + encountered, the interpreter will retry up to the amount configured. + + Args: + interp: An Interpreter object that has been properly initialised. + shutdown_pipe: A file object for a pipe or equivalent that becomes readable + (not blocked) to indicate that the loop should exit. Can be None to never + exit the loop. + """ + try: + # This is used instead of "break" to avoid exiting the loop in the middle of + # an iteration. + continue_looping = True + + while continue_looping: + # The inputs list is created anew in each loop iteration because the + # Interpreter class sometimes modifies the interp.inputs list. + if shutdown_pipe is None: + inputs = interp.inputs + else: + inputs = list(interp.inputs) + inputs.append(shutdown_pipe) + + readable, writeable, _ = select.select(inputs, interp.outputs, []) + + for obj in readable: + # Handle any debug prints from the EC. + if obj is interp.ec_uart_pty: + interp.HandleECData() + + # Handle any commands from the user. + elif obj is interp.cmd_pipe: + try: + interp.HandleUserData() + except EOFError: + interp.logger.debug( + "ec3po interpreter received EOF from cmd_pipe in " + "HandleUserData()" + ) + continue_looping = False + + elif obj is shutdown_pipe: + interp.logger.debug( + "ec3po interpreter received shutdown pipe unblocked notification" + ) + continue_looping = False + + for obj in writeable: + # Send a command to the EC. + if obj is interp.ec_uart_pty: + interp.SendCmdToEC() + + except KeyboardInterrupt: + pass + + finally: + interp.cmd_pipe.close() + interp.dbg_pipe.close() + interp.ec_uart_pty.close() + if shutdown_pipe is not None: + shutdown_pipe.close() + interp.logger.debug( + "Exit ec3po interpreter loop for %s", interp.ec_uart_pty_name + ) diff --git a/util/ec3po/interpreter_unittest.py b/util/ec3po/interpreter_unittest.py index fe4d43c351..e8f19e2e46 100755 --- a/util/ec3po/interpreter_unittest.py +++ b/util/ec3po/interpreter_unittest.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright 2015 The Chromium OS Authors. All rights reserved. +# Copyright 2015 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -10,371 +10,409 @@ from __future__ import print_function import logging -import mock import tempfile import unittest +import mock # pylint:disable=import-error import six - -from ec3po import interpreter -from ec3po import threadproc_shim +from ec3po import interpreter, threadproc_shim def GetBuiltins(func): - if six.PY2: - return '__builtin__.' + func - return 'builtins.' + func + if six.PY2: + return "__builtin__." + func + return "builtins." + func class TestEnhancedECBehaviour(unittest.TestCase): - """Test case to verify all enhanced EC interpretation tasks.""" - def setUp(self): - """Setup the test harness.""" - # Setup logging with a timestamp, the module, and the log level. - logging.basicConfig(level=logging.DEBUG, - format=('%(asctime)s - %(module)s -' - ' %(levelname)s - %(message)s')) - - # Create a tempfile that would represent the EC UART PTY. - self.tempfile = tempfile.NamedTemporaryFile() - - # Create the pipes that the interpreter will use. - self.cmd_pipe_user, self.cmd_pipe_itpr = threadproc_shim.Pipe() - self.dbg_pipe_user, self.dbg_pipe_itpr = threadproc_shim.Pipe(duplex=False) - - # Mock the open() function so we can inspect reads/writes to the EC. - self.ec_uart_pty = mock.mock_open() - - with mock.patch(GetBuiltins('open'), self.ec_uart_pty): - # Create an interpreter. - self.itpr = interpreter.Interpreter(self.tempfile.name, - self.cmd_pipe_itpr, - self.dbg_pipe_itpr, - log_level=logging.DEBUG, - name="EC") - - @mock.patch('ec3po.interpreter.os') - def test_HandlingCommandsThatProduceNoOutput(self, mock_os): - """Verify that the Interpreter correctly handles non-output commands. - - Args: - mock_os: MagicMock object replacing the 'os' module for this test - case. - """ - # The interpreter init should open the EC UART PTY. - expected_ec_calls = [mock.call(self.tempfile.name, 'r+b', buffering=0)] - # Have a command come in the command pipe. The first command will be an - # interrogation to determine if the EC is enhanced or not. - self.cmd_pipe_user.send(interpreter.EC_SYN) - self.itpr.HandleUserData() - # At this point, the command should be queued up waiting to be sent, so - # let's actually send it to the EC. - self.itpr.SendCmdToEC() - expected_ec_calls.extend([mock.call().write(interpreter.EC_SYN), - mock.call().flush()]) - # Now, assume that the EC sends only 1 response back of EC_ACK. - mock_os.read.side_effect = [interpreter.EC_ACK] - # When reading the EC, the interpreter will call file.fileno() to pass to - # os.read(). - expected_ec_calls.append(mock.call().fileno()) - # Simulate the response. - self.itpr.HandleECData() - - # Now that the interrogation was complete, it's time to send down the real - # command. - test_cmd = b'chan save' - # Send the test command down the pipe. - self.cmd_pipe_user.send(test_cmd) - self.itpr.HandleUserData() - self.itpr.SendCmdToEC() - # Since the EC image is enhanced, we should have sent a packed command. - expected_ec_calls.append(mock.call().write(self.itpr.PackCommand(test_cmd))) - expected_ec_calls.append(mock.call().flush()) - - # Now that the first command was sent, we should send another command which - # produces no output. The console would send another interrogation. - self.cmd_pipe_user.send(interpreter.EC_SYN) - self.itpr.HandleUserData() - self.itpr.SendCmdToEC() - expected_ec_calls.extend([mock.call().write(interpreter.EC_SYN), - mock.call().flush()]) - # Again, assume that the EC sends only 1 response back of EC_ACK. - mock_os.read.side_effect = [interpreter.EC_ACK] - # When reading the EC, the interpreter will call file.fileno() to pass to - # os.read(). - expected_ec_calls.append(mock.call().fileno()) - # Simulate the response. - self.itpr.HandleECData() - - # Now send the second test command. - test_cmd = b'chan 0' - self.cmd_pipe_user.send(test_cmd) - self.itpr.HandleUserData() - self.itpr.SendCmdToEC() - # Since the EC image is enhanced, we should have sent a packed command. - expected_ec_calls.append(mock.call().write(self.itpr.PackCommand(test_cmd))) - expected_ec_calls.append(mock.call().flush()) - - # Finally, verify that the appropriate writes were actually sent to the EC. - self.ec_uart_pty.assert_has_calls(expected_ec_calls) - - @mock.patch('ec3po.interpreter.os') - def test_CommandRetryingOnError(self, mock_os): - """Verify that commands are retried if an error is encountered. - - Args: - mock_os: MagicMock object replacing the 'os' module for this test - case. - """ - # The interpreter init should open the EC UART PTY. - expected_ec_calls = [mock.call(self.tempfile.name, 'r+b', buffering=0)] - # Have a command come in the command pipe. The first command will be an - # interrogation to determine if the EC is enhanced or not. - self.cmd_pipe_user.send(interpreter.EC_SYN) - self.itpr.HandleUserData() - # At this point, the command should be queued up waiting to be sent, so - # let's actually send it to the EC. - self.itpr.SendCmdToEC() - expected_ec_calls.extend([mock.call().write(interpreter.EC_SYN), - mock.call().flush()]) - # Now, assume that the EC sends only 1 response back of EC_ACK. - mock_os.read.side_effect = [interpreter.EC_ACK] - # When reading the EC, the interpreter will call file.fileno() to pass to - # os.read(). - expected_ec_calls.append(mock.call().fileno()) - # Simulate the response. - self.itpr.HandleECData() - - # Let's send a command that is received on the EC-side with an error. - test_cmd = b'accelinfo' - self.cmd_pipe_user.send(test_cmd) - self.itpr.HandleUserData() - self.itpr.SendCmdToEC() - packed_cmd = self.itpr.PackCommand(test_cmd) - expected_ec_calls.extend([mock.call().write(packed_cmd), - mock.call().flush()]) - # Have the EC return the error string twice. - mock_os.read.side_effect = [b'&&EE', b'&&EE'] - for i in range(2): - # When reading the EC, the interpreter will call file.fileno() to pass to - # os.read(). - expected_ec_calls.append(mock.call().fileno()) - # Simulate the response. - self.itpr.HandleECData() - - # Since an error was received, the EC should attempt to retry the command. - expected_ec_calls.extend([mock.call().write(packed_cmd), - mock.call().flush()]) - # Verify that the retry count was decremented. - self.assertEqual(interpreter.COMMAND_RETRIES-i-1, self.itpr.cmd_retries, - 'Unexpected cmd_remaining count.') - # Actually retry the command. - self.itpr.SendCmdToEC() - - # Now assume that the last one goes through with no trouble. - expected_ec_calls.extend([mock.call().write(packed_cmd), - mock.call().flush()]) - self.itpr.SendCmdToEC() - - # Verify all the calls. - self.ec_uart_pty.assert_has_calls(expected_ec_calls) - - def test_PackCommandsForEnhancedEC(self): - """Verify that the interpreter packs commands for enhanced EC images.""" - # Assume current EC image is enhanced. - self.itpr.enhanced_ec = True - # Receive a command from the user. - test_cmd = b'gettime' - self.cmd_pipe_user.send(test_cmd) - # Mock out PackCommand to see if it was called. - self.itpr.PackCommand = mock.MagicMock() - # Have the interpreter handle the command. - self.itpr.HandleUserData() - # Verify that PackCommand() was called. - self.itpr.PackCommand.assert_called_once_with(test_cmd) - - def test_DontPackCommandsForNonEnhancedEC(self): - """Verify the interpreter doesn't pack commands for non-enhanced images.""" - # Assume current EC image is not enhanced. - self.itpr.enhanced_ec = False - # Receive a command from the user. - test_cmd = b'gettime' - self.cmd_pipe_user.send(test_cmd) - # Mock out PackCommand to see if it was called. - self.itpr.PackCommand = mock.MagicMock() - # Have the interpreter handle the command. - self.itpr.HandleUserData() - # Verify that PackCommand() was called. - self.itpr.PackCommand.assert_not_called() - - @mock.patch('ec3po.interpreter.os') - def test_KeepingTrackOfInterrogation(self, mock_os): - """Verify that the interpreter can track the state of the interrogation. - - Args: - mock_os: MagicMock object replacing the 'os' module. for this test - case. - """ - # Upon init, the interpreter should assume that the current EC image is not - # enhanced. - self.assertFalse(self.itpr.enhanced_ec, msg=('State of enhanced_ec upon' - ' init is not False.')) - - # Assume an interrogation request comes in from the user. - self.cmd_pipe_user.send(interpreter.EC_SYN) - self.itpr.HandleUserData() - - # Verify the state is now within an interrogation. - self.assertTrue(self.itpr.interrogating, 'interrogating should be True') - # The state of enhanced_ec should not be changed yet because we haven't - # received a valid response yet. - self.assertFalse(self.itpr.enhanced_ec, msg=('State of enhanced_ec is ' - 'not False.')) - - # Assume that the EC responds with an EC_ACK. - mock_os.read.side_effect = [interpreter.EC_ACK] - self.itpr.HandleECData() - - # Now, the interrogation should be complete and we should know that the - # current EC image is enhanced. - self.assertFalse(self.itpr.interrogating, msg=('interrogating should be ' - 'False')) - self.assertTrue(self.itpr.enhanced_ec, msg='enhanced_ec sholud be True') - - # Now let's perform another interrogation, but pretend that the EC ignores - # it. - self.cmd_pipe_user.send(interpreter.EC_SYN) - self.itpr.HandleUserData() - - # Verify interrogating state. - self.assertTrue(self.itpr.interrogating, 'interrogating sholud be True') - # We should assume that the image is not enhanced until we get the valid - # response. - self.assertFalse(self.itpr.enhanced_ec, 'enhanced_ec should be False now.') - - # Let's pretend that we get a random debug print. This should clear the - # interrogating flag. - mock_os.read.side_effect = [b'[1660.593076 HC 0x103]'] - self.itpr.HandleECData() - - # Verify that interrogating flag is cleared and enhanced_ec is still False. - self.assertFalse(self.itpr.interrogating, 'interrogating should be False.') - self.assertFalse(self.itpr.enhanced_ec, - 'enhanced_ec should still be False.') + """Test case to verify all enhanced EC interpretation tasks.""" + + def setUp(self): + """Setup the test harness.""" + # Setup logging with a timestamp, the module, and the log level. + logging.basicConfig( + level=logging.DEBUG, + format=("%(asctime)s - %(module)s - %(levelname)s - %(message)s"), + ) + + # Create a tempfile that would represent the EC UART PTY. + self.tempfile = tempfile.NamedTemporaryFile() + + # Create the pipes that the interpreter will use. + self.cmd_pipe_user, self.cmd_pipe_itpr = threadproc_shim.Pipe() + self.dbg_pipe_user, self.dbg_pipe_itpr = threadproc_shim.Pipe( + duplex=False + ) + + # Mock the open() function so we can inspect reads/writes to the EC. + self.ec_uart_pty = mock.mock_open() + + with mock.patch(GetBuiltins("open"), self.ec_uart_pty): + # Create an interpreter. + self.itpr = interpreter.Interpreter( + self.tempfile.name, + self.cmd_pipe_itpr, + self.dbg_pipe_itpr, + log_level=logging.DEBUG, + name="EC", + ) + + @mock.patch("ec3po.interpreter.os") + def test_HandlingCommandsThatProduceNoOutput(self, mock_os): + """Verify that the Interpreter correctly handles non-output commands. + + Args: + mock_os: MagicMock object replacing the 'os' module for this test + case. + """ + # The interpreter init should open the EC UART PTY. + expected_ec_calls = [mock.call(self.tempfile.name, "r+b", buffering=0)] + # Have a command come in the command pipe. The first command will be an + # interrogation to determine if the EC is enhanced or not. + self.cmd_pipe_user.send(interpreter.EC_SYN) + self.itpr.HandleUserData() + # At this point, the command should be queued up waiting to be sent, so + # let's actually send it to the EC. + self.itpr.SendCmdToEC() + expected_ec_calls.extend( + [mock.call().write(interpreter.EC_SYN), mock.call().flush()] + ) + # Now, assume that the EC sends only 1 response back of EC_ACK. + mock_os.read.side_effect = [interpreter.EC_ACK] + # When reading the EC, the interpreter will call file.fileno() to pass to + # os.read(). + expected_ec_calls.append(mock.call().fileno()) + # Simulate the response. + self.itpr.HandleECData() + + # Now that the interrogation was complete, it's time to send down the real + # command. + test_cmd = b"chan save" + # Send the test command down the pipe. + self.cmd_pipe_user.send(test_cmd) + self.itpr.HandleUserData() + self.itpr.SendCmdToEC() + # Since the EC image is enhanced, we should have sent a packed command. + expected_ec_calls.append( + mock.call().write(self.itpr.PackCommand(test_cmd)) + ) + expected_ec_calls.append(mock.call().flush()) + + # Now that the first command was sent, we should send another command which + # produces no output. The console would send another interrogation. + self.cmd_pipe_user.send(interpreter.EC_SYN) + self.itpr.HandleUserData() + self.itpr.SendCmdToEC() + expected_ec_calls.extend( + [mock.call().write(interpreter.EC_SYN), mock.call().flush()] + ) + # Again, assume that the EC sends only 1 response back of EC_ACK. + mock_os.read.side_effect = [interpreter.EC_ACK] + # When reading the EC, the interpreter will call file.fileno() to pass to + # os.read(). + expected_ec_calls.append(mock.call().fileno()) + # Simulate the response. + self.itpr.HandleECData() + + # Now send the second test command. + test_cmd = b"chan 0" + self.cmd_pipe_user.send(test_cmd) + self.itpr.HandleUserData() + self.itpr.SendCmdToEC() + # Since the EC image is enhanced, we should have sent a packed command. + expected_ec_calls.append( + mock.call().write(self.itpr.PackCommand(test_cmd)) + ) + expected_ec_calls.append(mock.call().flush()) + + # Finally, verify that the appropriate writes were actually sent to the EC. + self.ec_uart_pty.assert_has_calls(expected_ec_calls) + + @mock.patch("ec3po.interpreter.os") + def test_CommandRetryingOnError(self, mock_os): + """Verify that commands are retried if an error is encountered. + + Args: + mock_os: MagicMock object replacing the 'os' module for this test + case. + """ + # The interpreter init should open the EC UART PTY. + expected_ec_calls = [mock.call(self.tempfile.name, "r+b", buffering=0)] + # Have a command come in the command pipe. The first command will be an + # interrogation to determine if the EC is enhanced or not. + self.cmd_pipe_user.send(interpreter.EC_SYN) + self.itpr.HandleUserData() + # At this point, the command should be queued up waiting to be sent, so + # let's actually send it to the EC. + self.itpr.SendCmdToEC() + expected_ec_calls.extend( + [mock.call().write(interpreter.EC_SYN), mock.call().flush()] + ) + # Now, assume that the EC sends only 1 response back of EC_ACK. + mock_os.read.side_effect = [interpreter.EC_ACK] + # When reading the EC, the interpreter will call file.fileno() to pass to + # os.read(). + expected_ec_calls.append(mock.call().fileno()) + # Simulate the response. + self.itpr.HandleECData() + + # Let's send a command that is received on the EC-side with an error. + test_cmd = b"accelinfo" + self.cmd_pipe_user.send(test_cmd) + self.itpr.HandleUserData() + self.itpr.SendCmdToEC() + packed_cmd = self.itpr.PackCommand(test_cmd) + expected_ec_calls.extend( + [mock.call().write(packed_cmd), mock.call().flush()] + ) + # Have the EC return the error string twice. + mock_os.read.side_effect = [b"&&EE", b"&&EE"] + for i in range(2): + # When reading the EC, the interpreter will call file.fileno() to pass to + # os.read(). + expected_ec_calls.append(mock.call().fileno()) + # Simulate the response. + self.itpr.HandleECData() + + # Since an error was received, the EC should attempt to retry the command. + expected_ec_calls.extend( + [mock.call().write(packed_cmd), mock.call().flush()] + ) + # Verify that the retry count was decremented. + self.assertEqual( + interpreter.COMMAND_RETRIES - i - 1, + self.itpr.cmd_retries, + "Unexpected cmd_remaining count.", + ) + # Actually retry the command. + self.itpr.SendCmdToEC() + + # Now assume that the last one goes through with no trouble. + expected_ec_calls.extend( + [mock.call().write(packed_cmd), mock.call().flush()] + ) + self.itpr.SendCmdToEC() + + # Verify all the calls. + self.ec_uart_pty.assert_has_calls(expected_ec_calls) + + def test_PackCommandsForEnhancedEC(self): + """Verify that the interpreter packs commands for enhanced EC images.""" + # Assume current EC image is enhanced. + self.itpr.enhanced_ec = True + # Receive a command from the user. + test_cmd = b"gettime" + self.cmd_pipe_user.send(test_cmd) + # Mock out PackCommand to see if it was called. + self.itpr.PackCommand = mock.MagicMock() + # Have the interpreter handle the command. + self.itpr.HandleUserData() + # Verify that PackCommand() was called. + self.itpr.PackCommand.assert_called_once_with(test_cmd) + + def test_DontPackCommandsForNonEnhancedEC(self): + """Verify the interpreter doesn't pack commands for non-enhanced images.""" + # Assume current EC image is not enhanced. + self.itpr.enhanced_ec = False + # Receive a command from the user. + test_cmd = b"gettime" + self.cmd_pipe_user.send(test_cmd) + # Mock out PackCommand to see if it was called. + self.itpr.PackCommand = mock.MagicMock() + # Have the interpreter handle the command. + self.itpr.HandleUserData() + # Verify that PackCommand() was called. + self.itpr.PackCommand.assert_not_called() + + @mock.patch("ec3po.interpreter.os") + def test_KeepingTrackOfInterrogation(self, mock_os): + """Verify that the interpreter can track the state of the interrogation. + + Args: + mock_os: MagicMock object replacing the 'os' module. for this test + case. + """ + # Upon init, the interpreter should assume that the current EC image is not + # enhanced. + self.assertFalse( + self.itpr.enhanced_ec, + msg=("State of enhanced_ec upon init is not False."), + ) + + # Assume an interrogation request comes in from the user. + self.cmd_pipe_user.send(interpreter.EC_SYN) + self.itpr.HandleUserData() + + # Verify the state is now within an interrogation. + self.assertTrue(self.itpr.interrogating, "interrogating should be True") + # The state of enhanced_ec should not be changed yet because we haven't + # received a valid response yet. + self.assertFalse( + self.itpr.enhanced_ec, msg=("State of enhanced_ec is not False.") + ) + + # Assume that the EC responds with an EC_ACK. + mock_os.read.side_effect = [interpreter.EC_ACK] + self.itpr.HandleECData() + + # Now, the interrogation should be complete and we should know that the + # current EC image is enhanced. + self.assertFalse( + self.itpr.interrogating, msg=("interrogating should be False") + ) + self.assertTrue(self.itpr.enhanced_ec, msg="enhanced_ec sholud be True") + + # Now let's perform another interrogation, but pretend that the EC ignores + # it. + self.cmd_pipe_user.send(interpreter.EC_SYN) + self.itpr.HandleUserData() + + # Verify interrogating state. + self.assertTrue(self.itpr.interrogating, "interrogating sholud be True") + # We should assume that the image is not enhanced until we get the valid + # response. + self.assertFalse( + self.itpr.enhanced_ec, "enhanced_ec should be False now." + ) + + # Let's pretend that we get a random debug print. This should clear the + # interrogating flag. + mock_os.read.side_effect = [b"[1660.593076 HC 0x103]"] + self.itpr.HandleECData() + + # Verify that interrogating flag is cleared and enhanced_ec is still False. + self.assertFalse( + self.itpr.interrogating, "interrogating should be False." + ) + self.assertFalse( + self.itpr.enhanced_ec, "enhanced_ec should still be False." + ) class TestUARTDisconnection(unittest.TestCase): - """Test case to verify interpreter disconnection/reconnection.""" - def setUp(self): - """Setup the test harness.""" - # Setup logging with a timestamp, the module, and the log level. - logging.basicConfig(level=logging.DEBUG, - format=('%(asctime)s - %(module)s -' - ' %(levelname)s - %(message)s')) - - # Create a tempfile that would represent the EC UART PTY. - self.tempfile = tempfile.NamedTemporaryFile() - - # Create the pipes that the interpreter will use. - self.cmd_pipe_user, self.cmd_pipe_itpr = threadproc_shim.Pipe() - self.dbg_pipe_user, self.dbg_pipe_itpr = threadproc_shim.Pipe(duplex=False) - - # Mock the open() function so we can inspect reads/writes to the EC. - self.ec_uart_pty = mock.mock_open() - - with mock.patch(GetBuiltins('open'), self.ec_uart_pty): - # Create an interpreter. - self.itpr = interpreter.Interpreter(self.tempfile.name, - self.cmd_pipe_itpr, - self.dbg_pipe_itpr, - log_level=logging.DEBUG, - name="EC") - - # First, check that interpreter is initialized to connected. - self.assertTrue(self.itpr.connected, ('The interpreter should be' - ' initialized in a connected state')) - - def test_DisconnectStopsECTraffic(self): - """Verify that when in disconnected state, no debug prints are sent.""" - # Let's send a disconnect command through the command pipe. - self.cmd_pipe_user.send(b'disconnect') - self.itpr.HandleUserData() - - # Verify interpreter is disconnected from EC. - self.assertFalse(self.itpr.connected, ('The interpreter should be' - 'disconnected.')) - # Verify that the EC UART is no longer a member of the inputs. The - # interpreter will never pull data from the EC if it's not a member of the - # inputs list. - self.assertFalse(self.itpr.ec_uart_pty in self.itpr.inputs) - - def test_CommandsDroppedWhenDisconnected(self): - """Verify that when in disconnected state, commands are dropped.""" - # Send a command, followed by 'disconnect'. - self.cmd_pipe_user.send(b'taskinfo') - self.itpr.HandleUserData() - self.cmd_pipe_user.send(b'disconnect') - self.itpr.HandleUserData() - - # Verify interpreter is disconnected from EC. - self.assertFalse(self.itpr.connected, ('The interpreter should be' - 'disconnected.')) - # Verify that the EC UART is no longer a member of the inputs nor outputs. - self.assertFalse(self.itpr.ec_uart_pty in self.itpr.inputs) - self.assertFalse(self.itpr.ec_uart_pty in self.itpr.outputs) - - # Have the user send a few more commands in the disconnected state. - command = 'help\n' - for char in command: - self.cmd_pipe_user.send(char.encode('utf-8')) - self.itpr.HandleUserData() - - # The command queue should be empty. - self.assertEqual(0, self.itpr.ec_cmd_queue.qsize()) - - # Now send the reconnect command. - self.cmd_pipe_user.send(b'reconnect') - - with mock.patch(GetBuiltins('open'), mock.mock_open()): - self.itpr.HandleUserData() - - # Verify interpreter is connected. - self.assertTrue(self.itpr.connected) - # Verify that EC UART is a member of the inputs. - self.assertTrue(self.itpr.ec_uart_pty in self.itpr.inputs) - # Since no command was sent after reconnection, verify that the EC UART is - # not a member of the outputs. - self.assertFalse(self.itpr.ec_uart_pty in self.itpr.outputs) - - def test_ReconnectAllowsECTraffic(self): - """Verify that when connected, EC UART traffic is allowed.""" - # Let's send a disconnect command through the command pipe. - self.cmd_pipe_user.send(b'disconnect') - self.itpr.HandleUserData() - - # Verify interpreter is disconnected. - self.assertFalse(self.itpr.connected, ('The interpreter should be' - 'disconnected.')) - # Verify that the EC UART is no longer a member of the inputs nor outputs. - self.assertFalse(self.itpr.ec_uart_pty in self.itpr.inputs) - self.assertFalse(self.itpr.ec_uart_pty in self.itpr.outputs) - - # Issue reconnect command through the command pipe. - self.cmd_pipe_user.send(b'reconnect') - - with mock.patch(GetBuiltins('open'), mock.mock_open()): - self.itpr.HandleUserData() - - # Verify interpreter is connected. - self.assertTrue(self.itpr.connected, ('The interpreter should be' - 'connected.')) - # Verify that the EC UART is now a member of the inputs. - self.assertTrue(self.itpr.ec_uart_pty in self.itpr.inputs) - # Since we have issued no commands during the disconnected state, no - # commands are pending and therefore the PTY should not be added to the - # outputs. - self.assertFalse(self.itpr.ec_uart_pty in self.itpr.outputs) - - -if __name__ == '__main__': - unittest.main() + """Test case to verify interpreter disconnection/reconnection.""" + + def setUp(self): + """Setup the test harness.""" + # Setup logging with a timestamp, the module, and the log level. + logging.basicConfig( + level=logging.DEBUG, + format=("%(asctime)s - %(module)s - %(levelname)s - %(message)s"), + ) + + # Create a tempfile that would represent the EC UART PTY. + self.tempfile = tempfile.NamedTemporaryFile() + + # Create the pipes that the interpreter will use. + self.cmd_pipe_user, self.cmd_pipe_itpr = threadproc_shim.Pipe() + self.dbg_pipe_user, self.dbg_pipe_itpr = threadproc_shim.Pipe( + duplex=False + ) + + # Mock the open() function so we can inspect reads/writes to the EC. + self.ec_uart_pty = mock.mock_open() + + with mock.patch(GetBuiltins("open"), self.ec_uart_pty): + # Create an interpreter. + self.itpr = interpreter.Interpreter( + self.tempfile.name, + self.cmd_pipe_itpr, + self.dbg_pipe_itpr, + log_level=logging.DEBUG, + name="EC", + ) + + # First, check that interpreter is initialized to connected. + self.assertTrue( + self.itpr.connected, + ("The interpreter should be initialized in a connected state"), + ) + + def test_DisconnectStopsECTraffic(self): + """Verify that when in disconnected state, no debug prints are sent.""" + # Let's send a disconnect command through the command pipe. + self.cmd_pipe_user.send(b"disconnect") + self.itpr.HandleUserData() + + # Verify interpreter is disconnected from EC. + self.assertFalse( + self.itpr.connected, ("The interpreter should be disconnected.") + ) + # Verify that the EC UART is no longer a member of the inputs. The + # interpreter will never pull data from the EC if it's not a member of the + # inputs list. + self.assertFalse(self.itpr.ec_uart_pty in self.itpr.inputs) + + def test_CommandsDroppedWhenDisconnected(self): + """Verify that when in disconnected state, commands are dropped.""" + # Send a command, followed by 'disconnect'. + self.cmd_pipe_user.send(b"taskinfo") + self.itpr.HandleUserData() + self.cmd_pipe_user.send(b"disconnect") + self.itpr.HandleUserData() + + # Verify interpreter is disconnected from EC. + self.assertFalse( + self.itpr.connected, ("The interpreter should be disconnected.") + ) + # Verify that the EC UART is no longer a member of the inputs nor outputs. + self.assertFalse(self.itpr.ec_uart_pty in self.itpr.inputs) + self.assertFalse(self.itpr.ec_uart_pty in self.itpr.outputs) + + # Have the user send a few more commands in the disconnected state. + command = "help\n" + for char in command: + self.cmd_pipe_user.send(char.encode("utf-8")) + self.itpr.HandleUserData() + + # The command queue should be empty. + self.assertEqual(0, self.itpr.ec_cmd_queue.qsize()) + + # Now send the reconnect command. + self.cmd_pipe_user.send(b"reconnect") + + with mock.patch(GetBuiltins("open"), mock.mock_open()): + self.itpr.HandleUserData() + + # Verify interpreter is connected. + self.assertTrue(self.itpr.connected) + # Verify that EC UART is a member of the inputs. + self.assertTrue(self.itpr.ec_uart_pty in self.itpr.inputs) + # Since no command was sent after reconnection, verify that the EC UART is + # not a member of the outputs. + self.assertFalse(self.itpr.ec_uart_pty in self.itpr.outputs) + + def test_ReconnectAllowsECTraffic(self): + """Verify that when connected, EC UART traffic is allowed.""" + # Let's send a disconnect command through the command pipe. + self.cmd_pipe_user.send(b"disconnect") + self.itpr.HandleUserData() + + # Verify interpreter is disconnected. + self.assertFalse( + self.itpr.connected, ("The interpreter should be disconnected.") + ) + # Verify that the EC UART is no longer a member of the inputs nor outputs. + self.assertFalse(self.itpr.ec_uart_pty in self.itpr.inputs) + self.assertFalse(self.itpr.ec_uart_pty in self.itpr.outputs) + + # Issue reconnect command through the command pipe. + self.cmd_pipe_user.send(b"reconnect") + + with mock.patch(GetBuiltins("open"), mock.mock_open()): + self.itpr.HandleUserData() + + # Verify interpreter is connected. + self.assertTrue( + self.itpr.connected, ("The interpreter should be connected.") + ) + # Verify that the EC UART is now a member of the inputs. + self.assertTrue(self.itpr.ec_uart_pty in self.itpr.inputs) + # Since we have issued no commands during the disconnected state, no + # commands are pending and therefore the PTY should not be added to the + # outputs. + self.assertFalse(self.itpr.ec_uart_pty in self.itpr.outputs) + + +if __name__ == "__main__": + unittest.main() diff --git a/util/ec3po/run_tests.sh b/util/ec3po/run_tests.sh index ba513abe30..d61b2b428e 100755 --- a/util/ec3po/run_tests.sh +++ b/util/ec3po/run_tests.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2015 The Chromium OS Authors. All rights reserved. +# Copyright 2015 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/util/ec3po/threadproc_shim.py b/util/ec3po/threadproc_shim.py index da5440b1f3..f76841dbf7 100644 --- a/util/ec3po/threadproc_shim.py +++ b/util/ec3po/threadproc_shim.py @@ -1,4 +1,4 @@ -# Copyright 2018 The Chromium OS Authors. All rights reserved. +# Copyright 2018 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -34,33 +34,34 @@ wait until after completing the TODO above to stop using multiprocessing.Pipe! # Imports to bring objects into this namespace for users of this module. from multiprocessing import Pipe -from six.moves.queue import Queue from threading import Thread as ThreadOrProcess +from six.moves.queue import Queue + # True if this module has ec3po using subprocesses, False if using threads. USING_SUBPROCS = False def _DoNothing(): - """Do-nothing function for use as a callback with DoIf().""" + """Do-nothing function for use as a callback with DoIf().""" def DoIf(subprocs=_DoNothing, threads=_DoNothing): - """Return a callback or not based on ec3po use of subprocesses or threads. + """Return a callback or not based on ec3po use of subprocesses or threads. - Args: - subprocs: callback that does not require any args - This will be returned - (not called!) if and only if ec3po is using subprocesses. This is - OPTIONAL, the default value is a do-nothing callback that returns None. - threads: callback that does not require any args - This will be returned - (not called!) if and only if ec3po is using threads. This is OPTIONAL, - the default value is a do-nothing callback that returns None. + Args: + subprocs: callback that does not require any args - This will be returned + (not called!) if and only if ec3po is using subprocesses. This is + OPTIONAL, the default value is a do-nothing callback that returns None. + threads: callback that does not require any args - This will be returned + (not called!) if and only if ec3po is using threads. This is OPTIONAL, + the default value is a do-nothing callback that returns None. - Returns: - Either the subprocs or threads argument will be returned. - """ - return subprocs if USING_SUBPROCS else threads + Returns: + Either the subprocs or threads argument will be returned. + """ + return subprocs if USING_SUBPROCS else threads def Value(ctype, *args): - return ctype(*args) + return ctype(*args) diff --git a/util/ec_flash.c b/util/ec_flash.c index ffa4eca4b7..ba18bb8d4c 100644 --- a/util/ec_flash.c +++ b/util/ec_flash.c @@ -1,4 +1,4 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. +/* Copyright 2013 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -27,8 +27,8 @@ int ec_flash_read(uint8_t *buf, int offset, int size) for (i = 0; i < size; i += ec_max_insize) { p.offset = offset + i; p.size = MIN(size - i, ec_max_insize); - rv = ec_command(EC_CMD_FLASH_READ, 0, - &p, sizeof(p), ec_inbuf, p.size); + rv = ec_command(EC_CMD_FLASH_READ, 0, &p, sizeof(p), ec_inbuf, + p.size); if (rv < 0) { fprintf(stderr, "Read error at offset %d\n", i); return rv; @@ -58,7 +58,8 @@ int ec_flash_verify(const uint8_t *buf, int offset, int size) for (i = 0; i < size; i++) { if (buf[i] != rbuf[i]) { - fprintf(stderr, "Mismatch at offset 0x%x: " + fprintf(stderr, + "Mismatch at offset 0x%x: " "want 0x%02x, got 0x%02x\n", i, buf[i], rbuf[i]); free(rbuf); @@ -76,12 +77,15 @@ int ec_flash_verify(const uint8_t *buf, int offset, int size) */ static int get_flash_info_v2(struct ec_response_flash_info_2 *info_response) { - struct ec_params_flash_info_2 info_params = { - /* - * By setting this to zero we indicate that we don't care - * about getting the bank description in the response. - */ - .num_banks_desc = 0 + struct ec_params_flash_info_2 info_params = { /* + * By setting this to zero + * we indicate that we + * don't care about + * getting the bank + * description in the + * response. + */ + .num_banks_desc = 0 }; return ec_command(EC_CMD_FLASH_INFO, 2, &info_params, diff --git a/util/ec_flash.h b/util/ec_flash.h index f4aea3b7a3..179df1979b 100644 --- a/util/ec_flash.h +++ b/util/ec_flash.h @@ -1,4 +1,4 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. +/* Copyright 2013 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ diff --git a/util/ec_openocd.py b/util/ec_openocd.py index a84c00643c..e0a15bd08b 100755 --- a/util/ec_openocd.py +++ b/util/ec_openocd.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright 2022 The Chromium OS Authors. All rights reserved. +# Copyright 2022 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -16,6 +16,7 @@ import time Flashes and debugs the EC through openocd """ + @dataclasses.dataclass class BoardInfo: gdb_variant: str @@ -24,9 +25,7 @@ class BoardInfo: # Debuggers for each board, OpenOCD currently only supports GDB -boards = { - "skyrim": BoardInfo("arm-none-eabi-gdb", 6, 4) -} +boards = {"skyrim": BoardInfo("arm-none-eabi-gdb", 6, 4)} def create_openocd_args(interface, board): @@ -36,9 +35,12 @@ def create_openocd_args(interface, board): board_info = boards[board] args = [ "openocd", - "-f", f"interface/{interface}.cfg", - "-c", "add_script_search_dir openocd", - "-f", f"board/{board}.cfg", + "-f", + f"interface/{interface}.cfg", + "-c", + "add_script_search_dir openocd", + "-f", + f"board/{board}.cfg", ] return args @@ -53,11 +55,13 @@ def create_gdb_args(board, port, executable): board_info.gdb_variant, executable, # GDB can't autodetect these according to OpenOCD - "-ex", f"set remote hardware-breakpoint-limit {board_info.num_breakpoints}", - "-ex", f"set remote hardware-watchpoint-limit {board_info.num_watchpoints}", - + "-ex", + f"set remote hardware-breakpoint-limit {board_info.num_breakpoints}", + "-ex", + f"set remote hardware-watchpoint-limit {board_info.num_watchpoints}", # Connect to OpenOCD - "-ex", f"target extended-remote localhost:{port}", + "-ex", + f"target extended-remote localhost:{port}", ] return args @@ -79,7 +83,10 @@ def debug(interface, board, port, executable): openocd_args += ["-c", f"gdb_port {port}"] openocd = subprocess.Popen( - openocd_args, encoding="utf-8", stdout=subprocess.PIPE, stderr=subprocess.STDOUT + openocd_args, + encoding="utf-8", + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, ) # Wait for OpenOCD to start, it'll open a port for GDB connections @@ -134,7 +141,7 @@ def get_flash_file(board): / "zephyr" / board / "output" - / "zephyr.bin" + / "ec.bin" ).resolve() @@ -209,11 +216,15 @@ def main(): target_file = args.file.resolve() if args.command == "flash": - image_file = get_flash_file(args.board) if target_file == None else target_file + image_file = ( + get_flash_file(args.board) if target_file == None else target_file + ) flash(args.interface, args.board, image_file, args.verify) elif args.command == "debug": executable_file = ( - get_executable_file(args.board) if target_file == None else target_file + get_executable_file(args.board) + if target_file == None + else target_file ) debug(args.interface, args.board, args.port, executable_file) else: diff --git a/util/ec_panicinfo.c b/util/ec_panicinfo.c index 0294ac90de..0aa412bfe1 100644 --- a/util/ec_panicinfo.c +++ b/util/ec_panicinfo.c @@ -1,4 +1,4 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. +/* Copyright 2016 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -12,11 +12,10 @@ static void print_panic_reg(int regnum, const uint32_t *regs, int index) { - static const char * const regname[] = { - "r0 ", "r1 ", "r2 ", "r3 ", "r4 ", - "r5 ", "r6 ", "r7 ", "r8 ", "r9 ", - "r10", "r11", "r12", "sp ", "lr ", - "pc "}; + static const char *const regname[] = { "r0 ", "r1 ", "r2 ", "r3 ", + "r4 ", "r5 ", "r6 ", "r7 ", + "r8 ", "r9 ", "r10", "r11", + "r12", "sp ", "lr ", "pc " }; printf("%s:", regname[regnum]); if (regs) @@ -56,14 +55,15 @@ static int parse_panic_info_cm(const struct panic_data *pdata) ORIG_HANDLER } origin = ORIG_UNKNOWN; int i; - const char *panic_origins[3] = {"", "PROCESS", "HANDLER"}; + const char *panic_origins[3] = { "", "PROCESS", "HANDLER" }; printf("Saved panic data:%s\n", (pdata->flags & PANIC_DATA_FLAG_OLD_HOSTCMD ? "" : " (NEW)")); if (pdata->struct_version == 2) origin = ((lregs[11] & 0xf) == 1 || (lregs[11] & 0xf) == 9) ? - ORIG_HANDLER : ORIG_PROCESS; + ORIG_HANDLER : + ORIG_PROCESS; /* * In pdata struct, 'regs', which is allocated before 'frame', has @@ -75,8 +75,7 @@ static int parse_panic_info_cm(const struct panic_data *pdata) sregs = pdata->cm.frame - (pdata->struct_version == 1 ? 1 : 0); printf("=== %s EXCEPTION: %02x ====== xPSR: %08x ===\n", - panic_origins[origin], - lregs[1] & 0xff, sregs ? sregs[7] : -1); + panic_origins[origin], lregs[1] & 0xff, sregs ? sregs[7] : -1); for (i = 0; i < 4; ++i) print_panic_reg(i, sregs, i); for (i = 4; i < 10; ++i) @@ -104,14 +103,14 @@ static int parse_panic_info_nds32(const struct panic_data *pdata) (pdata->flags & PANIC_DATA_FLAG_OLD_HOSTCMD ? "" : " (NEW)")); printf("=== EXCEP: ITYPE=%x ===\n", itype); - printf("R0 %08x R1 %08x R2 %08x R3 %08x\n", - regs[0], regs[1], regs[2], regs[3]); - printf("R4 %08x R5 %08x R6 %08x R7 %08x\n", - regs[4], regs[5], regs[6], regs[7]); - printf("R8 %08x R9 %08x R10 %08x R15 %08x\n", - regs[8], regs[9], regs[10], regs[11]); - printf("FP %08x GP %08x LP %08x SP %08x\n", - regs[12], regs[13], regs[14], regs[15]); + printf("R0 %08x R1 %08x R2 %08x R3 %08x\n", regs[0], regs[1], + regs[2], regs[3]); + printf("R4 %08x R5 %08x R6 %08x R7 %08x\n", regs[4], regs[5], + regs[6], regs[7]); + printf("R8 %08x R9 %08x R10 %08x R15 %08x\n", regs[8], regs[9], + regs[10], regs[11]); + printf("FP %08x GP %08x LP %08x SP %08x\n", regs[12], regs[13], + regs[14], regs[15]); printf("IPC %08x IPSW %05x\n", ipc, ipsw); printf("SWID of ITYPE: %x\n", ((itype >> 16) & 0x7fff)); @@ -127,22 +126,22 @@ static int parse_panic_info_rv32i(const struct panic_data *pdata) mepc = pdata->riscv.mepc; printf("=== EXCEPTION: MCAUSE=%x ===\n", mcause); - printf("S11 %08x S10 %08x S9 %08x S8 %08x\n", - regs[0], regs[1], regs[2], regs[3]); - printf("S7 %08x S6 %08x S5 %08x S4 %08x\n", - regs[4], regs[5], regs[6], regs[7]); - printf("S3 %08x S2 %08x S1 %08x S0 %08x\n", - regs[8], regs[9], regs[10], regs[11]); - printf("T6 %08x T5 %08x T4 %08x T3 %08x\n", - regs[12], regs[13], regs[14], regs[15]); - printf("T2 %08x T1 %08x T0 %08x A7 %08x\n", - regs[16], regs[17], regs[18], regs[19]); - printf("A6 %08x A5 %08x A4 %08x A3 %08x\n", - regs[20], regs[21], regs[22], regs[23]); - printf("A2 %08x A1 %08x A0 %08x TP %08x\n", - regs[24], regs[25], regs[26], regs[27]); - printf("GP %08x RA %08x SP %08x MEPC %08x\n", - regs[28], regs[29], regs[30], mepc); + printf("S11 %08x S10 %08x S9 %08x S8 %08x\n", regs[0], regs[1], + regs[2], regs[3]); + printf("S7 %08x S6 %08x S5 %08x S4 %08x\n", regs[4], regs[5], + regs[6], regs[7]); + printf("S3 %08x S2 %08x S1 %08x S0 %08x\n", regs[8], regs[9], + regs[10], regs[11]); + printf("T6 %08x T5 %08x T4 %08x T3 %08x\n", regs[12], regs[13], + regs[14], regs[15]); + printf("T2 %08x T1 %08x T0 %08x A7 %08x\n", regs[16], regs[17], + regs[18], regs[19]); + printf("A6 %08x A5 %08x A4 %08x A3 %08x\n", regs[20], regs[21], + regs[22], regs[23]); + printf("A2 %08x A1 %08x A0 %08x TP %08x\n", regs[24], regs[25], + regs[26], regs[27]); + printf("GP %08x RA %08x SP %08x MEPC %08x\n", regs[28], regs[29], + regs[30], mepc); return 0; } @@ -153,7 +152,7 @@ int parse_panic_info(const char *data, size_t size) const size_t header_size = 4; /* Size of the panic information "trailer" (struct_size and magic). */ const size_t trailer_size = sizeof(struct panic_data) - - offsetof(struct panic_data, struct_size); + offsetof(struct panic_data, struct_size); struct panic_data pdata = { 0 }; size_t copy_size; @@ -164,7 +163,8 @@ int parse_panic_info(const char *data, size_t size) } if (size > sizeof(pdata)) { - fprintf(stderr, "WARNING: Panic data too large (%zd > %zd). " + fprintf(stderr, + "WARNING: Panic data too large (%zd > %zd). " "Following data may be incorrect!\n", size, sizeof(pdata)); copy_size = sizeof(pdata); @@ -175,20 +175,22 @@ int parse_panic_info(const char *data, size_t size) memcpy(&pdata, data, copy_size); /* Then copy the trailer in position. */ memcpy((char *)&pdata + (sizeof(struct panic_data) - trailer_size), - data + (size - trailer_size), trailer_size); + data + (size - trailer_size), trailer_size); /* * We only understand panic data with version <= 2. Warn the user * of higher versions. */ if (pdata.struct_version > 2) - fprintf(stderr, "WARNING: Unknown panic data version (%d). " + fprintf(stderr, + "WARNING: Unknown panic data version (%d). " "Following data may be incorrect!\n", pdata.struct_version); /* Validate magic number */ if (pdata.magic != PANIC_DATA_MAGIC) - fprintf(stderr, "WARNING: Incorrect panic magic (%d). " + fprintf(stderr, + "WARNING: Incorrect panic magic (%d). " "Following data may be incorrect!\n", pdata.magic); diff --git a/util/ec_panicinfo.h b/util/ec_panicinfo.h index c61cf797e6..0d7dba79f5 100644 --- a/util/ec_panicinfo.h +++ b/util/ec_panicinfo.h @@ -1,4 +1,4 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. +/* Copyright 2016 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ diff --git a/util/ec_parse_panicinfo.c b/util/ec_parse_panicinfo.c index 3a2da4590a..33c904b512 100644 --- a/util/ec_parse_panicinfo.c +++ b/util/ec_parse_panicinfo.c @@ -1,4 +1,4 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. +/* Copyright 2016 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -20,7 +20,7 @@ int main(int argc, char *argv[]) size_t size = 0; size_t read; - BUILD_ASSERT(sizeof(pdata) > sizeof(struct panic_data)*2); + BUILD_ASSERT(sizeof(pdata) > sizeof(struct panic_data) * 2); /* * Provide a minimal help message. @@ -36,7 +36,7 @@ int main(int argc, char *argv[]) } while (1) { - read = fread(&pdata[size], 1, sizeof(pdata)-size, stdin); + read = fread(&pdata[size], 1, sizeof(pdata) - size, stdin); if (read < 0) { fprintf(stderr, "Cannot read panicinfo from stdin.\n"); return 1; diff --git a/util/ec_sb_firmware_update.c b/util/ec_sb_firmware_update.c index a959cd6fe9..a2fb70d2a3 100644 --- a/util/ec_sb_firmware_update.c +++ b/util/ec_sb_firmware_update.c @@ -1,4 +1,4 @@ -/* Copyright 2014 The Chromium OS Authors. All rights reserved. +/* Copyright 2014 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -21,8 +21,8 @@ /* Subcommands: [check|update] */ enum { OP_UNKNOWN = 0, - OP_CHECK = 1, - OP_UPDATE = 2, + OP_CHECK = 1, + OP_UPDATE = 2, }; struct delay_value { @@ -33,54 +33,50 @@ struct delay_value { /* Default retry counter on errors */ #define SB_FW_UPDATE_DEFAULT_RETRY_CNT 3 /* Default delay value */ -#define SB_FW_UPDATE_DEFAULT_DELAY 1000 +#define SB_FW_UPDATE_DEFAULT_DELAY 1000 -#define DELAY_US_BEGIN 500000 -#define DELAY_US_END 1000000 -#define DELAY_US_BUSY 1000000 -#define DELAY_US_WRITE_END 50000 +#define DELAY_US_BEGIN 500000 +#define DELAY_US_END 1000000 +#define DELAY_US_BUSY 1000000 +#define DELAY_US_WRITE_END 50000 static struct delay_value sb_delays[] = { - {1, 100000}, - {2, 9000000}, - {4, 100000}, - {771, 30000}, - {2200, 10000}, - {0xFFFFFF, 50000}, + { 1, 100000 }, { 2, 9000000 }, { 4, 100000 }, + { 771, 30000 }, { 2200, 10000 }, { 0xFFFFFF, 50000 }, }; enum fw_update_state { - S0_READ_STATUS = 0, - S1_READ_INFO = 1, + S0_READ_STATUS = 0, + S1_READ_INFO = 1, S2_WRITE_PREPARE = 2, - S3_READ_STATUS = 3, - S4_WRITE_UPDATE = 4, - S5_READ_STATUS = 5, - S6_WRITE_BLOCK = 6, - S7_READ_STATUS = 7, - S8_WRITE_END = 8, - S9_READ_STATUS = 9, - S10_TERMINAL = 10 + S3_READ_STATUS = 3, + S4_WRITE_UPDATE = 4, + S5_READ_STATUS = 5, + S6_WRITE_BLOCK = 6, + S7_READ_STATUS = 7, + S8_WRITE_END = 8, + S9_READ_STATUS = 9, + S10_TERMINAL = 10 }; #define MAX_FW_IMAGE_NAME_SIZE 80 /* Firmware Update Control Flags */ enum { - F_AC_PRESENT = 0x1, /* AC Present */ + F_AC_PRESENT = 0x1, /* AC Present */ F_VERSION_CHECK = 0x2, /* do firmware version check */ - F_UPDATE = 0x4, /* do firmware update */ - F_NEED_UPDATE = 0x8, /* need firmware update */ - F_POWERD_DISABLED = 0x10, /* powerd is disabled */ - F_LFCC_ZERO = 0x20, /* last full charge is zero */ - F_BATT_DISCHARGE = 0x40 /* battery discharging */ + F_UPDATE = 0x4, /* do firmware update */ + F_NEED_UPDATE = 0x8, /* need firmware update */ + F_POWERD_DISABLED = 0x10, /* powerd is disabled */ + F_LFCC_ZERO = 0x20, /* last full charge is zero */ + F_BATT_DISCHARGE = 0x40 /* battery discharging */ }; struct fw_update_ctrl { uint32_t flags; /* fw update control flags */ - int size; /* size of battery firmware image */ - char *ptr; /* current read pointer of the firmware image */ - int offset; /* current block write offset */ + int size; /* size of battery firmware image */ + char *ptr; /* current read pointer of the firmware image */ + int offset; /* current block write offset */ struct sb_fw_header *fw_img_hdr; /*pointer to firmware image header*/ struct sb_fw_update_status status; struct sb_fw_update_info info; @@ -106,76 +102,59 @@ static uint32_t get_delay_value(uint32_t offset, uint32_t step_size) if (offset <= sb_delays[i].steps * step_size) return sb_delays[i].value; } - return sb_delays[sz-1].value; + return sb_delays[sz - 1].value; } -static void print_battery_firmware_image_hdr( - struct sb_fw_header *hdr) +static void print_battery_firmware_image_hdr(struct sb_fw_header *hdr) { printf("Latest Battery Firmware:\n"); - printf("\t%c%c%c%c hdr_ver:%04x major_minor:%04x\n", - hdr->signature[0], - hdr->signature[1], - hdr->signature[2], - hdr->signature[3], - hdr->hdr_version, hdr->pkg_version_major_minor); + printf("\t%c%c%c%c hdr_ver:%04x major_minor:%04x\n", hdr->signature[0], + hdr->signature[1], hdr->signature[2], hdr->signature[3], + hdr->hdr_version, hdr->pkg_version_major_minor); printf("\tmaker:0x%04x hwid:0x%04x fw_ver:0x%04x tbl_ver:0x%04x\n", - hdr->vendor_id, hdr->battery_type, hdr->fw_version, - hdr->data_table_version); + hdr->vendor_id, hdr->battery_type, hdr->fw_version, + hdr->data_table_version); printf("\tbinary offset:0x%08x size:0x%08x chk_sum:0x%02x\n", - hdr->fw_binary_offset, hdr->fw_binary_size, hdr->checksum); + hdr->fw_binary_offset, hdr->fw_binary_size, hdr->checksum); } static void print_info(struct sb_fw_update_info *info) { printf("\nCurrent Battery Firmware:\n"); printf("\tmaker:0x%04x hwid:0x%04x fw_ver:0x%04x tbl_ver:0x%04x\n", - info->maker_id, - info->hardware_id, - info->fw_version, - info->data_version); + info->maker_id, info->hardware_id, info->fw_version, + info->data_version); return; } static void print_status(struct sb_fw_update_status *sts) { printf("f_maker_id:%d f_hw_id:%d f_fw_ver:%d f_permnent:%d\n", - sts->v_fail_maker_id, - sts->v_fail_hw_id, - sts->v_fail_fw_version, - sts->v_fail_permanent); + sts->v_fail_maker_id, sts->v_fail_hw_id, sts->v_fail_fw_version, + sts->v_fail_permanent); printf("permanent failure:%d abnormal:%d fw_update:%d\n", - sts->permanent_failure, - sts->abnormal_condition, - sts->fw_update_supported); + sts->permanent_failure, sts->abnormal_condition, + sts->fw_update_supported); printf("fw_update_mode:%d fw_corrupted:%d cmd_reject:%d\n", - sts->fw_update_mode, - sts->fw_corrupted, - sts->cmd_reject); + sts->fw_update_mode, sts->fw_corrupted, sts->cmd_reject); printf("invliad data:%d fw_fatal_err:%d fec_err:%d busy:%d\n", - sts->invalid_data, - sts->fw_fatal_error, - sts->fec_error, - sts->busy); + sts->invalid_data, sts->fw_fatal_error, sts->fec_error, + sts->busy); printf("\n"); return; } /* @return 1 (True) if img signature is valid */ -static int check_battery_firmware_image_signature( - struct sb_fw_header *hdr) +static int check_battery_firmware_image_signature(struct sb_fw_header *hdr) { - return (hdr->signature[0] == 'B') && - (hdr->signature[1] == 'T') && - (hdr->signature[2] == 'F') && - (hdr->signature[3] == 'W'); + return (hdr->signature[0] == 'B') && (hdr->signature[1] == 'T') && + (hdr->signature[2] == 'F') && (hdr->signature[3] == 'W'); } /* @return 1 (True) if img checksum is valid. */ -static int check_battery_firmware_image_checksum( - struct sb_fw_header *hdr) +static int check_battery_firmware_image_checksum(struct sb_fw_header *hdr) { int i; uint8_t sum = 0; @@ -189,22 +168,19 @@ static int check_battery_firmware_image_checksum( } /* @return 1 (True) if img versions are ok to update. */ -static int check_battery_firmware_image_version( - struct sb_fw_header *hdr, - struct sb_fw_update_info *p) +static int check_battery_firmware_image_version(struct sb_fw_header *hdr, + struct sb_fw_update_info *p) { /* * If the battery firmware has a newer fw version * or a newer data table version, then it is ok to update. */ - return (hdr->fw_version > p->fw_version) - || (hdr->data_table_version > p->data_version); + return (hdr->fw_version > p->fw_version) || + (hdr->data_table_version > p->data_version); } - -static int check_battery_firmware_ids( - struct sb_fw_header *hdr, - struct sb_fw_update_info *p) +static int check_battery_firmware_ids(struct sb_fw_header *hdr, + struct sb_fw_update_info *p) { return ((hdr->vendor_id == p->maker_id) && (hdr->battery_type == p->hardware_id)); @@ -213,33 +189,30 @@ static int check_battery_firmware_ids( /* check_if_need_update_fw * @return 1 (true) if need; 0 (false) if not. */ -static int check_if_valid_fw( - struct sb_fw_header *hdr, - struct sb_fw_update_info *info) +static int check_if_valid_fw(struct sb_fw_header *hdr, + struct sb_fw_update_info *info) { - return check_battery_firmware_image_signature(hdr) - && check_battery_firmware_ids(hdr, info) - && check_battery_firmware_image_checksum(hdr); + return check_battery_firmware_image_signature(hdr) && + check_battery_firmware_ids(hdr, info) && + check_battery_firmware_image_checksum(hdr); } /* check_if_need_update_fw * @return 1 (true) if need; 0 (false) if not. */ -static int check_if_need_update_fw( - struct sb_fw_header *hdr, - struct sb_fw_update_info *info) +static int check_if_need_update_fw(struct sb_fw_header *hdr, + struct sb_fw_update_info *info) { return check_battery_firmware_image_version(hdr, info); } static void log_msg(struct fw_update_ctrl *fw_update, - enum fw_update_state state, const char *msg) + enum fw_update_state state, const char *msg) { - sprintf(fw_update->msg, - "Battery Firmware Updater State:%d %s", state, msg); + sprintf(fw_update->msg, "Battery Firmware Updater State:%d %s", state, + msg); } - static char *read_fw_image(struct fw_update_ctrl *fw_update) { int size; @@ -259,11 +232,11 @@ static char *read_fw_image(struct fw_update_ctrl *fw_update) print_battery_firmware_image_hdr(fw_update->fw_img_hdr); if (fw_update->fw_img_hdr->fw_binary_offset >= fw_update->size || - fw_update->size < 256) { + fw_update->size < 256) { printf("Load Firmware Image[%s] Error offset:%d size:%d\n", - fw_update->image_name, - fw_update->fw_img_hdr->fw_binary_offset, - fw_update->size); + fw_update->image_name, + fw_update->fw_img_hdr->fw_binary_offset, + fw_update->size); free(buf); return NULL; } @@ -284,9 +257,9 @@ static int get_status(struct sb_fw_update_status *status) param->hdr.subcmd = EC_SB_FW_UPDATE_STATUS; do { usleep(SB_FW_UPDATE_DEFAULT_DELAY); - rv = ec_command(EC_CMD_SB_FW_UPDATE, 0, - param, sizeof(struct ec_sb_fw_update_header), - resp, SB_FW_UPDATE_CMD_STATUS_SIZE); + rv = ec_command(EC_CMD_SB_FW_UPDATE, 0, param, + sizeof(struct ec_sb_fw_update_header), resp, + SB_FW_UPDATE_CMD_STATUS_SIZE); } while ((rv < 0) && (cnt++ < SB_FW_UPDATE_DEFAULT_RETRY_CNT)); if (rv < 0) { @@ -312,9 +285,9 @@ static int get_info(struct sb_fw_update_info *info) param->hdr.subcmd = EC_SB_FW_UPDATE_INFO; do { usleep(SB_FW_UPDATE_DEFAULT_DELAY); - rv = ec_command(EC_CMD_SB_FW_UPDATE, 0, - param, sizeof(struct ec_sb_fw_update_header), - resp, SB_FW_UPDATE_CMD_INFO_SIZE); + rv = ec_command(EC_CMD_SB_FW_UPDATE, 0, param, + sizeof(struct ec_sb_fw_update_header), resp, + SB_FW_UPDATE_CMD_INFO_SIZE); } while ((rv < 0) && (cnt++ < SB_FW_UPDATE_DEFAULT_RETRY_CNT)); if (rv < 0) { @@ -334,8 +307,8 @@ static int send_subcmd(int subcmd) (struct ec_params_sb_fw_update *)ec_outbuf; param->hdr.subcmd = subcmd; - rv = ec_command(EC_CMD_SB_FW_UPDATE, 0, - param, sizeof(struct ec_sb_fw_update_header), NULL, 0); + rv = ec_command(EC_CMD_SB_FW_UPDATE, 0, param, + sizeof(struct ec_sb_fw_update_header), NULL, 0); if (rv < 0) { printf("Firmware Update subcmd:%d Error\n", subcmd); return -EC_RES_ERROR; @@ -343,22 +316,21 @@ static int send_subcmd(int subcmd) return EC_RES_SUCCESS; } -static int write_block(struct fw_update_ctrl *fw_update, - int offset, int bsize) +static int write_block(struct fw_update_ctrl *fw_update, int offset, int bsize) { int rv; struct ec_params_sb_fw_update *param = (struct ec_params_sb_fw_update *)ec_outbuf; - memcpy(param->write.data, fw_update->ptr+offset, bsize); + memcpy(param->write.data, fw_update->ptr + offset, bsize); param->hdr.subcmd = EC_SB_FW_UPDATE_WRITE; - rv = ec_command(EC_CMD_SB_FW_UPDATE, 0, - param, sizeof(struct ec_params_sb_fw_update), NULL, 0); + rv = ec_command(EC_CMD_SB_FW_UPDATE, 0, param, + sizeof(struct ec_params_sb_fw_update), NULL, 0); if (rv < 0) { printf("Firmware Update Write Error ptr:%p offset@%x\n", - fw_update->ptr, offset); + fw_update->ptr, offset); return -EC_RES_ERROR; } return EC_RES_SUCCESS; @@ -373,7 +345,7 @@ static void dump_data(char *data, int offset, int size) printf("Offset:0x%X\n", offset); for (i = 0; i < size; i++) { - if ((i%16) == 0) + if ((i % 16) == 0) printf("\n"); printf("%02X ", data[i]); } @@ -397,8 +369,8 @@ static enum fw_update_state s0_read_status(struct fw_update_ctrl *fw_update) return S10_TERMINAL; } - if (!((fw_update->status.abnormal_condition == 0) - && (fw_update->status.fw_update_supported == 1))) { + if (!((fw_update->status.abnormal_condition == 0) && + (fw_update->status.fw_update_supported == 1))) { return S0_READ_STATUS; } @@ -409,8 +381,8 @@ static enum fw_update_state s0_read_status(struct fw_update_ctrl *fw_update) return S1_READ_INFO; } -static enum fw_update_state s1_read_battery_info( - struct fw_update_ctrl *fw_update) +static enum fw_update_state +s1_read_battery_info(struct fw_update_ctrl *fw_update) { int rv; @@ -431,9 +403,8 @@ static enum fw_update_state s1_read_battery_info( print_info(&fw_update->info); sprintf(fw_update->image_name, - "/lib/firmware/battery/maker.%04x.hwid.%04x.bin", - fw_update->info.maker_id, - fw_update->info.hardware_id); + "/lib/firmware/battery/maker.%04x.hwid.%04x.bin", + fw_update->info.maker_id, fw_update->info.hardware_id); if (NULL == read_fw_image(fw_update)) { fw_update->rv = 0; @@ -520,7 +491,6 @@ static enum fw_update_state s3_read_status(struct fw_update_ctrl *fw_update) return S10_TERMINAL; } return S4_WRITE_UPDATE; - } static enum fw_update_state s4_write_update(struct fw_update_ctrl *fw_update) @@ -589,7 +559,7 @@ static enum fw_update_state s6_write_block(struct fw_update_ctrl *fw_update) * Add more delays after the last few (3) block writes. * 3 is chosen based on current test results. */ - if ((offset + 3*fw_update->step_size) >= fw_update->size) + if ((offset + 3 * fw_update->step_size) >= fw_update->size) usleep(DELAY_US_WRITE_END); usleep(get_delay_value(offset, fw_update->step_size)); @@ -609,38 +579,36 @@ static enum fw_update_state s7_read_status(struct fw_update_ctrl *fw_update) usleep(SB_FW_UPDATE_DEFAULT_DELAY); rv = get_status(&fw_update->status); if (rv) { - dump_data(fw_update->ptr+offset, offset, bsize); + dump_data(fw_update->ptr + offset, offset, bsize); print_status(&fw_update->status); fw_update->rv = -1; log_msg(fw_update, S7_READ_STATUS, "Interface Error"); return S10_TERMINAL; } } while (fw_update->status.busy && - (cnt++ < SB_FW_UPDATE_DEFAULT_RETRY_CNT)); + (cnt++ < SB_FW_UPDATE_DEFAULT_RETRY_CNT)); if (fw_update->status.fec_error) { - dump_data(fw_update->ptr+offset, offset, bsize); + dump_data(fw_update->ptr + offset, offset, bsize); print_status(&fw_update->status); fw_update->rv = 0; return S6_WRITE_BLOCK; } if (fw_update->status.permanent_failure || - fw_update->status.v_fail_permanent) { - dump_data(fw_update->ptr+offset, offset, bsize); + fw_update->status.v_fail_permanent) { + dump_data(fw_update->ptr + offset, offset, bsize); print_status(&fw_update->status); fw_update->rv = -1; log_msg(fw_update, S7_READ_STATUS, "Battery Permanent Error"); return S8_WRITE_END; } if (fw_update->status.v_fail_maker_id || - fw_update->status.v_fail_hw_id || - fw_update->status.v_fail_fw_version || - fw_update->status.fw_corrupted || - fw_update->status.cmd_reject || - fw_update->status.invalid_data || - fw_update->status.fw_fatal_error) { - - dump_data(fw_update->ptr+offset, offset, bsize); + fw_update->status.v_fail_hw_id || + fw_update->status.v_fail_fw_version || + fw_update->status.fw_corrupted || fw_update->status.cmd_reject || + fw_update->status.invalid_data || + fw_update->status.fw_fatal_error) { + dump_data(fw_update->ptr + offset, offset, bsize); print_status(&fw_update->status); fw_update->rv = 0; return S1_READ_INFO; @@ -651,7 +619,6 @@ static enum fw_update_state s7_read_status(struct fw_update_ctrl *fw_update) return S6_WRITE_BLOCK; } - static enum fw_update_state s8_write_end(struct fw_update_ctrl *fw_update) { int rv; @@ -686,8 +653,8 @@ static enum fw_update_state s9_read_status(struct fw_update_ctrl *fw_update) log_msg(fw_update, S9_READ_STATUS, "Interface Error"); return S10_TERMINAL; } - if ((fw_update->status.fw_update_mode == 1) - || (fw_update->status.busy == 1)) { + if ((fw_update->status.fw_update_mode == 1) || + (fw_update->status.busy == 1)) { usleep(SB_FW_UPDATE_DEFAULT_DELAY); fw_update->busy_retry_cnt--; return S9_READ_STATUS; @@ -697,22 +664,13 @@ static enum fw_update_state s9_read_status(struct fw_update_ctrl *fw_update) return S10_TERMINAL; } - typedef enum fw_update_state (*fw_state_func)(struct fw_update_ctrl *fw_update); -fw_state_func state_table[] = { - s0_read_status, - s1_read_battery_info, - s2_write_prepare, - s3_read_status, - s4_write_update, - s5_read_status, - s6_write_block, - s7_read_status, - s8_write_end, - s9_read_status -}; - +fw_state_func state_table[] = { s0_read_status, s1_read_battery_info, + s2_write_prepare, s3_read_status, + s4_write_update, s5_read_status, + s6_write_block, s7_read_status, + s8_write_end, s9_read_status }; /** * Update Smart Battery Firmware @@ -740,13 +698,13 @@ static int ec_sb_firmware_update(struct fw_update_ctrl *fw_update) return fw_update->rv; } -#define GEC_LOCK_TIMEOUT_SECS 30 /* 30 secs */ +#define GEC_LOCK_TIMEOUT_SECS 30 /* 30 secs */ void usage(char *argv[]) { printf("Usage: %s [check|update]\n" - " check: check if AC Adaptor is connected.\n" - " update: trigger battery firmware update.\n", - argv[0]); + " check: check if AC Adaptor is connected.\n" + " update: trigger battery firmware update.\n", + argv[0]); } int main(int argc, char *argv[]) @@ -827,10 +785,8 @@ int main(int argc, char *argv[]) fw_update.flags |= F_VERSION_CHECK; rv = ec_sb_firmware_update(&fw_update); - printf("Battery Firmware Update:0x%02x %s\n%s\n", - fw_update.flags, - ((rv) ? "FAIL " : " "), - fw_update.msg); + printf("Battery Firmware Update:0x%02x %s\n%s\n", fw_update.flags, + ((rv) ? "FAIL " : " "), fw_update.msg); /* Update battery firmware update interface to be protected */ if (!(fw_update.flags & F_NEED_UPDATE)) diff --git a/util/ec_sb_firmware_update.h b/util/ec_sb_firmware_update.h index 5bddebaf4a..2757dca9a5 100644 --- a/util/ec_sb_firmware_update.h +++ b/util/ec_sb_firmware_update.h @@ -1,4 +1,4 @@ -/* Copyright 2014 The Chromium OS Authors. All rights reserved. +/* Copyright 2014 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -55,7 +55,7 @@ struct sb_fw_header { uint16_t data_table_version; /* E F */ uint32_t fw_binary_offset; /*0x10 0x11 0x12 0x13 */ uint32_t fw_binary_size; /* 0x14 0x15 0x16 0x17 */ - uint8_t checksum; /* 0x18 */ + uint8_t checksum; /* 0x18 */ }; /** @@ -63,25 +63,25 @@ struct sb_fw_header { * Firmware Update Status */ struct sb_fw_update_status { - uint16_t v_fail_maker_id:1; /* b0 */ - uint16_t v_fail_hw_id:1; /* b1 */ - uint16_t v_fail_fw_version:1; /* b2 */ - uint16_t v_fail_permanent:1; /* b3 */ + uint16_t v_fail_maker_id : 1; /* b0 */ + uint16_t v_fail_hw_id : 1; /* b1 */ + uint16_t v_fail_fw_version : 1; /* b2 */ + uint16_t v_fail_permanent : 1; /* b3 */ - uint16_t rsvd5:1; /* b4 */ - uint16_t permanent_failure:1; /* b5 */ - uint16_t abnormal_condition:1; /* b6 */ - uint16_t fw_update_supported:1; /* b7 */ + uint16_t rsvd5 : 1; /* b4 */ + uint16_t permanent_failure : 1; /* b5 */ + uint16_t abnormal_condition : 1; /* b6 */ + uint16_t fw_update_supported : 1; /* b7 */ - uint16_t fw_update_mode:1; /* b8 */ - uint16_t fw_corrupted:1; /* b9 */ - uint16_t cmd_reject:1; /* b10 */ - uint16_t invalid_data:1; /* b11 */ + uint16_t fw_update_mode : 1; /* b8 */ + uint16_t fw_corrupted : 1; /* b9 */ + uint16_t cmd_reject : 1; /* b10 */ + uint16_t invalid_data : 1; /* b11 */ - uint16_t fw_fatal_error:1; /* b12 */ - uint16_t fec_error:1; /* b13 */ - uint16_t busy:1; /* b14 */ - uint16_t rsvd15:1; /* b15 */ + uint16_t fw_fatal_error : 1; /* b12 */ + uint16_t fec_error : 1; /* b13 */ + uint16_t busy : 1; /* b14 */ + uint16_t rsvd15 : 1; /* b15 */ } __packed; /** @@ -90,22 +90,22 @@ struct sb_fw_update_status { * sequence:=b1,b0,b3,b2,b5,b5,b7,b6 */ struct sb_fw_update_info { - uint16_t maker_id; /* b0, b1 */ + uint16_t maker_id; /* b0, b1 */ uint16_t hardware_id; /* b2, b3 */ - uint16_t fw_version; /* b4, b5 */ - uint16_t data_version;/* b6, b7 */ + uint16_t fw_version; /* b4, b5 */ + uint16_t data_version; /* b6, b7 */ } __packed; /** * smart.battery.maker.id */ enum sb_maker_id { - sb_maker_id_lgc = 0x0001, /* b0=0; b1=1 */ + sb_maker_id_lgc = 0x0001, /* b0=0; b1=1 */ sb_maker_id_panasonic = 0x0002, - sb_maker_id_sanyo = 0x0003, - sb_maker_id_sony = 0x0004, - sb_maker_id_simplo = 0x0005, - sb_maker_id_celxpert = 0x0006, + sb_maker_id_sanyo = 0x0003, + sb_maker_id_sony = 0x0004, + sb_maker_id_simplo = 0x0005, + sb_maker_id_celxpert = 0x0006, }; /* @@ -119,8 +119,8 @@ enum sb_maker_id { * case 5. If battery interface is busy, retry < 10 times. * Delay 1 second between retries. */ -#define SB_FW_UPDATE_ERROR_RETRY_CNT 2 -#define SB_FW_UPDATE_FEC_ERROR_RETRY_CNT 2 +#define SB_FW_UPDATE_ERROR_RETRY_CNT 2 +#define SB_FW_UPDATE_FEC_ERROR_RETRY_CNT 2 #define SB_FW_UPDATE_BUSY_ERROR_RETRY_CNT 4 #endif diff --git a/util/ecst.c b/util/ecst.c index 8d0ce940d6..2c3150c34a 100644 --- a/util/ecst.c +++ b/util/ecst.c @@ -1,5 +1,5 @@ /* - * Copyright 2015 The Chromium OS Authors. All rights reserved. + * Copyright 2015 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -39,20 +39,21 @@ int is_mrider15 = FALSE; /* Chips information, RAM start address and RAM size. */ struct chip_info chip_info[] = { - [NPCX5M5G] = {NPCX5M5G_RAM_ADDR, NPCX5M5G_RAM_SIZE}, - [NPCX5M6G] = {NPCX5M6G_RAM_ADDR, NPCX5M6G_RAM_SIZE}, - [NPCX7M5] = {NPCX7M5X_RAM_ADDR, NPCX7M5X_RAM_SIZE}, - [NPCX7M6] = {NPCX7M6X_RAM_ADDR, NPCX7M6X_RAM_SIZE}, - [NPCX7M7] = {NPCX7M7X_RAM_ADDR, NPCX7M7X_RAM_SIZE}, - [NPCX9M3] = {NPCX9M3X_RAM_ADDR, NPCX9M3X_RAM_SIZE}, - [NPCX9M6] = {NPCX9M6X_RAM_ADDR, NPCX9M6X_RAM_SIZE}, + [NPCX5M5G] = { NPCX5M5G_RAM_ADDR, NPCX5M5G_RAM_SIZE }, + [NPCX5M6G] = { NPCX5M6G_RAM_ADDR, NPCX5M6G_RAM_SIZE }, + [NPCX7M5] = { NPCX7M5X_RAM_ADDR, NPCX7M5X_RAM_SIZE }, + [NPCX7M6] = { NPCX7M6X_RAM_ADDR, NPCX7M6X_RAM_SIZE }, + [NPCX7M7] = { NPCX7M7X_RAM_ADDR, NPCX7M7X_RAM_SIZE }, + [NPCX9M3] = { NPCX9M3X_RAM_ADDR, NPCX9M3X_RAM_SIZE }, + [NPCX9M6] = { NPCX9M6X_RAM_ADDR, NPCX9M6X_RAM_SIZE }, }; BUILD_ASSERT(ARRAY_SIZE(chip_info) == NPCX_CHIP_RAM_VAR_NONE); /* Support chips name strings */ -const char *supported_chips = "npcx5m5g, npcx5m6g, npcx7m5g, npcx7m6g, " - "npcx7m6f, npcx7m6fb, npcx7m6fc, npcx7m7fc, npcx7m7wb, " - "npcx7m7wc, npcx9m3f or npcx9m6f"; +const char *supported_chips = + "npcx5m5g, npcx5m6g, npcx7m5g, npcx7m6g, " + "npcx7m6f, npcx7m6fb, npcx7m6fc, npcx7m7fc, npcx7m7wb, " + "npcx7m7wc, npcx9m3f or npcx9m6f"; static unsigned int calc_api_csum_bin(void); static unsigned int initialize_crc_32(void); @@ -70,16 +71,17 @@ static unsigned int finalize_crc_32(unsigned int crc); * and returns FALSE. */ static int splice_into_path(char *result, const char *path, int resultsz, - const char *prefix) { + const char *prefix) +{ char *last_delim, *result_last_delim; if (strlen(path) + strlen(prefix) + 1 > resultsz) { my_printf(TERR, - "\n\nfilename '%s' with prefix '%s' too long\n\n", - path, prefix); + "\n\nfilename '%s' with prefix '%s' too long\n\n", + path, prefix); my_printf(TINF, - "\n\n%zu + %zu + 1 needs to fit in %d bytes\n\n", - strlen(path), strlen(prefix), resultsz); + "\n\n%zu + %zu + 1 needs to fit in %d bytes\n\n", + strlen(path), strlen(prefix), resultsz); return FALSE; } @@ -124,7 +126,7 @@ static enum npcx_chip_ram_variant chip_to_ram_var(const char *chip_name) else if (str_cmp_no_case(chip_name, "npcx7m6fc") == 0) return NPCX7M6; else if (str_cmp_no_case(chip_name, "npcx7m6g") == 0) - return NPCX7M6; + return NPCX7M6; else if (str_cmp_no_case(chip_name, "npcx7m5g") == 0) return NPCX7M5; else if (str_cmp_no_case(chip_name, "npcx5m6g") == 0) @@ -149,7 +151,6 @@ static enum npcx_chip_ram_variant chip_to_ram_var(const char *chip_name) int main(int argc, char *argv[]) { - int mode_choose = FALSE; /* Do we get a bin File? */ int main_fw_hdr_flag = FALSE; @@ -160,7 +161,7 @@ int main(int argc, char *argv[]) /* Following variables: common to all modes */ int main_status = TRUE; - unsigned int main_temp = 0L; + unsigned int main_temp = 0L; char main_str_temp[TMP_STR_SIZE]; char *end_ptr; @@ -189,17 +190,15 @@ int main(int argc, char *argv[]) g_verbose = NO_VERBOSE; g_ram_start_address = chip_info[DEFAULT_CHIP].ram_addr; - g_ram_size = chip_info[DEFAULT_CHIP].ram_size; + g_ram_size = chip_info[DEFAULT_CHIP].ram_size; /* Set default values */ g_calc_type = CALC_TYPE_NONE; bin_params.spi_max_clk = SPI_MAX_CLOCK_DEFAULT; bin_params.spi_clk_ratio = 0x00; bin_params.spi_read_mode = SPI_READ_MODE_DEFAULT; - bin_params.fw_load_addr = - chip_info[DEFAULT_CHIP].ram_addr; - bin_params.fw_ep = - chip_info[DEFAULT_CHIP].ram_addr; + bin_params.fw_load_addr = chip_info[DEFAULT_CHIP].ram_addr; + bin_params.fw_ep = chip_info[DEFAULT_CHIP].ram_addr; bin_params.fw_err_detec_s_addr = FW_CRC_START_ADDR; bin_params.fw_err_detec_e_addr = FW_CRC_START_ADDR; bin_params.flash_size = FLASH_SIZE_DEFAULT; @@ -234,20 +233,18 @@ int main(int argc, char *argv[]) else if (str_cmp_no_case(hdr_args[arg_ind], "-vv") == 0) g_verbose = SUPER_VERBOSE; - else if (str_cmp_no_case(hdr_args[arg_ind], - "-mode") == 0) { + else if (str_cmp_no_case(hdr_args[arg_ind], "-mode") == 0) { mode_choose = TRUE; arg_ind++; if ((hdr_args[arg_ind] == NULL) || - (sscanf(hdr_args[arg_ind], - "%s", main_str_temp) != 1)) { + (sscanf(hdr_args[arg_ind], "%s", main_str_temp) != + 1)) { my_printf(TERR, "\nCannot read operation mode"); my_printf(TERR, ", bt, bh or api. !\n"); main_status = FALSE; } else { /* bt, bh and api should not coexist */ - if (main_fw_hdr_flag || - main_api_flag || + if (main_fw_hdr_flag || main_api_flag || main_hdr_flag) { my_printf(TERR, "\nOperation modes bt"); my_printf(TERR, ", bh, and api should"); @@ -257,8 +254,8 @@ int main(int argc, char *argv[]) if (str_cmp_no_case(main_str_temp, "bt") == 0) main_fw_hdr_flag = TRUE; - else if (str_cmp_no_case(main_str_temp, - "bh") == 0) + else if (str_cmp_no_case(main_str_temp, "bh") == + 0) main_hdr_flag = TRUE; else if (str_cmp_no_case(main_str_temp, "api") == 0) @@ -266,8 +263,8 @@ int main(int argc, char *argv[]) else { my_printf(TERR, "\nInvalid operation mode "); - my_printf(TERR, - "(%s)\n", main_str_temp); + my_printf(TERR, "(%s)\n", + main_str_temp); main_status = FALSE; } } @@ -276,11 +273,10 @@ int main(int argc, char *argv[]) else if (str_cmp_no_case(hdr_args[arg_ind], "-chip") == 0) { arg_ind++; if ((hdr_args[arg_ind] == NULL) || - (sscanf(hdr_args[arg_ind], - "%s", - main_str_temp) != 1)) { + (sscanf(hdr_args[arg_ind], "%s", main_str_temp) != + 1)) { my_printf(TERR, "\nCannot read chip name %s.\n", - supported_chips); + supported_chips); main_status = FALSE; } else { enum npcx_chip_ram_variant ram_variant; @@ -291,41 +287,38 @@ int main(int argc, char *argv[]) "\nInvalid chip name (%s) ", main_str_temp); my_printf(TERR, ", it should be %s.\n", - supported_chips); + supported_chips); main_status = FALSE; break; } - if ((bin_params.bin_params - & BIN_FW_LOAD_START_ADDR) == - 0x00000000) + if ((bin_params.bin_params & + BIN_FW_LOAD_START_ADDR) == 0x00000000) bin_params.fw_load_addr = - chip_info[ram_variant].ram_addr; + chip_info[ram_variant].ram_addr; - if ((bin_params.bin_params - & BIN_FW_ENTRY_POINT) == - 0x00000000) + if ((bin_params.bin_params & + BIN_FW_ENTRY_POINT) == 0x00000000) bin_params.fw_ep = - chip_info[ram_variant].ram_addr; + chip_info[ram_variant].ram_addr; g_ram_start_address = chip_info[ram_variant].ram_addr; - g_ram_size = - chip_info[ram_variant].ram_size; + g_ram_size = chip_info[ram_variant].ram_size; if ((ram_variant == NPCX5M5G) || - (ram_variant == NPCX5M6G)) { + (ram_variant == NPCX5M6G)) { is_mrider15 = TRUE; } } - /* -argfile Read argument file. File name must be after it.*/ - } else if (str_cmp_no_case(hdr_args[arg_ind], - "-argfile") == 0) { + /* -argfile Read argument file. File name must be after + * it.*/ + } else if (str_cmp_no_case(hdr_args[arg_ind], "-argfile") == + 0) { arg_ind++; if (arg_ind < arg_num) { - strncpy(arg_file_name, - hdr_args[arg_ind], - sizeof(arg_file_name) - 1); + strncpy(arg_file_name, hdr_args[arg_ind], + sizeof(arg_file_name) - 1); arg_file_pointer = fopen(arg_file_name, "rt"); if (arg_file_pointer == NULL) { my_printf(TERR, @@ -340,16 +333,15 @@ int main(int argc, char *argv[]) (tmp_ind + arg_ind + 1) < arg_num; tmp_ind++) strncpy(tmp_hdr_args[tmp_ind], - hdr_args - [tmp_ind+arg_ind+1], + hdr_args[tmp_ind + + arg_ind + 1], ARG_SIZE); tmp_arg_num = tmp_ind; /* Read arguments from file to array */ for (arg_ind++; - fscanf(arg_file_pointer, - "%s", + fscanf(arg_file_pointer, "%s", hdr_args[arg_ind]) == 1; arg_ind++) ; @@ -359,9 +351,9 @@ int main(int argc, char *argv[]) /* Copy back the restored arguments. */ for (tmp_ind = 0; - (tmp_ind < tmp_arg_num) && - (arg_ind < MAX_ARGS); - tmp_ind++) { + (tmp_ind < tmp_arg_num) && + (arg_ind < MAX_ARGS); + tmp_ind++) { strncpy(hdr_args[arg_ind++], tmp_hdr_args[tmp_ind], ARG_SIZE); @@ -379,120 +371,113 @@ int main(int argc, char *argv[]) } else if (str_cmp_no_case(hdr_args[arg_ind], "-i") == 0) { arg_ind++; if (arg_ind < arg_num) { - strncpy(input_file_name, - hdr_args[arg_ind], - sizeof(input_file_name) - 1); + strncpy(input_file_name, hdr_args[arg_ind], + sizeof(input_file_name) - 1); } else { my_printf(TERR, "\nMissing Input File Name\n"); main_status = FALSE; } - /* -o Get output file name. */ + /* -o Get output file name. */ } else if (str_cmp_no_case(hdr_args[arg_ind], "-o") == 0) { arg_ind++; if (arg_ind < arg_num) { - strncpy(output_file_name, - hdr_args[arg_ind], + strncpy(output_file_name, hdr_args[arg_ind], sizeof(output_file_name) - 1); } else { my_printf(TERR, "\nMissing Output File Name.\n"); main_status = FALSE; } - /* -usearmrst get FW entry point from FW image offset 4.*/ - } else if (str_cmp_no_case(hdr_args[arg_ind], - "-usearmrst") == 0) { - if ((bin_params.bin_params & - BIN_FW_ENTRY_POINT) != 0x00000000) { + /* -usearmrst get FW entry point from FW image + * offset 4.*/ + } else if (str_cmp_no_case(hdr_args[arg_ind], "-usearmrst") == + 0) { + if ((bin_params.bin_params & BIN_FW_ENTRY_POINT) != + 0x00000000) { my_printf(TERR, "\n-usearmrst not allowed, "); my_printf(TERR, "FW entry point already set "); my_printf(TERR, "using -fwep !\n"); main_status = FALSE; } else - bin_params.bin_params |= - BIN_FW_USER_ARM_RESET; - /* -nohcrs disable header CRC*/ + bin_params.bin_params |= BIN_FW_USER_ARM_RESET; + /* -nohcrs disable header CRC*/ } else if (str_cmp_no_case(hdr_args[arg_ind], "-nohcrc") == 0) - bin_params.bin_params |= - BIN_FW_HDR_CRC_DISABLE; + bin_params.bin_params |= BIN_FW_HDR_CRC_DISABLE; /* -ph merg header in BIN file. */ else if (str_cmp_no_case(hdr_args[arg_ind], "-ph") == 0) { - bin_params.bin_params |= - BIN_FW_HDR_OFFSET; - if ((strlen(hdr_args[arg_ind+1]) == 0) || - (sscanf(hdr_args[arg_ind+1], - "%x", - &main_temp) != 1)) + bin_params.bin_params |= BIN_FW_HDR_OFFSET; + if ((strlen(hdr_args[arg_ind + 1]) == 0) || + (sscanf(hdr_args[arg_ind + 1], "%x", &main_temp) != + 1)) bin_params.fw_hdr_offset = 0; else { arg_ind++; bin_params.fw_hdr_offset = main_temp; } - /* -spimaxclk Get SPI flash max clock. */ - } else if (str_cmp_no_case(hdr_args[arg_ind], - "-spimaxclk") == 0) { + /* -spimaxclk Get SPI flash max clock. */ + } else if (str_cmp_no_case(hdr_args[arg_ind], "-spimaxclk") == + 0) { arg_ind++; if ((hdr_args[arg_ind] == NULL) || - (sscanf(hdr_args[arg_ind], - "%d", &main_temp) != 1)) { + (sscanf(hdr_args[arg_ind], "%d", &main_temp) != + 1)) { my_printf(TERR, "\nCannot read SPI Flash Max"); my_printf(TERR, " Clock !\n"); main_status = FALSE; } else bin_params.spi_max_clk = - (unsigned char) main_temp; - /* -spiclkratio Get SPI flash max clock ratio. */ - } else if (str_cmp_no_case(hdr_args[arg_ind], - "-spiclkratio") == 0) { + (unsigned char)main_temp; + /* -spiclkratio Get SPI flash max clock ratio. */ + } else if (str_cmp_no_case(hdr_args[arg_ind], "-spiclkratio") == + 0) { arg_ind++; if ((hdr_args[arg_ind] == NULL) || - (sscanf(hdr_args[arg_ind], - "%d", &main_temp) != 1)) { + (sscanf(hdr_args[arg_ind], "%d", &main_temp) != + 1)) { my_printf(TERR, "\nCannot read SPI Clock Ratio\n"); main_status = FALSE; } else bin_params.spi_clk_ratio = - (unsigned char)main_temp; + (unsigned char)main_temp; - /* spireadmode get SPI read mode. */ - } else if (str_cmp_no_case(hdr_args[arg_ind], - "-spireadmode") == 0) { + /* spireadmode get SPI read mode. */ + } else if (str_cmp_no_case(hdr_args[arg_ind], "-spireadmode") == + 0) { arg_ind++; if ((hdr_args[arg_ind] == NULL) || - (sscanf(hdr_args[arg_ind], - "%20s", - main_str_temp) != 1)) { + (sscanf(hdr_args[arg_ind], "%20s", main_str_temp) != + 1)) { my_printf(TERR, "\nCannot read SPI Flash"); my_printf(TERR, " Read Mode !\n"); main_status = FALSE; } else { if (str_cmp_no_case(main_str_temp, - SPI_NORMAL_MODE_VAL) == 0) + SPI_NORMAL_MODE_VAL) == 0) bin_params.spi_read_mode = - (unsigned char) SPI_NORMAL_MODE; + (unsigned char)SPI_NORMAL_MODE; else if (str_cmp_no_case(main_str_temp, - SPI_SINGLE_MODE_VAL) == 0) + SPI_SINGLE_MODE_VAL) == + 0) bin_params.spi_read_mode = - (unsigned char) - SPI_SINGLE_MODE; + (unsigned char)SPI_SINGLE_MODE; else if (str_cmp_no_case(main_str_temp, - SPI_DUAL_MODE_VAL) == 0) + SPI_DUAL_MODE_VAL) == + 0) bin_params.spi_read_mode = - (unsigned char) - SPI_DUAL_MODE; + (unsigned char)SPI_DUAL_MODE; else if (str_cmp_no_case(main_str_temp, - SPI_QUAD_MODE_VAL) == 0) + SPI_QUAD_MODE_VAL) == + 0) bin_params.spi_read_mode = - (unsigned char) - SPI_QUAD_MODE; + (unsigned char)SPI_QUAD_MODE; else { my_printf(TERR, "\nInvalid SPI Flash Read "); my_printf(TERR, "Mode (%s), it should be ", main_str_temp); - my_printf(TERR, - "normal, singleMode, "); + my_printf(TERR, "normal, singleMode, "); my_printf(TERR, "dualMode or quadMode !\n"); main_status = FALSE; @@ -508,95 +493,88 @@ int main(int argc, char *argv[]) bin_params.bin_params |= BIN_FW_CRC_DISABLE; /* -fwloadaddr, Get the FW load address. */ - else if (str_cmp_no_case(hdr_args[arg_ind], - "-fwloadaddr") == 0) { + else if (str_cmp_no_case(hdr_args[arg_ind], "-fwloadaddr") == + 0) { arg_ind++; if ((hdr_args[arg_ind] == NULL) || - (sscanf(hdr_args[arg_ind], - "%x", - &main_temp) != 1)) { + (sscanf(hdr_args[arg_ind], "%x", &main_temp) != + 1)) { my_printf(TERR, "\nCannot read FW Load "); my_printf(TERR, "\nstart address !\n"); main_status = FALSE; } else { /* Check that the address is 16-bytes aligned */ - if ((main_temp & - ADDR_16_BYTES_ALIGNED_MASK) != 0) { + if ((main_temp & ADDR_16_BYTES_ALIGNED_MASK) != + 0) { my_printf(TERR, "\nFW load address start "); my_printf(TERR, "address (0x%08X) is not ", main_temp); - my_printf(TERR, - "16-bytes aligned !\n"); + my_printf(TERR, "16-bytes aligned !\n"); main_status = FALSE; } else { - bin_params.fw_load_addr = - main_temp; + bin_params.fw_load_addr = main_temp; bin_params.bin_params |= - BIN_FW_LOAD_START_ADDR; + BIN_FW_LOAD_START_ADDR; } } - /* -fwep, Get the FW entry point. */ + /* -fwep, Get the FW entry point. */ } else if (str_cmp_no_case(hdr_args[arg_ind], "-fwep") == 0) { - if ((bin_params.bin_params & BIN_FW_USER_ARM_RESET) - != 0x00000000) { - my_printf(TERR, - "\n-fwep not allowed, FW entry point"); + if ((bin_params.bin_params & BIN_FW_USER_ARM_RESET) != + 0x00000000) { + my_printf( + TERR, + "\n-fwep not allowed, FW entry point"); my_printf(TERR, " already set using -usearmrst!\n"); main_status = FALSE; } else { arg_ind++; if ((hdr_args[arg_ind] == NULL) || - (sscanf(hdr_args[arg_ind], - "%x", - &main_temp) != 1)) { + (sscanf(hdr_args[arg_ind], "%x", + &main_temp) != 1)) { my_printf(TERR, "\nCan't read FW E-Point\n"); main_status = FALSE; } else { - bin_params.fw_ep = - main_temp; + bin_params.fw_ep = main_temp; bin_params.bin_params |= - BIN_FW_ENTRY_POINT; + BIN_FW_ENTRY_POINT; } } - /* - * -crcstart, Get the address from where to calculate - * the FW CRC. - */ - } else if (str_cmp_no_case(hdr_args[arg_ind], - "-crcstart") == 0) { + /* + * -crcstart, Get the address from where to calculate + * the FW CRC. + */ + } else if (str_cmp_no_case(hdr_args[arg_ind], "-crcstart") == + 0) { arg_ind++; if ((hdr_args[arg_ind] == NULL) || - (sscanf(hdr_args[arg_ind], - "%x", - &main_temp) != 1)) { - my_printf(TERR, - "\nCannot read FW CRC"); - my_printf(TERR, - " start address !\n"); + (sscanf(hdr_args[arg_ind], "%x", &main_temp) != + 1)) { + my_printf(TERR, "\nCannot read FW CRC"); + my_printf(TERR, " start address !\n"); main_status = FALSE; } else { bin_params.fw_err_detec_e_addr = bin_params.fw_err_detec_e_addr - - bin_params.fw_err_detec_s_addr - + main_temp; - bin_params.fw_err_detec_s_addr = - main_temp; + bin_params.fw_err_detec_s_addr + + main_temp; + bin_params.fw_err_detec_s_addr = main_temp; bin_params.bin_params |= BIN_FW_CKS_START; } - /* -crcsize, Get the area size that need to be CRCed. */ - } else if (str_cmp_no_case(hdr_args[arg_ind], - "-crcsize") == 0) { + /* -crcsize, Get the area size that need to be CRCed. + */ + } else if (str_cmp_no_case(hdr_args[arg_ind], "-crcsize") == + 0) { arg_ind++; main_temp = 0x00; if (hdr_args[arg_ind] == NULL) end_ptr = NULL; else - main_temp = strtol(hdr_args[arg_ind], - &end_ptr, 16); + main_temp = + strtol(hdr_args[arg_ind], &end_ptr, 16); if (hdr_args[arg_ind] == end_ptr) { my_printf(TERR, @@ -604,8 +582,8 @@ int main(int argc, char *argv[]) main_status = FALSE; } else { bin_params.fw_err_detec_e_addr = - bin_params.fw_err_detec_s_addr - + main_temp - 1; + bin_params.fw_err_detec_s_addr + + main_temp - 1; bin_params.bin_params |= BIN_FW_CKS_SIZE; } } @@ -613,9 +591,8 @@ int main(int argc, char *argv[]) else if (str_cmp_no_case(hdr_args[arg_ind], "-fwlen") == 0) { arg_ind++; if ((hdr_args[arg_ind] == NULL) || - (sscanf(hdr_args[arg_ind], - "%x", - &main_temp) != 1)) { + (sscanf(hdr_args[arg_ind], "%x", &main_temp) != + 1)) { my_printf(TERR, "\nCannot read FW length !\n"); main_status = FALSE; } else { @@ -624,25 +601,24 @@ int main(int argc, char *argv[]) } } /* flashsize, Get the flash size. */ - else if (str_cmp_no_case(hdr_args[arg_ind], - "-flashsize") == 0) { + else if (str_cmp_no_case(hdr_args[arg_ind], "-flashsize") == + 0) { arg_ind++; if ((hdr_args[arg_ind] == NULL) || - (sscanf(hdr_args[arg_ind], - "%d", - &main_temp) != 1)) { + (sscanf(hdr_args[arg_ind], "%d", &main_temp) != + 1)) { my_printf(TERR, "\nCannot read Flash size !\n"); main_status = FALSE; } else bin_params.flash_size = main_temp; - /* -apisign, Get the method for error detect calculation. */ - } else if (str_cmp_no_case(hdr_args[arg_ind], - "-apisign") == 0) { + /* -apisign, Get the method for error detect + * calculation. */ + } else if (str_cmp_no_case(hdr_args[arg_ind], "-apisign") == + 0) { arg_ind++; if ((hdr_args[arg_ind] == NULL) || - (sscanf(hdr_args[arg_ind], - "%s", - main_str_temp) != 1)) { + (sscanf(hdr_args[arg_ind], "%s", main_str_temp) != + 1)) { my_printf(TERR, "\nCannot read API sign, CRC,"); my_printf(TERR, " CheckSum or None. !\n"); main_status = FALSE; @@ -666,23 +642,21 @@ int main(int argc, char *argv[]) main_str_temp); main_status = FALSE; } - } - /* -pointer, Get the FW image address. */ - } else if (str_cmp_no_case(hdr_args[arg_ind], - "-pointer") == 0) { + /* -pointer, Get the FW image address. */ + } else if (str_cmp_no_case(hdr_args[arg_ind], "-pointer") == + 0) { arg_ind++; if ((hdr_args[arg_ind] == NULL) || - (sscanf(hdr_args[arg_ind], - "%x", - &main_temp) != 1)) { + (sscanf(hdr_args[arg_ind], "%x", &main_temp) != + 1)) { my_printf(TERR, "\nCannot read FW Image address !\n"); main_status = FALSE; } else { /* Check that the address is 16-bytes aligned */ - if ((main_temp & ADDR_16_BYTES_ALIGNED_MASK) - != 0) { + if ((main_temp & ADDR_16_BYTES_ALIGNED_MASK) != + 0) { my_printf(TERR, "\nFW Image address (0x%08X)" " isn't 16-bytes aligned !\n", @@ -696,8 +670,7 @@ int main(int argc, char *argv[]) main_temp); my_printf(TERR, "is higher from flash size"); - my_printf(TERR, - " (0x%08X) !\n", + my_printf(TERR, " (0x%08X) !\n", MAX_FLASH_SIZE); main_status = FALSE; } else { @@ -713,8 +686,8 @@ int main(int argc, char *argv[]) if (hdr_args[arg_ind] == NULL) end_ptr = NULL; else - main_temp = strtol(hdr_args[arg_ind], - &end_ptr, 16); + main_temp = + strtol(hdr_args[arg_ind], &end_ptr, 16); if (hdr_args[arg_ind] == end_ptr) { my_printf(TERR, "\nCannot read BootLoader"); @@ -722,11 +695,12 @@ int main(int argc, char *argv[]) main_status = FALSE; } else { /* Check that the address is 16-bytes aligned */ - if ((main_temp & ADDR_16_BYTES_ALIGNED_MASK) - != 0) { - my_printf(TERR, - "\nFW Image address (0x%08X) ", - main_temp); + if ((main_temp & ADDR_16_BYTES_ALIGNED_MASK) != + 0) { + my_printf( + TERR, + "\nFW Image address (0x%08X) ", + main_temp); my_printf(TERR, "is not 16-bytes aligned!\n"); } @@ -737,8 +711,7 @@ int main(int argc, char *argv[]) main_temp); my_printf(TERR, " is higher from flash size"); - my_printf(TERR, - " (0x%08X) !\n", + my_printf(TERR, " (0x%08X) !\n", MAX_FLASH_SIZE); main_status = FALSE; } else { @@ -747,27 +720,25 @@ int main(int argc, char *argv[]) } } } else { - my_printf(TERR, - "\nUnknown flag: %s\n", + my_printf(TERR, "\nUnknown flag: %s\n", hdr_args[arg_ind]); main_status = FALSE; } } /* - * If the input and output file have the same name then exit with error. - */ + * If the input and output file have the same name then exit with error. + */ if (strcmp(output_file_name, input_file_name) == 0) { my_printf(TINF, - "Input file name (%s) should be differed from\n", - input_file_name); + "Input file name (%s) should be differed from\n", + input_file_name); my_printf(TINF, "Output file name (%s).\n", output_file_name); main_status = FALSE; } /* No problems reading argv? So go on... */ if (main_status) { - /* if output file already exist, then delete it. */ tmp_file = fopen(output_file_name, "w"); if (tmp_file != NULL) @@ -802,18 +773,17 @@ int main(int argc, char *argv[]) /* Say Bye Bye */ if (main_status) { my_printf(TPAS, "\n\n******************************"); - my_printf(TPAS, "\n*** SUCCESS ***"); - my_printf(TPAS, "\n******************************\n"); + my_printf(TPAS, "\n*** SUCCESS ***"); + my_printf(TPAS, "\n******************************\n"); exit(EXIT_SUCCESS); } else { my_printf(TERR, "\n\n******************************"); - my_printf(TERR, "\n*** FAILED ***"); - my_printf(TERR, "\n******************************\n"); + my_printf(TERR, "\n*** FAILED ***"); + my_printf(TERR, "\n******************************\n"); exit(EXIT_FAILURE); } - } /* @@ -930,12 +900,9 @@ void exit_with_usage(void) * Description: Copy the source file to the end of the destination file. *-------------------------------------------------------------------------- */ -int copy_file_to_file(char *dst_file_name, - char *src_file_name, - int offset, - int origin) +int copy_file_to_file(char *dst_file_name, char *src_file_name, int offset, + int origin) { - int index = 0; int result = 0; unsigned char local_val; @@ -1030,12 +997,9 @@ void my_printf(int error_level, char *fmt, ...) * Description: Writes to ELF or BIN files - whatever is open *-------------------------------------------------------------------------- */ -int write_to_file(unsigned int write_value, - unsigned int offset, - unsigned char num_of_bytes, - char *print_string) +int write_to_file(unsigned int write_value, unsigned int offset, + unsigned char num_of_bytes, char *print_string) { - int result = 0; int index; unsigned int localValue4; @@ -1046,32 +1010,23 @@ int write_to_file(unsigned int write_value, return FALSE; switch (num_of_bytes) { - case(1): + case (1): localValue1 = (unsigned char)write_value; - result = (int)(fwrite(&localValue1, 1, - 1, g_hfd_pointer)); - break; - case(2): + result = (int)(fwrite(&localValue1, 1, 1, g_hfd_pointer)); + break; + case (2): localValue2 = (unsigned short)write_value; - result = (int)(fwrite(&localValue2, - 2, - 1, - g_hfd_pointer)); + result = (int)(fwrite(&localValue2, 2, 1, g_hfd_pointer)); break; - case(4): + case (4): localValue4 = write_value; - result = (int)(fwrite(&localValue4, - 4, - 1, - g_hfd_pointer)); + result = (int)(fwrite(&localValue4, 4, 1, g_hfd_pointer)); break; default: /* Pad the same value N times. */ localValue1 = (unsigned char)write_value; for (index = 0; index < num_of_bytes; index++) - result = (int)(fwrite(&localValue1, - 1, - 1, + result = (int)(fwrite(&localValue1, 1, 1, g_hfd_pointer)); break; } @@ -1079,18 +1034,15 @@ int write_to_file(unsigned int write_value, my_printf(TINF, "\nIn write_to_file - %s", print_string); if (result) { - my_printf(TINF, - " - Offset %2d - value 0x%x", - offset, write_value); + my_printf(TINF, " - Offset %2d - value 0x%x", offset, + write_value); } else { - my_printf(TERR, - "\n\nCouldn't write %x to file at %x\n\n", - write_value, offset); + my_printf(TERR, "\n\nCouldn't write %x to file at %x\n\n", + write_value, offset); return FALSE; } return TRUE; - } /* @@ -1101,10 +1053,8 @@ int write_to_file(unsigned int write_value, * Description : Reads from open BIN file *-------------------------------------------------------------------------- */ -int read_from_file(unsigned int offset, - unsigned char size_to_read, - unsigned int *read_value, - char *print_string) +int read_from_file(unsigned int offset, unsigned char size_to_read, + unsigned int *read_value, char *print_string) { int result; unsigned int localValue4; @@ -1115,25 +1065,16 @@ int read_from_file(unsigned int offset, return FALSE; switch (size_to_read) { - case(1): - result = (int)(fread(&localValue1, - 1, - 1, - input_file_pointer)); + case (1): + result = (int)(fread(&localValue1, 1, 1, input_file_pointer)); *read_value = localValue1; break; - case(2): - result = (int)(fread(&localValue2, - 2, - 1, - input_file_pointer)); + case (2): + result = (int)(fread(&localValue2, 2, 1, input_file_pointer)); *read_value = localValue2; break; - case(4): - result = (int)(fread(&localValue4, - 4, - 1, - input_file_pointer)); + case (4): + result = (int)(fread(&localValue4, 4, 1, input_file_pointer)); *read_value = localValue4; break; default: @@ -1145,13 +1086,10 @@ int read_from_file(unsigned int offset, my_printf(TINF, "\nIn read_from_file - %s", print_string); if (result) { - my_printf(TINF, - " - Offset %d - value %x", - offset, *read_value); + my_printf(TINF, " - Offset %d - value %x", offset, *read_value); } else { - my_printf(TERR, - "\n\nCouldn't read from file at %x\n\n", - offset); + my_printf(TERR, "\n\nCouldn't read from file at %x\n\n", + offset); return FALSE; } @@ -1210,12 +1148,11 @@ void finalize_calculation(unsigned int *check_sum_crc) * given the previous checksum\crc *-------------------------------------------------------------------------- */ -void update_calculation(unsigned int *check_sum_crc, - unsigned char byte_to_add) +void update_calculation(unsigned int *check_sum_crc, unsigned char byte_to_add) { switch (g_calc_type) { case CALC_TYPE_NONE: - /* Do nothing */ + /* Do nothing */ break; case CALC_TYPE_CHECKSUM: *check_sum_crc += byte_to_add; @@ -1328,25 +1265,22 @@ int main_bin(struct tbinparams binary_params) bin_fw_offset = binary_params.fw_hdr_offset + HEADER_SIZE; my_printf(TINF, "\nBIN file: %s, size: %d (0x%x) bytes\n", - input_file_name, - bin_file_size_bytes, - bin_file_size_bytes); + input_file_name, bin_file_size_bytes, bin_file_size_bytes); /* Check validity of FW header offset. */ if (((int)binary_params.fw_hdr_offset < 0) || - (binary_params.fw_hdr_offset > bin_file_size_bytes)) { + (binary_params.fw_hdr_offset > bin_file_size_bytes)) { my_printf(TERR, "\nFW header offset 0x%08x (%d) should be in the" " range of 0 and file size (%d).\n", binary_params.fw_hdr_offset, - binary_params.fw_hdr_offset, - bin_file_size_bytes); + binary_params.fw_hdr_offset, bin_file_size_bytes); return FALSE; } /* Create the header file in the same directory as the input file. */ if (!splice_into_path(g_hdr_input_name, input_file_name, - sizeof(g_hdr_input_name), "hdr_")) + sizeof(g_hdr_input_name), "hdr_")) return FALSE; g_hfd_pointer = fopen(g_hdr_input_name, "w+b"); if (g_hfd_pointer == NULL) { @@ -1356,7 +1290,7 @@ int main_bin(struct tbinparams binary_params) if (strlen(output_file_name) == 0) { if (!splice_into_path(output_file_name, input_file_name, - sizeof(output_file_name), "out_")) + sizeof(output_file_name), "out_")) return FALSE; } @@ -1368,15 +1302,12 @@ int main_bin(struct tbinparams binary_params) ********************************************************************* */ /* Write the ancore. */ - if (!write_to_file(FW_HDR_ANCHOR, - HDR_ANCHOR_OFFSET, - 4, + if (!write_to_file(FW_HDR_ANCHOR, HDR_ANCHOR_OFFSET, 4, "HDR - FW Header ANCHOR ")) return FALSE; /* Write the extended anchor. */ if (binary_params.bin_params & BIN_FW_HDR_CRC_DISABLE) { - /* Write the ancore and the extended anchor. */ if (!write_to_file(FW_HDR_EXT_ANCHOR_DISABLE, HDR_EXTENDED_ANCHOR_OFFSET, 2, @@ -1409,14 +1340,13 @@ int main_bin(struct tbinparams binary_params) break; default: my_printf(TERR, "\n\nInvalid SPI Flash MAX clock (%d MHz) ", - binary_params.spi_max_clk); + binary_params.spi_max_clk); my_printf(TERR, "- it should be 20, 25, 33, 40 or 50 MHz"); return FALSE; } /* If SPI clock ratio set for MRIDER15, then it is error. */ if ((binary_params.spi_clk_ratio != 0x00) && (is_mrider15 == TRUE)) { - my_printf(TERR, "\nspiclkratio is not relevant for"); my_printf(TERR, " npcx5mng chips family !\n"); @@ -1439,13 +1369,13 @@ int main_bin(struct tbinparams binary_params) break; default: my_printf(TERR, "\n\nInvalid SPI Core Clock Ratio (%d) ", - binary_params.spi_clk_ratio); + binary_params.spi_clk_ratio); my_printf(TERR, "- it should be 1 or 2"); return FALSE; } if (!write_to_file(tmp_param, HDR_SPI_MAX_CLK_OFFSET, 1, - "HDR - SPI flash MAX Clock ")) + "HDR - SPI flash MAX Clock ")) return FALSE; /* Write the SPI flash Read Mode. */ @@ -1453,7 +1383,6 @@ int main_bin(struct tbinparams binary_params) /* If needed, set the unlimited burst bit. */ if (binary_params.bin_params & BIN_UNLIM_BURST_ENABLE) { if (is_mrider15 == TRUE) { - my_printf(TERR, "\nunlimburst is not relevant for"); my_printf(TERR, " npcx5mng chips family !\n"); @@ -1462,35 +1391,29 @@ int main_bin(struct tbinparams binary_params) tmp_param |= SPI_UNLIMITED_BURST_ENABLE; } - if (!write_to_file(tmp_param, - HDR_SPI_READ_MODE_OFFSET, 1, - "HDR - SPI flash Read Mode ")) + if (!write_to_file(tmp_param, HDR_SPI_READ_MODE_OFFSET, 1, + "HDR - SPI flash Read Mode ")) return FALSE; /* Write the error detection configuration. */ if (binary_params.bin_params & BIN_FW_CRC_DISABLE) { if (!write_to_file(FW_CRC_DISABLE, - HDR_ERR_DETECTION_CONF_OFFSET, - 1, + HDR_ERR_DETECTION_CONF_OFFSET, 1, "HDR - FW CRC Disabled ")) return FALSE; } else { /* Write the ancore and the extended anchor. */ - if (!write_to_file(FW_CRC_ENABLE, - HDR_ERR_DETECTION_CONF_OFFSET, 1, - "HDR - FW CRC Enabled ")) + if (!write_to_file(FW_CRC_ENABLE, HDR_ERR_DETECTION_CONF_OFFSET, + 1, "HDR - FW CRC Enabled ")) return FALSE; } /* FW entry point should be between the FW load address and RAM size */ - if ((binary_params.fw_load_addr > - (g_ram_start_address + g_ram_size)) || - (binary_params.fw_load_addr < g_ram_start_address)) { - my_printf(TERR, - "\nFW load address (0x%08x) should be between ", + if ((binary_params.fw_load_addr > (g_ram_start_address + g_ram_size)) || + (binary_params.fw_load_addr < g_ram_start_address)) { + my_printf(TERR, "\nFW load address (0x%08x) should be between ", binary_params.fw_load_addr); - my_printf(TERR, - "start (0x%08x) and end (0x%08x) of RAM ).", + my_printf(TERR, "start (0x%08x) and end (0x%08x) of RAM ).", g_ram_start_address, (g_ram_start_address + g_ram_size)); @@ -1499,8 +1422,8 @@ int main_bin(struct tbinparams binary_params) /* Write the FW load start address */ if (!write_to_file(binary_params.fw_load_addr, - HDR_FW_LOAD_START_ADDR_OFFSET, 4, - "HDR - FW load start address ")) + HDR_FW_LOAD_START_ADDR_OFFSET, 4, + "HDR - FW load start address ")) return FALSE; /* @@ -1512,25 +1435,22 @@ int main_bin(struct tbinparams binary_params) * size of the binary file minus the offset of the start of the * FW. */ - binary_params.fw_len = bin_file_size_bytes-bin_fw_offset; + binary_params.fw_len = bin_file_size_bytes - bin_fw_offset; } if ((int)binary_params.fw_len < 0) { my_printf(TERR, "\nFW length %d (0x%08x) should be greater than 0x0.", - binary_params.fw_len, - binary_params.fw_len); + binary_params.fw_len, binary_params.fw_len); return FALSE; } if (((int)binary_params.fw_len > - (bin_file_size_bytes - bin_fw_offset)) || - ((int)binary_params.fw_len > g_ram_size)) { - my_printf(TERR, - "\nFW length %d (0x%08x) should be within the", + (bin_file_size_bytes - bin_fw_offset)) || + ((int)binary_params.fw_len > g_ram_size)) { + my_printf(TERR, "\nFW length %d (0x%08x) should be within the", binary_params.fw_len, binary_params.fw_len); - my_printf(TERR, - " input-file (related to the FW offset)"); + my_printf(TERR, " input-file (related to the FW offset)"); my_printf(TERR, "\n (0x%08x) and within the RAM (RAM size: 0x%08x).", (bin_file_size_bytes - bin_fw_offset), g_ram_size); @@ -1538,61 +1458,48 @@ int main_bin(struct tbinparams binary_params) } if ((binary_params.bin_params & BIN_FW_USER_ARM_RESET) != 0x00000000) { - read_from_file((bin_fw_offset + ARM_FW_ENTRY_POINT_OFFSET), - 4, - &binary_params.fw_ep, - "read FW entry point for FW image "); - - if ((binary_params.fw_ep < - binary_params.fw_load_addr) || - (binary_params.fw_ep > - (binary_params.fw_load_addr + - binary_params.fw_len))) { + read_from_file((bin_fw_offset + ARM_FW_ENTRY_POINT_OFFSET), 4, + &binary_params.fw_ep, + "read FW entry point for FW image "); + + if ((binary_params.fw_ep < binary_params.fw_load_addr) || + (binary_params.fw_ep > + (binary_params.fw_load_addr + binary_params.fw_len))) { my_printf(TERR, "\nFW entry point (0x%08x) should be between", binary_params.fw_ep); - my_printf(TERR, - " the FW load address (0x%08x) ", + my_printf(TERR, " the FW load address (0x%08x) ", binary_params.fw_load_addr); - my_printf(TERR, - "and FW length (0x%08x).\n", + my_printf(TERR, "and FW length (0x%08x).\n", (binary_params.fw_load_addr + - binary_params.fw_len)); + binary_params.fw_len)); return FALSE; } } /* FW entry point should be between the FW load address and RAM size */ - if ((binary_params.fw_ep < - binary_params.fw_load_addr) || - (binary_params.fw_ep > - (binary_params.fw_load_addr + - binary_params.fw_len))) { + if ((binary_params.fw_ep < binary_params.fw_load_addr) || + (binary_params.fw_ep > + (binary_params.fw_load_addr + binary_params.fw_len))) { if (((binary_params.bin_params & BIN_FW_ENTRY_POINT) == - 0x00000000) && - ((binary_params.bin_params & - BIN_FW_LOAD_START_ADDR) != 0x00000000)) { - binary_params.fw_ep = - binary_params.fw_load_addr; + 0x00000000) && + ((binary_params.bin_params & BIN_FW_LOAD_START_ADDR) != + 0x00000000)) { + binary_params.fw_ep = binary_params.fw_load_addr; } else { - my_printf(TERR, - "\nFW entry point (0x%08x) should be ", + my_printf(TERR, "\nFW entry point (0x%08x) should be ", binary_params.fw_ep); - my_printf(TERR, - "\between the FW load address (0x%08x)", + my_printf(TERR, "\between the FW load address (0x%08x)", binary_params.fw_load_addr); - my_printf(TERR, - " and FW length (0x%08x).\n", + my_printf(TERR, " and FW length (0x%08x).\n", (binary_params.fw_load_addr + - binary_params.fw_len)); + binary_params.fw_len)); return FALSE; } } /* Write the FW entry point */ - if (!write_to_file(binary_params.fw_ep, - HDR_FW_ENTRY_POINT_OFFSET, - 4, + if (!write_to_file(binary_params.fw_ep, HDR_FW_ENTRY_POINT_OFFSET, 4, "HDR - FW Entry point ")) return FALSE; @@ -1602,17 +1509,15 @@ int main_bin(struct tbinparams binary_params) * In case the size was not set, then CRC end address is * the size of the binary file. */ - binary_params.fw_err_detec_e_addr = - binary_params.fw_len - 1; + binary_params.fw_err_detec_e_addr = binary_params.fw_len - 1; } else { /* CRC end address should be less than FW length. */ if (binary_params.fw_err_detec_e_addr > - (binary_params.fw_len - 1)) { + (binary_params.fw_len - 1)) { my_printf(TERR, "\nCRC end address (0x%08x) should be less ", binary_params.fw_err_detec_e_addr); - my_printf(TERR, - "than the FW length %d (0x%08x)", + my_printf(TERR, "than the FW length %d (0x%08x)", (binary_params.fw_len), (binary_params.fw_len)); return FALSE; @@ -1621,40 +1526,35 @@ int main_bin(struct tbinparams binary_params) /* Check CRC start and end addresses. */ if (binary_params.fw_err_detec_s_addr > - binary_params.fw_err_detec_e_addr) { + binary_params.fw_err_detec_e_addr) { my_printf(TERR, "\nCRC start address (0x%08x) should be less or ", binary_params.fw_err_detec_s_addr); my_printf(TERR, "equal to CRC end address (0x%08x)\nPlease check ", binary_params.fw_err_detec_e_addr); - my_printf(TERR, - "CRC start address and CRC size arguments."); + my_printf(TERR, "CRC start address and CRC size arguments."); return FALSE; } /* CRC start addr should be between the FW load address and RAM size */ - if (binary_params.fw_err_detec_s_addr > - binary_params.fw_len) { + if (binary_params.fw_err_detec_s_addr > binary_params.fw_len) { my_printf(TERR, "\nCRC start address (0x%08x) should ", binary_params.fw_err_detec_s_addr); - my_printf(TERR, "be FW length (0x%08x).", - binary_params.fw_len); + my_printf(TERR, "be FW length (0x%08x).", binary_params.fw_len); return FALSE; } /* Write the CRC start address */ if (!write_to_file(binary_params.fw_err_detec_s_addr, - HDR_FW_ERR_DETECT_START_ADDR_OFFSET, - 4, + HDR_FW_ERR_DETECT_START_ADDR_OFFSET, 4, "HDR - FW CRC Start ")) return FALSE; /* CRC end addr should be between the CRC start address and RAM size */ if ((binary_params.fw_err_detec_e_addr < - binary_params.fw_err_detec_s_addr) || - (binary_params.fw_err_detec_e_addr > - binary_params.fw_len)) { + binary_params.fw_err_detec_s_addr) || + (binary_params.fw_err_detec_e_addr > binary_params.fw_len)) { my_printf(TERR, "\nCRC end address (0x%08x) should be between the ", binary_params.fw_err_detec_e_addr); @@ -1667,8 +1567,7 @@ int main_bin(struct tbinparams binary_params) /* Write the CRC end address */ if (!write_to_file(binary_params.fw_err_detec_e_addr, - HDR_FW_ERR_DETECT_END_ADDR_OFFSET, - 4, + HDR_FW_ERR_DETECT_END_ADDR_OFFSET, 4, "HDR - FW CRC End ")) return FALSE; @@ -1678,22 +1577,18 @@ int main_bin(struct tbinparams binary_params) binary_params.fw_len += (16 - tmp_param); /* FW load address + FW length should be less than the RAM size. */ - if ((binary_params.fw_load_addr + - binary_params.fw_len) > - (g_ram_start_address + g_ram_size)) { + if ((binary_params.fw_load_addr + binary_params.fw_len) > + (g_ram_start_address + g_ram_size)) { my_printf(TERR, "\nFW load address + FW length should (0x%08x) be ", (binary_params.fw_load_addr + binary_params.fw_len)); - my_printf(TERR, - "less than the RAM size (0x%08x).", + my_printf(TERR, "less than the RAM size (0x%08x).", (g_ram_start_address + g_ram_size)); return FALSE; } /* Write the FW length */ - if (!write_to_file(binary_params.fw_len, - HDR_FW_LENGTH_OFFSET, - 4, + if (!write_to_file(binary_params.fw_len, HDR_FW_LENGTH_OFFSET, 4, "HDR - FW Length ")) return FALSE; @@ -1716,30 +1611,26 @@ int main_bin(struct tbinparams binary_params) break; default: my_printf(TERR, "\n\nInvalid Flash size (%d MBytes) -", - binary_params.flash_size); + binary_params.flash_size); my_printf(TERR, " it should be 1, 2, 4, 8 or 16 MBytes\n"); return FALSE; } - if (!write_to_file(tmp_param, - HDR_FLASH_SIZE_OFFSET, - 1, + if (!write_to_file(tmp_param, HDR_FLASH_SIZE_OFFSET, 1, "HDR - Flash size ")) return FALSE; /* Write the reserved bytes. */ if (!write_to_file(PAD_VALUE, HDR_RESERVED, 26, - "HDR - Reserved (26 bytes) ")) + "HDR - Reserved (26 bytes) ")) return FALSE; - /* Refresh the FW header bin file in order to calculate CRC */ if (g_hfd_pointer) { fclose(g_hfd_pointer); g_hfd_pointer = fopen(g_hdr_input_name, "r+b"); if (g_hfd_pointer == NULL) { - my_printf(TERR, - "\n\nCannot open %s\n\n", + my_printf(TERR, "\n\nCannot open %s\n\n", input_file_name); return FALSE; } @@ -1757,9 +1648,7 @@ int main_bin(struct tbinparams binary_params) binary_params.hdr_crc = 0; /* Write FW header CRC to header file */ - if (!write_to_file(binary_params.hdr_crc, - HDR_FW_HEADER_SIG_OFFSET, - 4, + if (!write_to_file(binary_params.hdr_crc, HDR_FW_HEADER_SIG_OFFSET, 4, "HDR - Header CRC ")) return FALSE; @@ -1767,11 +1656,11 @@ int main_bin(struct tbinparams binary_params) if ((binary_params.bin_params & BIN_FW_CRC_DISABLE) == 0) { /* Calculate ... */ g_calc_type = CALC_TYPE_CRC; - if (!calc_firmware_csum_bin(&binary_params.fw_crc, - (bin_fw_offset + - binary_params.fw_err_detec_s_addr), - (binary_params.fw_err_detec_e_addr - - binary_params.fw_err_detec_s_addr+1))) + if (!calc_firmware_csum_bin( + &binary_params.fw_crc, + (bin_fw_offset + binary_params.fw_err_detec_s_addr), + (binary_params.fw_err_detec_e_addr - + binary_params.fw_err_detec_s_addr + 1))) return FALSE; g_calc_type = CALC_TYPE_NONE; @@ -1779,9 +1668,7 @@ int main_bin(struct tbinparams binary_params) binary_params.fw_crc = 0; /* Write the FW CRC into file header file */ - if (!write_to_file(binary_params.fw_crc, - HDR_FW_IMAGE_SIG_OFFSET, - 4, + if (!write_to_file(binary_params.fw_crc, HDR_FW_IMAGE_SIG_OFFSET, 4, "HDR - FW CRC ")) return FALSE; @@ -1802,22 +1689,14 @@ int main_bin(struct tbinparams binary_params) fclose(output_file_pointer); if ((binary_params.bin_params & BIN_FW_HDR_OFFSET) != 0) { - copy_file_to_file(output_file_name, - input_file_name, - 0, - SEEK_SET); - copy_file_to_file(output_file_name, - g_hdr_input_name, - binary_params.fw_hdr_offset, + copy_file_to_file(output_file_name, input_file_name, 0, SEEK_SET); + copy_file_to_file(output_file_name, g_hdr_input_name, + binary_params.fw_hdr_offset, SEEK_SET); } else { - copy_file_to_file(output_file_name, - g_hdr_input_name, - 0, + copy_file_to_file(output_file_name, g_hdr_input_name, 0, SEEK_END); - copy_file_to_file(output_file_name, - input_file_name, - 0, + copy_file_to_file(output_file_name, input_file_name, 0, SEEK_END); } @@ -1848,20 +1727,16 @@ int calc_header_crc_bin(unsigned int *p_cksum) if (fseek(g_hfd_pointer, 0x00000000, SEEK_SET) < 0) return FALSE; - if (fread(g_header_array, - HEADER_SIZE, - 1, - g_hfd_pointer) != 1) + if (fread(g_header_array, HEADER_SIZE, 1, g_hfd_pointer) != 1) return FALSE; for (i = 0; i < (HEADER_SIZE - HEADER_CRC_FIELDS_SIZE); i++) { - /* * I had once the Verbose check inside the my_printf, but * it made ECST run sloooowwwwwly.... */ if (g_verbose == SUPER_VERBOSE) { - if (i%line_print_size == 0) + if (i % line_print_size == 0) my_printf(TDBG, "\n[%.4x]: ", i); my_printf(TDBG, "%.2x ", g_header_array[i]); @@ -1872,10 +1747,8 @@ int calc_header_crc_bin(unsigned int *p_cksum) if (g_verbose == SUPER_VERBOSE) { if ((i + 1) % line_print_size == 0) - my_printf(TDBG, - "FW Header ChecksumCRC = %.8x", - calc_header_checksum_crc); - + my_printf(TDBG, "FW Header ChecksumCRC = %.8x", + calc_header_checksum_crc); } } @@ -1895,11 +1768,9 @@ int calc_header_crc_bin(unsigned int *p_cksum) * Description: TBD ******************************************************************* */ -int calc_firmware_csum_bin(unsigned int *p_cksum, - unsigned int fw_offset, - unsigned int fw_length) +int calc_firmware_csum_bin(unsigned int *p_cksum, unsigned int fw_offset, + unsigned int fw_length) { - unsigned int i; unsigned int calc_read_bytes; unsigned int calc_num_of_bytes_to_read; @@ -1912,16 +1783,12 @@ int calc_firmware_csum_bin(unsigned int *p_cksum, calc_curr_position = fw_offset; if (g_verbose == REGULAR_VERBOSE) { - my_printf(TINF, - "\nFW Error Detect Start Dddress: 0x%08x", + my_printf(TINF, "\nFW Error Detect Start Dddress: 0x%08x", calc_curr_position); - my_printf(TINF, - "\nFW Error Detect End Dddress: 0x%08x", + my_printf(TINF, "\nFW Error Detect End Dddress: 0x%08x", calc_curr_position + calc_num_of_bytes_to_read - 1); - my_printf(TINF, - "\nFW Error Detect Size: %d (0x%X)", - calc_num_of_bytes_to_read, - calc_num_of_bytes_to_read); + my_printf(TINF, "\nFW Error Detect Size: %d (0x%X)", + calc_num_of_bytes_to_read, calc_num_of_bytes_to_read); } init_calculation(&calc_fw_checksum_crc); @@ -1932,13 +1799,10 @@ int calc_firmware_csum_bin(unsigned int *p_cksum, else calc_read_bytes = calc_num_of_bytes_to_read; - if (fseek(input_file_pointer, - calc_curr_position, SEEK_SET) < 0) + if (fseek(input_file_pointer, calc_curr_position, SEEK_SET) < 0) return 0; - if (fread(g_fw_array, - calc_read_bytes, - 1, - input_file_pointer) != 1) + if (fread(g_fw_array, calc_read_bytes, 1, input_file_pointer) != + 1) return 0; for (i = 0; i < calc_read_bytes; i++) { @@ -1947,9 +1811,8 @@ int calc_firmware_csum_bin(unsigned int *p_cksum, * but it made ECST run sloooowwwwwly.... */ if (g_verbose == SUPER_VERBOSE) { - if (i%line_print_size == 0) - my_printf(TDBG, - "\n[%.4x]: ", + if (i % line_print_size == 0) + my_printf(TDBG, "\n[%.4x]: ", calc_curr_position + i); my_printf(TDBG, "%.2x ", g_fw_array[i]); @@ -1960,8 +1823,7 @@ int calc_firmware_csum_bin(unsigned int *p_cksum, if (g_verbose == SUPER_VERBOSE) { if ((i + 1) % line_print_size == 0) - my_printf(TDBG, - "FW Checksum= %.8x", + my_printf(TDBG, "FW Checksum= %.8x", calc_fw_checksum_crc); } } @@ -2006,24 +1868,19 @@ int main_hdr(void) } if (strlen(output_file_name) == 0) - strncpy(tmp_file_name, - input_file_name, + strncpy(tmp_file_name, input_file_name, sizeof(tmp_file_name) - 1); else { - copy_file_to_file(output_file_name, - input_file_name, - 0, + copy_file_to_file(output_file_name, input_file_name, 0, SEEK_END); - strncpy(tmp_file_name, - output_file_name, + strncpy(tmp_file_name, output_file_name, sizeof(tmp_file_name) - 1); } /* Open Header file */ g_hdr_pointer = fopen(tmp_file_name, "r+b"); if (g_hdr_pointer == NULL) { - my_printf(TERR, - "\n\nCannot open %s file.\n\n", + my_printf(TERR, "\n\nCannot open %s file.\n\n", tmp_file_name); return FALSE; } @@ -2035,10 +1892,9 @@ int main_hdr(void) my_printf(TERR, "\n\nFW offset 0x%08x should be less than ", fw_offset); - my_printf(TERR, - "file size 0x%x (%d).\n\n", + my_printf(TERR, "file size 0x%x (%d).\n\n", bin_file_size_bytes, bin_file_size_bytes); - return FALSE; + return FALSE; } /* FW table should be less than file size. */ @@ -2046,7 +1902,7 @@ int main_hdr(void) my_printf(TERR, "\n\nFW table 0x%08x should be less ", ptr_fw_addr); my_printf(TERR, "than file size 0x%x (%d).\n\n", - bin_file_size_bytes, bin_file_size_bytes); + bin_file_size_bytes, bin_file_size_bytes); return FALSE; } @@ -2054,25 +1910,15 @@ int main_hdr(void) return FALSE; tmp_long_val = HDR_PTR_SIGNATURE; - result = (int)(fwrite(&tmp_long_val, - 4, - 1, - g_hdr_pointer)); - result |= (int)(fwrite(&ptr_fw_addr, - 4, - 1, - g_hdr_pointer)); + result = (int)(fwrite(&tmp_long_val, 4, 1, g_hdr_pointer)); + result |= (int)(fwrite(&ptr_fw_addr, 4, 1, g_hdr_pointer)); if (result) { - my_printf(TINF, - "\nBootLoader Header file: %s\n", + my_printf(TINF, "\nBootLoader Header file: %s\n", tmp_file_name); - my_printf(TINF, - " Offset: 0x%08X, Signature: 0x%08X,", + my_printf(TINF, " Offset: 0x%08X, Signature: 0x%08X,", fw_offset, HDR_PTR_SIGNATURE); - my_printf(TINF, - " Pointer: 0x%08X\n", - ptr_fw_addr); + my_printf(TINF, " Pointer: 0x%08X\n", ptr_fw_addr); } else { my_printf(TERR, "\n\nCouldn't write signature (%x) and " @@ -2082,7 +1928,6 @@ int main_hdr(void) } } else { - if (strlen(output_file_name) == 0) { my_printf(TERR, "\n\nNo output file selected "); my_printf(TERR, "for BootLoader header file.\n\n"); @@ -2092,8 +1937,7 @@ int main_hdr(void) /* Open Output file */ g_hdr_pointer = fopen(output_file_name, "w+b"); if (g_hdr_pointer == NULL) { - my_printf(TERR, - "\n\nCannot open %s file.\n\n", + my_printf(TERR, "\n\nCannot open %s file.\n\n", output_file_name); return FALSE; } @@ -2102,23 +1946,15 @@ int main_hdr(void) return FALSE; tmp_long_val = HDR_PTR_SIGNATURE; - result = (int)(fwrite(&tmp_long_val, - 4, - 1, - g_hdr_pointer)); - result |= (int)(fwrite(&ptr_fw_addr, - 4, - 1, - g_hdr_pointer)); + result = (int)(fwrite(&tmp_long_val, 4, 1, g_hdr_pointer)); + result |= (int)(fwrite(&ptr_fw_addr, 4, 1, g_hdr_pointer)); if (result) { - my_printf(TINF, - "\nBootLoader Header file: %s\n", + my_printf(TINF, "\nBootLoader Header file: %s\n", output_file_name); my_printf(TINF, " Signature: 0x%08X, Pointer: 0x%08X\n", - HDR_PTR_SIGNATURE, - ptr_fw_addr); + HDR_PTR_SIGNATURE, ptr_fw_addr); } else { my_printf(TERR, "\n\nCouldn't write signature (%x) and ", @@ -2128,7 +1964,6 @@ int main_hdr(void) output_file_name); return FALSE; } - } /* Close if needed... */ @@ -2166,15 +2001,15 @@ int main_api(void) /* If API input file was not declared, then print error message. */ if (strlen(input_file_name) == 0) { - my_printf(TERR, + my_printf( + TERR, "\n\nNeed to define API input file, using -i flag\n\n"); return FALSE; - } if (strlen(output_file_name) == 0) { if (!splice_into_path(tmp_file_name, input_file_name, - sizeof(tmp_file_name), "api_")) + sizeof(tmp_file_name), "api_")) return FALSE; } else strncpy(tmp_file_name, output_file_name, @@ -2204,27 +2039,20 @@ int main_api(void) api_file_size_bytes = get_file_length(api_file_pointer); if (api_file_size_bytes < 0) return FALSE; - my_printf(TINF, - "\nAPI file: %s, size: %d bytes (0x%x)\n", - tmp_file_name, - api_file_size_bytes, - api_file_size_bytes); + my_printf(TINF, "\nAPI file: %s, size: %d bytes (0x%x)\n", + tmp_file_name, api_file_size_bytes, api_file_size_bytes); crc_checksum = calc_api_csum_bin(); if (fseek(api_file_pointer, api_file_size_bytes, SEEK_SET) < 0) return FALSE; - result = (int)(fwrite(&crc_checksum, - 4, - 1, - api_file_pointer)); + result = (int)(fwrite(&crc_checksum, 4, 1, api_file_pointer)); if (result) my_printf(TINF, "\nIn API BIN file - Offset 0x%08X - value 0x%08X", - api_file_size_bytes, - crc_checksum); + api_file_size_bytes, crc_checksum); else { my_printf(TERR, "\n\nCouldn't write %x to API BIN file at %08x\n\n", @@ -2241,7 +2069,6 @@ int main_api(void) return TRUE; } - /* ******************************************************************* * Function: calc_api_csum_bin @@ -2250,10 +2077,9 @@ int main_api(void) * Return: Return the CRC \ checksum, or "0" in case of fail. * Description: TBD ******************************************************************* -*/ + */ unsigned int calc_api_csum_bin(void) { - unsigned int i; unsigned int calc_read_bytes; int calc_num_of_bytes_to_read; @@ -2269,10 +2095,8 @@ unsigned int calc_api_csum_bin(void) my_printf(TDBG, "\nAPI CRC \\ Checksum First Byte Address: 0x%08x", calc_curr_position); - my_printf(TDBG, - "\nAPI CRC \\ Checksum Size: %d (0x%X)", - calc_num_of_bytes_to_read, - calc_num_of_bytes_to_read); + my_printf(TDBG, "\nAPI CRC \\ Checksum Size: %d (0x%X)", + calc_num_of_bytes_to_read, calc_num_of_bytes_to_read); } init_calculation(&calc_fw_checksum_crc); @@ -2283,13 +2107,10 @@ unsigned int calc_api_csum_bin(void) else calc_read_bytes = calc_num_of_bytes_to_read; - if (fseek(api_file_pointer, - calc_curr_position, SEEK_SET) < 0) + if (fseek(api_file_pointer, calc_curr_position, SEEK_SET) < 0) return 0; - if (fread(g_fw_array, - calc_read_bytes, - 1, - api_file_pointer) != 1) + if (fread(g_fw_array, calc_read_bytes, 1, api_file_pointer) != + 1) return 0; for (i = 0; i < calc_read_bytes; i++) { @@ -2298,10 +2119,9 @@ unsigned int calc_api_csum_bin(void) * but it made ecst run sloooowwwwwly.... */ if (g_verbose == SUPER_VERBOSE) { - if (i%line_print_size == 0) - my_printf(TDBG, - "\n[%.4x]: ", - calc_curr_position + i); + if (i % line_print_size == 0) + my_printf(TDBG, "\n[%.4x]: ", + calc_curr_position + i); my_printf(TDBG, "%.2x ", g_fw_array[i]); } @@ -2311,8 +2131,7 @@ unsigned int calc_api_csum_bin(void) if (g_verbose == SUPER_VERBOSE) { if ((i + 1) % line_print_size == 0) - my_printf(TDBG, - "FW Checksum= %.8x", + my_printf(TDBG, "FW Checksum= %.8x", calc_fw_checksum_crc); } } @@ -2323,14 +2142,13 @@ unsigned int calc_api_csum_bin(void) finalize_calculation(&calc_fw_checksum_crc); return calc_fw_checksum_crc; - } /* ************************************************************************** * CRC Handler ************************************************************************** -*/ + */ /* ******************************************************************* @@ -2343,7 +2161,7 @@ unsigned int calc_api_csum_bin(void) ******************************************************************* */ -#define P_32 0xEDB88320L +#define P_32 0xEDB88320L /* ******************************************************************* @@ -2394,7 +2212,7 @@ static void init_crc32_tab(void); unsigned int initialize_crc_32(void) { return 0xffffffffL; -} /* initialize_crc_32 */ +} /* initialize_crc_32 */ /* ******************************************************************* @@ -2410,7 +2228,6 @@ unsigned int initialize_crc_32(void) unsigned int update_crc_32(unsigned int crc, char c) { - unsigned int tmp, long_c; long_c = 0x000000ffL & (unsigned int)c; @@ -2423,7 +2240,7 @@ unsigned int update_crc_32(unsigned int crc, char c) return crc; -} /* update_crc_32 */ +} /* update_crc_32 */ /* ******************************************************************* @@ -2437,16 +2254,13 @@ unsigned int update_crc_32(unsigned int crc, char c) */ static void init_crc32_tab(void) { - int i, j; unsigned int crc; for (i = 0; i < 256; i++) { - crc = (unsigned int)i; for (j = 0; j < 8; j++) { - if (crc & 0x00000001L) crc = (crc >> 1) ^ P_32; else @@ -2458,7 +2272,7 @@ static void init_crc32_tab(void) crc_tab32_init = TRUE; -} /* init_crc32_tab */ +} /* init_crc32_tab */ /* ******************************************************************* @@ -2473,13 +2287,13 @@ static void init_crc32_tab(void) unsigned int finalize_crc_32(unsigned int crc) { - int i; unsigned int result = 0; for (i = 0; i < NUM_OF_BYTES; i++) - SET_VAR_BIT(result, NUM_OF_BYTES - (i+1), READ_VAR_BIT(crc, i)); + SET_VAR_BIT(result, NUM_OF_BYTES - (i + 1), + READ_VAR_BIT(crc, i)); return result; -} /* finalize_crc_32 */ +} /* finalize_crc_32 */ diff --git a/util/ecst.h b/util/ecst.h index 628eaebe9b..7d3dbbe153 100644 --- a/util/ecst.h +++ b/util/ecst.h @@ -1,5 +1,5 @@ /* - * Copyright 2015 The Chromium OS Authors. All rights reserved. + * Copyright 2015 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -16,149 +16,146 @@ #include <stdio.h> #include <curses.h> - /*--------------------------------------------------------------------------- Defines --------------------------------------------------------------------------*/ /* For the beauty */ -#define TRUE 1 -#define FALSE 0 +#define TRUE 1 +#define FALSE 0 /* CHANGEME when the version is updated */ -#define T_VER 1 -#define T_REV_MAJOR 0 -#define T_REV_MINOR 3 +#define T_VER 1 +#define T_REV_MAJOR 0 +#define T_REV_MINOR 3 /* Header starts by default at 0x20000 */ -#define FIRMWARE_OFFSET_FROM_HEADER 0x40 +#define FIRMWARE_OFFSET_FROM_HEADER 0x40 -#define ARM_FW_ENTRY_POINT_OFFSET 0x04 +#define ARM_FW_ENTRY_POINT_OFFSET 0x04 /* Some useful offsets inside the header */ -#define HDR_ANCHOR_OFFSET 0 -#define HDR_EXTENDED_ANCHOR_OFFSET 4 -#define HDR_SPI_MAX_CLK_OFFSET 6 -#define HDR_SPI_READ_MODE_OFFSET 7 -#define HDR_ERR_DETECTION_CONF_OFFSET 8 -#define HDR_FW_LOAD_START_ADDR_OFFSET 9 -#define HDR_FW_ENTRY_POINT_OFFSET 13 -#define HDR_FW_ERR_DETECT_START_ADDR_OFFSET 17 -#define HDR_FW_ERR_DETECT_END_ADDR_OFFSET 21 -#define HDR_FW_LENGTH_OFFSET 25 -#define HDR_FLASH_SIZE_OFFSET 29 -#define HDR_RESERVED 30 -#define HDR_FW_HEADER_SIG_OFFSET 56 -#define HDR_FW_IMAGE_SIG_OFFSET 60 - - -#define FIRMW_CKSM_OFFSET 0x3C +#define HDR_ANCHOR_OFFSET 0 +#define HDR_EXTENDED_ANCHOR_OFFSET 4 +#define HDR_SPI_MAX_CLK_OFFSET 6 +#define HDR_SPI_READ_MODE_OFFSET 7 +#define HDR_ERR_DETECTION_CONF_OFFSET 8 +#define HDR_FW_LOAD_START_ADDR_OFFSET 9 +#define HDR_FW_ENTRY_POINT_OFFSET 13 +#define HDR_FW_ERR_DETECT_START_ADDR_OFFSET 17 +#define HDR_FW_ERR_DETECT_END_ADDR_OFFSET 21 +#define HDR_FW_LENGTH_OFFSET 25 +#define HDR_FLASH_SIZE_OFFSET 29 +#define HDR_RESERVED 30 +#define HDR_FW_HEADER_SIG_OFFSET 56 +#define HDR_FW_IMAGE_SIG_OFFSET 60 + +#define FIRMW_CKSM_OFFSET 0x3C /* Header field known values */ -#define FW_HDR_ANCHOR 0x2A3B4D5E -#define FW_HDR_EXT_ANCHOR_ENABLE 0xAB1E -#define FW_HDR_EXT_ANCHOR_DISABLE 0x54E1 -#define FW_CRC_DISABLE 0x00 -#define FW_CRC_ENABLE 0x02 -#define HEADER_CRC_FIELDS_SIZE 8 +#define FW_HDR_ANCHOR 0x2A3B4D5E +#define FW_HDR_EXT_ANCHOR_ENABLE 0xAB1E +#define FW_HDR_EXT_ANCHOR_DISABLE 0x54E1 +#define FW_CRC_DISABLE 0x00 +#define FW_CRC_ENABLE 0x02 +#define HEADER_CRC_FIELDS_SIZE 8 -#define HDR_PTR_SIGNATURE 0x55AA650E +#define HDR_PTR_SIGNATURE 0x55AA650E -#define CKSMCRC_INV_BIT_OFFSET 0x1 +#define CKSMCRC_INV_BIT_OFFSET 0x1 /* Some common Sizes */ -#define STR_SIZE 200 -#define ARG_SIZE 100 -#define NAME_SIZE 160 -#define BUFF_SIZE 0x400 -#define HEADER_SIZE 64 -#define TMP_STR_SIZE 21 -#define PAD_VALUE 0x00 - +#define STR_SIZE 200 +#define ARG_SIZE 100 +#define NAME_SIZE 160 +#define BUFF_SIZE 0x400 +#define HEADER_SIZE 64 +#define TMP_STR_SIZE 21 +#define PAD_VALUE 0x00 -#define MAX_ARGS 100 +#define MAX_ARGS 100 /* Text Colors */ -#define TDBG 0x02 /* Dark Green */ -#define TPAS 0x0A /* light green */ -#define TINF 0x0B /* light turquise */ -#define TERR 0x0C /* light red */ -#define TUSG 0x0E /* light yellow */ +#define TDBG 0x02 /* Dark Green */ +#define TPAS 0x0A /* light green */ +#define TINF 0x0B /* light turquise */ +#define TERR 0x0C /* light red */ +#define TUSG 0x0E /* light yellow */ /* Indicates bin Command line parameters */ -#define BIN_FW_HDR_CRC_DISABLE 0x0001 -#define BIN_FW_CRC_DISABLE 0x0002 -#define BIN_FW_START 0x0004 -#define BIN_FW_SIZE 0x0008 -#define BIN_CK_FIRMWARE 0x0010 -#define BIN_FW_CKS_START 0x0020 -#define BIN_FW_CKS_SIZE 0x0040 -#define BIN_FW_CHANGE_SIG 0x0080 -#define BIN_FW_SPI_MAX_CLK 0x0100 -#define BIN_FW_LOAD_START_ADDR 0x0200 -#define BIN_FW_ENTRY_POINT 0x0400 -#define BIN_FW_LENGTH 0x0800 -#define BIN_FW_HDR_OFFSET 0x1000 -#define BIN_FW_USER_ARM_RESET 0x2000 -#define BIN_UNLIM_BURST_ENABLE 0x4000 - -#define ECRP_OFFSET 0x01 -#define ECRP_INPUT_FILE 0x02 -#define ECRP_OUTPUT_FILE 0x04 - -#define SPI_MAX_CLOCK_20_MHZ_VAL 20 -#define SPI_MAX_CLOCK_25_MHZ_VAL 25 -#define SPI_MAX_CLOCK_33_MHZ_VAL 33 -#define SPI_MAX_CLOCK_40_MHZ_VAL 40 -#define SPI_MAX_CLOCK_50_MHZ_VAL 50 - -#define SPI_MAX_CLOCK_20_MHZ 0x00 -#define SPI_MAX_CLOCK_25_MHZ 0x01 -#define SPI_MAX_CLOCK_33_MHZ 0x02 -#define SPI_MAX_CLOCK_40_MHZ 0x03 -#define SPI_MAX_CLOCK_50_MHZ 0x04 -#define SPI_MAX_CLOCK_MASK 0xF8 - -#define SPI_CLOCK_RATIO_1_VAL 1 -#define SPI_CLOCK_RATIO_2_VAL 2 - -#define SPI_CLOCK_RATIO_1 0x07 -#define SPI_CLOCK_RATIO_2 0x08 - -#define SPI_NORMAL_MODE_VAL "normal" -#define SPI_SINGLE_MODE_VAL "fast" -#define SPI_DUAL_MODE_VAL "dual" -#define SPI_QUAD_MODE_VAL "quad" - -#define SPI_NORMAL_MODE 0x00 -#define SPI_SINGLE_MODE 0x01 -#define SPI_DUAL_MODE 0x03 -#define SPI_QUAD_MODE 0x04 - -#define SPI_UNLIMITED_BURST_ENABLE 0x08 - -#define FLASH_SIZE_1_MBYTES_VAL 1 -#define FLASH_SIZE_2_MBYTES_VAL 2 -#define FLASH_SIZE_4_MBYTES_VAL 4 -#define FLASH_SIZE_8_MBYTES_VAL 8 -#define FLASH_SIZE_16_MBYTES_VAL 16 - -#define FLASH_SIZE_1_MBYTES 0x01 -#define FLASH_SIZE_2_MBYTES 0x03 -#define FLASH_SIZE_4_MBYTES 0x07 -#define FLASH_SIZE_8_MBYTES 0x0F -#define FLASH_SIZE_16_MBYTES 0x1F +#define BIN_FW_HDR_CRC_DISABLE 0x0001 +#define BIN_FW_CRC_DISABLE 0x0002 +#define BIN_FW_START 0x0004 +#define BIN_FW_SIZE 0x0008 +#define BIN_CK_FIRMWARE 0x0010 +#define BIN_FW_CKS_START 0x0020 +#define BIN_FW_CKS_SIZE 0x0040 +#define BIN_FW_CHANGE_SIG 0x0080 +#define BIN_FW_SPI_MAX_CLK 0x0100 +#define BIN_FW_LOAD_START_ADDR 0x0200 +#define BIN_FW_ENTRY_POINT 0x0400 +#define BIN_FW_LENGTH 0x0800 +#define BIN_FW_HDR_OFFSET 0x1000 +#define BIN_FW_USER_ARM_RESET 0x2000 +#define BIN_UNLIM_BURST_ENABLE 0x4000 + +#define ECRP_OFFSET 0x01 +#define ECRP_INPUT_FILE 0x02 +#define ECRP_OUTPUT_FILE 0x04 + +#define SPI_MAX_CLOCK_20_MHZ_VAL 20 +#define SPI_MAX_CLOCK_25_MHZ_VAL 25 +#define SPI_MAX_CLOCK_33_MHZ_VAL 33 +#define SPI_MAX_CLOCK_40_MHZ_VAL 40 +#define SPI_MAX_CLOCK_50_MHZ_VAL 50 + +#define SPI_MAX_CLOCK_20_MHZ 0x00 +#define SPI_MAX_CLOCK_25_MHZ 0x01 +#define SPI_MAX_CLOCK_33_MHZ 0x02 +#define SPI_MAX_CLOCK_40_MHZ 0x03 +#define SPI_MAX_CLOCK_50_MHZ 0x04 +#define SPI_MAX_CLOCK_MASK 0xF8 + +#define SPI_CLOCK_RATIO_1_VAL 1 +#define SPI_CLOCK_RATIO_2_VAL 2 + +#define SPI_CLOCK_RATIO_1 0x07 +#define SPI_CLOCK_RATIO_2 0x08 + +#define SPI_NORMAL_MODE_VAL "normal" +#define SPI_SINGLE_MODE_VAL "fast" +#define SPI_DUAL_MODE_VAL "dual" +#define SPI_QUAD_MODE_VAL "quad" + +#define SPI_NORMAL_MODE 0x00 +#define SPI_SINGLE_MODE 0x01 +#define SPI_DUAL_MODE 0x03 +#define SPI_QUAD_MODE 0x04 + +#define SPI_UNLIMITED_BURST_ENABLE 0x08 + +#define FLASH_SIZE_1_MBYTES_VAL 1 +#define FLASH_SIZE_2_MBYTES_VAL 2 +#define FLASH_SIZE_4_MBYTES_VAL 4 +#define FLASH_SIZE_8_MBYTES_VAL 8 +#define FLASH_SIZE_16_MBYTES_VAL 16 + +#define FLASH_SIZE_1_MBYTES 0x01 +#define FLASH_SIZE_2_MBYTES 0x03 +#define FLASH_SIZE_4_MBYTES 0x07 +#define FLASH_SIZE_8_MBYTES 0x0F +#define FLASH_SIZE_16_MBYTES 0x1F /* Header fields default values. */ -#define SPI_MAX_CLOCK_DEFAULT SPI_MAX_CLOCK_20_MHZ_VAL -#define SPI_READ_MODE_DEFAULT SPI_NORMAL_MODE -#define FLASH_SIZE_DEFAULT FLASH_SIZE_16_MBYTES_VAL -#define FW_CRC_START_ADDR 0x00000000 +#define SPI_MAX_CLOCK_DEFAULT SPI_MAX_CLOCK_20_MHZ_VAL +#define SPI_READ_MODE_DEFAULT SPI_NORMAL_MODE +#define FLASH_SIZE_DEFAULT FLASH_SIZE_16_MBYTES_VAL +#define FW_CRC_START_ADDR 0x00000000 -#define ADDR_16_BYTES_ALIGNED_MASK 0x0000000F -#define ADDR_4_BYTES_ALIGNED_MASK 0x00000003 +#define ADDR_16_BYTES_ALIGNED_MASK 0x0000000F +#define ADDR_4_BYTES_ALIGNED_MASK 0x00000003 -#define MAX_FLASH_SIZE 0x03ffffff +#define MAX_FLASH_SIZE 0x03ffffff /* Chips: convert from name to index. */ enum npcx_chip_ram_variant { @@ -172,25 +169,25 @@ enum npcx_chip_ram_variant { NPCX_CHIP_RAM_VAR_NONE }; -#define DEFAULT_CHIP NPCX5M5G +#define DEFAULT_CHIP NPCX5M5G /* NPCX5 */ -#define NPCX5M5G_RAM_ADDR 0x100A8000 -#define NPCX5M5G_RAM_SIZE 0x20000 -#define NPCX5M6G_RAM_ADDR 0x10088000 -#define NPCX5M6G_RAM_SIZE 0x40000 +#define NPCX5M5G_RAM_ADDR 0x100A8000 +#define NPCX5M5G_RAM_SIZE 0x20000 +#define NPCX5M6G_RAM_ADDR 0x10088000 +#define NPCX5M6G_RAM_SIZE 0x40000 /* NPCX7 */ -#define NPCX7M5X_RAM_ADDR 0x100A8000 -#define NPCX7M5X_RAM_SIZE 0x20000 -#define NPCX7M6X_RAM_ADDR 0x10090000 -#define NPCX7M6X_RAM_SIZE 0x40000 -#define NPCX7M7X_RAM_ADDR 0x10070000 -#define NPCX7M7X_RAM_SIZE 0x60000 +#define NPCX7M5X_RAM_ADDR 0x100A8000 +#define NPCX7M5X_RAM_SIZE 0x20000 +#define NPCX7M6X_RAM_ADDR 0x10090000 +#define NPCX7M6X_RAM_SIZE 0x40000 +#define NPCX7M7X_RAM_ADDR 0x10070000 +#define NPCX7M7X_RAM_SIZE 0x60000 /* NPCX9 */ -#define NPCX9M3X_RAM_ADDR 0x10080000 -#define NPCX9M3X_RAM_SIZE 0x50000 -#define NPCX9M6X_RAM_ADDR 0x10090000 -#define NPCX9M6X_RAM_SIZE 0x40000 +#define NPCX9M3X_RAM_ADDR 0x10080000 +#define NPCX9M3X_RAM_SIZE 0x50000 +#define NPCX9M6X_RAM_ADDR 0x10090000 +#define NPCX9M6X_RAM_SIZE 0x40000 /*--------------------------------------------------------------------------- Typedefs @@ -198,47 +195,39 @@ enum npcx_chip_ram_variant { /* Parameters for Binary manipulation */ struct tbinparams { - unsigned int anchor; - unsigned short ext_anchor; - unsigned char spi_max_clk; - unsigned char spi_clk_ratio; - unsigned char spi_read_mode; - unsigned char err_detec_cnf; - unsigned int fw_load_addr; - unsigned int fw_ep; - unsigned int fw_err_detec_s_addr; - unsigned int fw_err_detec_e_addr; - unsigned int fw_len; - unsigned int flash_size; - unsigned int hdr_crc; - unsigned int fw_crc; - unsigned int fw_hdr_offset; - unsigned int bin_params; + unsigned int anchor; + unsigned short ext_anchor; + unsigned char spi_max_clk; + unsigned char spi_clk_ratio; + unsigned char spi_read_mode; + unsigned char err_detec_cnf; + unsigned int fw_load_addr; + unsigned int fw_ep; + unsigned int fw_err_detec_s_addr; + unsigned int fw_err_detec_e_addr; + unsigned int fw_len; + unsigned int flash_size; + unsigned int hdr_crc; + unsigned int fw_crc; + unsigned int fw_hdr_offset; + unsigned int bin_params; } bin_params_struct; -enum verbose_level { - NO_VERBOSE = 0, - REGULAR_VERBOSE, - SUPER_VERBOSE -}; +enum verbose_level { NO_VERBOSE = 0, REGULAR_VERBOSE, SUPER_VERBOSE }; -enum calc_type { - CALC_TYPE_NONE = 0, - CALC_TYPE_CHECKSUM , - CALC_TYPE_CRC -}; +enum calc_type { CALC_TYPE_NONE = 0, CALC_TYPE_CHECKSUM, CALC_TYPE_CRC }; struct chip_info { - unsigned int ram_addr; - unsigned int ram_size; + unsigned int ram_addr; + unsigned int ram_size; } chip_info_struct; /*------------------------------------------------------------------------*/ /* CRC Variable bit operation macros */ /*------------------------------------------------------------------------*/ -#define NUM_OF_BYTES 32 -#define READ_VAR_BIT(var, nb) (((var) >> (nb)) & 0x1) -#define SET_VAR_BIT(var, nb, val) ((var) |= ((val)<<(nb))) +#define NUM_OF_BYTES 32 +#define READ_VAR_BIT(var, nb) (((var) >> (nb)) & 0x1) +#define SET_VAR_BIT(var, nb, val) ((var) |= ((val) << (nb))) /*--------------------------------------------------------------------------- Functions Declaration @@ -254,35 +243,27 @@ void init_calculation(unsigned int *check_sum_crc); void finalize_calculation(unsigned int *check_sum_crc); void update_calculation_information(unsigned char crc_con_dat); - /* Checksum calculation etc. (BIN Specific) */ int calc_header_crc_bin(unsigned int *pointer_header_checksum); -int calc_firmware_csum_bin(unsigned int *p_cksum, - unsigned int fw_offset, - unsigned int fw_length); +int calc_firmware_csum_bin(unsigned int *p_cksum, unsigned int fw_offset, + unsigned int fw_length); /* Checksum calculation etc. (ERP Specific) */ int calc_erp_csum_bin(unsigned short *region_pointer_header_checksum, - unsigned int region_pointer_ofs); + unsigned int region_pointer_ofs); /* No words - General */ void exit_with_usage(void); -int copy_file_to_file(char *dst_file_name, - char *src_file_name, - int offset, - int origin); -int write_to_file(unsigned int write_value, - unsigned int offset, - unsigned char num_of_bytes, - char *print_string); -int read_from_file(unsigned int offset, - unsigned char size_to_read, - unsigned int *read_value, - char *print_string); +int copy_file_to_file(char *dst_file_name, char *src_file_name, int offset, + int origin); +int write_to_file(unsigned int write_value, unsigned int offset, + unsigned char num_of_bytes, char *print_string); +int read_from_file(unsigned int offset, unsigned char size_to_read, + unsigned int *read_value, char *print_string); /* Nice Particular Printf - General */ -__attribute__((__format__(__printf__, 2, 3))) -void my_printf(int error_level, char *fmt, ...); +__attribute__((__format__(__printf__, 2, 3))) void my_printf(int error_level, + char *fmt, ...); int str_cmp_no_case(const char *s1, const char *s2); int get_file_length(FILE *stream); diff --git a/util/ectool.c b/util/ectool.c index 028828ebd5..b05e75d14e 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -1,8 +1,9 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. +/* Copyright 2013 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +#include <assert.h> #include <ctype.h> #include <errno.h> #include <getopt.h> @@ -42,8 +43,8 @@ */ #define HELLO_RESP(in_data) ((in_data) + 0x01020304) -#define USB_VID_GOOGLE 0x18d1 -#define USB_PID_HAMMER 0x5022 +#define USB_VID_GOOGLE 0x18d1 +#define USB_PID_HAMMER 0x5022 /* Command line options */ enum { @@ -55,17 +56,15 @@ enum { OPT_DEVICE, }; -static struct option long_opts[] = { - {"dev", 1, 0, OPT_DEV}, - {"interface", 1, 0, OPT_INTERFACE}, - {"name", 1, 0, OPT_NAME}, - {"ascii", 0, 0, OPT_ASCII}, - {"i2c_bus", 1, 0, OPT_I2C_BUS}, - {"device", 1, 0, OPT_DEVICE}, - {NULL, 0, 0, 0} -}; +static struct option long_opts[] = { { "dev", 1, 0, OPT_DEV }, + { "interface", 1, 0, OPT_INTERFACE }, + { "name", 1, 0, OPT_NAME }, + { "ascii", 0, 0, OPT_ASCII }, + { "i2c_bus", 1, 0, OPT_I2C_BUS }, + { "device", 1, 0, OPT_DEVICE }, + { NULL, 0, 0, 0 } }; -#define GEC_LOCK_TIMEOUT_SECS 30 /* 30 secs */ +#define GEC_LOCK_TIMEOUT_SECS 30 /* 30 secs */ const char help_str[] = "Commands:\n" @@ -216,6 +215,8 @@ const char help_str[] = " Set the color of an LED or query brightness range\n" " lightbar [CMDS]\n" " Various lightbar control commands\n" + " locatechip <type> <index>\n" + " Get the addresses and ports of i2c connected and embedded chips\n" " mkbpget <buttons|switches>\n" " Get MKBP buttons/switches supported mask and current state\n" " mkbpwakemask <get|set> <event|hostevent> [mask]\n" @@ -275,7 +276,7 @@ const char help_str[] = " readtest <patternoffset> <size>\n" " Reads a pattern from the EC via LPC\n" " reboot_ec <RO|RW|cold|hibernate|hibernate-clear-ap-off|disable-jump|cold-ap-off>" - " [at-shutdown|switch-slot]\n" + " [at-shutdown|switch-slot]\n" " Reboot EC to RO or RW\n" " reboot_ap_on_g3 [<delay>]\n" " Requests that the EC will automatically reboot the AP after a\n" @@ -344,17 +345,17 @@ const char help_str[] = " usbmux <mux>\n" " Set USB mux switch state\n" " usbpd <port> <auto | " - "[toggle|toggle-off|sink|source] [none|usb|dp|dock] " - "[dr_swap|pr_swap|vconn_swap]>\n" + "[toggle|toggle-off|sink|source] [none|usb|dp|dock] " + "[dr_swap|pr_swap|vconn_swap]>\n" " Control USB PD/type-C [deprecated]\n" " usbpddps [enable | disable]\n" " Enable or disable dynamic pdo selection\n" " usbpdmuxinfo [tsv]\n" " Get USB-C SS mux info.\n" " tsv: Output as tab separated values. Columns are defined " - "as:\n" + "as:\n" " Port, USB enabled, DP enabled, Polarity, HPD IRQ, " - "HPD LVL\n" + "HPD LVL\n" " usbpdpower [port]\n" " Get USB PD power information\n" " version\n" @@ -366,17 +367,18 @@ const char help_str[] = ""; /* Note: depends on enum ec_image */ -static const char * const image_names[] = {"unknown", "RO", "RW"}; +static const char *const image_names[] = { "unknown", "RO", "RW" }; /* Note: depends on enum ec_led_colors */ -static const char * const led_color_names[] = { - "red", "green", "blue", "yellow", "white", "amber"}; +static const char *const led_color_names[] = { "red", "green", "blue", + "yellow", "white", "amber" }; BUILD_ASSERT(ARRAY_SIZE(led_color_names) == EC_LED_COLOR_COUNT); /* Note: depends on enum ec_led_id */ -static const char * const led_names[] = { - "battery", "power", "adapter", "left", "right", "recovery_hwreinit", - "sysrq debug" }; +static const char *const led_names[] = { "battery", "power", + "adapter", "left", + "right", "recovery_hwreinit", + "sysrq debug" }; BUILD_ASSERT(ARRAY_SIZE(led_names) == EC_LED_ID_COUNT); /* ASCII mode for printing, default off */ @@ -395,7 +397,7 @@ int parse_bool(const char *s, int *dest) *dest = 0; return 1; } else if (!strcasecmp(s, "on") || !strncasecmp(s, "ena", 3) || - tolower(*s) == 't' || tolower(*s) == 'y') { + tolower(*s) == 't' || tolower(*s) == 'y') { *dest = 1; return 1; } else { @@ -403,6 +405,48 @@ int parse_bool(const char *s, int *dest) } } +/** + * @brief Find the enum value associated the string of enum text or value. + * + * @param str The input string to parse an enum from. + * @param enum_text_map The array that maps enum value (index) to text. + * @param enum_text_map_length The length of the enum_text_map array. + * @param enum_value Output parsed enum value. + * @return int 0 on success, -1 if result cannot be found + */ +static int find_enum_from_text(const char *str, + const char *const enum_text_map[], + long enum_text_map_length, long *enum_value) +{ + char *e; + long value; + + assert(str); + assert(enum_value); + assert(enum_text_map); + assert(enum_text_map_length >= 0); + + if (*str == '\0') + return -1; + + value = strtol(str, &e, 0); + if (!e || !*e) { + *enum_value = value; + return 0; + } + + for (value = 0; value < enum_text_map_length; value++) { + if (!enum_text_map[value]) + continue; + if (strcasecmp(str, enum_text_map[value]) == 0) { + *enum_value = value; + return 0; + } + } + + return -1; +} + void print_help(const char *prog, int print_cmds) { printf("Usage: %s [--dev=n] " @@ -546,11 +590,11 @@ int cmd_add_entropy(int argc, char *argv[]) } /* Abort if EC returns an error other than EC_RES_BUSY. */ - if (rv <= -EECRESULT && rv != -EECRESULT-EC_RES_BUSY) + if (rv <= -EECRESULT && rv != -EECRESULT - EC_RES_BUSY) goto out; } - rv = -EECRESULT-EC_RES_TIMEOUT; + rv = -EECRESULT - EC_RES_TIMEOUT; out: fprintf(stderr, "Failed to add entropy: %d\n", rv); return rv; @@ -595,8 +639,8 @@ int cmd_hibdelay(int argc, char *argv[]) } } - rv = ec_command(EC_CMD_HIBERNATION_DELAY, 0, &p, sizeof(p), - &r, sizeof(r)); + rv = ec_command(EC_CMD_HIBERNATION_DELAY, 0, &p, sizeof(p), &r, + sizeof(r)); if (rv < 0) { fprintf(stderr, "err: rv=%d\n", rv); return -1; @@ -611,18 +655,18 @@ int cmd_hibdelay(int argc, char *argv[]) static void cmd_hostevent_help(char *cmd) { fprintf(stderr, - " Usage: %s get <type>\n" - " Usage: %s set <type> <value>\n" - " <type> is one of:\n" - " 1: EC_HOST_EVENT_B\n" - " 2: EC_HOST_EVENT_SCI_MASK\n" - " 3: EC_HOST_EVENT_SMI_MASK\n" - " 4: EC_HOST_EVENT_ALWAYS_REPORT_MASK\n" - " 5: EC_HOST_EVENT_ACTIVE_WAKE_MASK\n" - " 6: EC_HOST_EVENT_LAZY_WAKE_MASK_S0IX\n" - " 7: EC_HOST_EVENT_LAZY_WAKE_MASK_S3\n" - " 8: EC_HOST_EVENT_LAZY_WAKE_MASK_S5\n" - , cmd, cmd); + " Usage: %s get <type>\n" + " Usage: %s set <type> <value>\n" + " <type> is one of:\n" + " 1: EC_HOST_EVENT_B\n" + " 2: EC_HOST_EVENT_SCI_MASK\n" + " 3: EC_HOST_EVENT_SMI_MASK\n" + " 4: EC_HOST_EVENT_ALWAYS_REPORT_MASK\n" + " 5: EC_HOST_EVENT_ACTIVE_WAKE_MASK\n" + " 6: EC_HOST_EVENT_LAZY_WAKE_MASK_S0IX\n" + " 7: EC_HOST_EVENT_LAZY_WAKE_MASK_S3\n" + " 8: EC_HOST_EVENT_LAZY_WAKE_MASK_S5\n", + cmd, cmd); } static int cmd_hostevent(int argc, char *argv[]) @@ -693,12 +737,12 @@ static int get_latest_cmd_version(uint8_t cmd, int *version) *version = 0; /* Figure out the latest version of the given command the EC supports */ p.cmd = cmd; - rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 0, &p, sizeof(p), - &r, sizeof(r)); + rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 0, &p, sizeof(p), &r, + sizeof(r)); if (rv < 0) { if (rv == -EC_RES_INVALID_PARAM) printf("Command 0x%02x not supported by EC.\n", - EC_CMD_GET_CMD_VERSIONS); + EC_CMD_GET_CMD_VERSIONS); return rv; } @@ -721,7 +765,8 @@ int cmd_hostsleepstate(int argc, char *argv[]) uint32_t timeout, transitions; if (argc < 2) { - fprintf(stderr, "Usage: %s " + fprintf(stderr, + "Usage: %s " "[suspend|wsuspend|resume|freeze|thaw] [timeout]\n", argv[0]); return -1; @@ -751,8 +796,7 @@ int cmd_hostsleepstate(int argc, char *argv[]) if ((*afterscan != '\0') || (afterscan == argv[2])) { - fprintf(stderr, - "Invalid value: %s\n", + fprintf(stderr, "Invalid value: %s\n", argv[2]); return -1; @@ -789,8 +833,7 @@ int cmd_hostsleepstate(int argc, char *argv[]) EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK; printf("%s%d sleep line transitions.\n", - timeout ? "Timeout: " : "", - transitions); + timeout ? "Timeout: " : "", transitions); } return 0; @@ -799,7 +842,7 @@ int cmd_hostsleepstate(int argc, char *argv[]) int cmd_test(int argc, char *argv[]) { struct ec_params_test_protocol p = { - .buf = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + .buf = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 } }; @@ -808,8 +851,7 @@ int cmd_test(int argc, char *argv[]) char *e; if (argc < 3) { - fprintf(stderr, "Usage: %s result length [version]\n", - argv[0]); + fprintf(stderr, "Usage: %s result length [version]\n", argv[0]); return -1; } @@ -832,8 +874,8 @@ int cmd_test(int argc, char *argv[]) } } - rv = ec_command(EC_CMD_TEST_PROTOCOL, version, - &p, sizeof(p), &r, sizeof(r)); + rv = ec_command(EC_CMD_TEST_PROTOCOL, version, &p, sizeof(p), &r, + sizeof(r)); printf("rv = %d\n", rv); return rv; @@ -856,15 +898,15 @@ int cmd_s5(int argc, char *argv[]) p.value = param; } - rv = ec_command(EC_CMD_GSV_PAUSE_IN_S5, 0, - &p, sizeof(p), &r, sizeof(r)); + rv = ec_command(EC_CMD_GSV_PAUSE_IN_S5, 0, &p, sizeof(p), &r, + sizeof(r)); if (rv > 0) printf("%s\n", r.value ? "on" : "off"); return rv < 0; } -static const char * const ec_feature_names[] = { +static const char *const ec_feature_names[] = { [EC_FEATURE_LIMITED] = "Limited image, load RW for more", [EC_FEATURE_FLASH] = "Flash", [EC_FEATURE_PWM_FAN] = "Direct Fan power management", @@ -913,6 +955,7 @@ static const char * const ec_feature_names[] = { [EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK] = "AP ack for Type-C mux configuration", [EC_FEATURE_S4_RESIDENCY] = "S4 residency", + [EC_FEATURE_TYPEC_AP_MUX_SET] = "AP directed mux sets", }; int cmd_inventory(int argc, char *argv[]) @@ -933,15 +976,14 @@ int cmd_inventory(int argc, char *argv[]) strlen(ec_feature_names[idx]) == 0) printf("%-4d: Unknown feature\n", idx); else - printf("%-4d: %s support\n", - idx, ec_feature_names[idx]); + printf("%-4d: %s support\n", idx, + ec_feature_names[idx]); } } } return 0; } - int cmd_cmdversions(int argc, char *argv[]) { struct ec_params_get_cmd_versions p; @@ -961,8 +1003,8 @@ int cmd_cmdversions(int argc, char *argv[]) } p.cmd = cmd; - rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 0, &p, sizeof(p), - &r, sizeof(r)); + rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 0, &p, sizeof(p), &r, + sizeof(r)); if (rv < 0) { if (rv == -EC_RES_INVALID_PARAM) printf("Command 0x%02x not supported by EC.\n", cmd); @@ -970,8 +1012,8 @@ int cmd_cmdversions(int argc, char *argv[]) return rv; } - printf("Command 0x%02x supports version mask 0x%08x\n", - cmd, r.version_mask); + printf("Command 0x%02x supports version mask 0x%08x\n", cmd, + r.version_mask); return 0; } @@ -982,7 +1024,7 @@ int cmd_cmdversions(int argc, char *argv[]) */ static const char *reset_cause_to_str(uint16_t cause) { - static const char * const reset_causes[] = { + static const char *const reset_causes[] = { "(reset unknown)", "reset: board custom", "reset: ap hang detected", @@ -997,7 +1039,7 @@ static const char *reset_cause_to_str(uint16_t cause) }; BUILD_ASSERT(ARRAY_SIZE(reset_causes) == CHIPSET_RESET_COUNT); - static const char * const shutdown_causes[] = { + static const char *const shutdown_causes[] = { "shutdown: power failure", "shutdown: during EC initialization", "shutdown: board custom", @@ -1031,8 +1073,8 @@ int cmd_uptimeinfo(int argc, char *argv[]) int i; int flag_count; uint32_t flag; - static const char * const reset_flag_descs[] = { - #include "reset_flag_desc.inc" + static const char *const reset_flag_descs[] = { +#include "reset_flag_desc.inc" }; if (argc != 1) { @@ -1047,9 +1089,8 @@ int cmd_uptimeinfo(int argc, char *argv[]) return rv; } - printf("EC uptime: %d.%03d seconds\n", - r.time_since_ec_boot_ms / 1000, - r.time_since_ec_boot_ms % 1000); + printf("EC uptime: %d.%03d seconds\n", r.time_since_ec_boot_ms / 1000, + r.time_since_ec_boot_ms % 1000); printf("AP resets since EC boot: %d\n", r.ap_resets_since_ec_boot); @@ -1059,9 +1100,9 @@ int cmd_uptimeinfo(int argc, char *argv[]) continue; printf("\t%d.%03d: %s\n", - r.recent_ap_reset[i].reset_time_ms / 1000, - r.recent_ap_reset[i].reset_time_ms % 1000, - reset_cause_to_str(r.recent_ap_reset[i].reset_cause)); + r.recent_ap_reset[i].reset_time_ms / 1000, + r.recent_ap_reset[i].reset_time_ms % 1000, + reset_cause_to_str(r.recent_ap_reset[i].reset_cause)); } printf("EC reset flags at last EC boot: "); @@ -1112,11 +1153,11 @@ int cmd_version(int argc, char *argv[]) goto exit; } - rv = ec_command(EC_CMD_GET_BUILD_INFO, 0, - NULL, 0, ec_inbuf, ec_max_insize); + rv = ec_command(EC_CMD_GET_BUILD_INFO, 0, NULL, 0, ec_inbuf, + ec_max_insize); if (rv < 0) { fprintf(stderr, "ERROR: EC_CMD_GET_BUILD_INFO failed: %d\n", - rv); + rv); goto exit; } @@ -1137,7 +1178,8 @@ int cmd_version(int argc, char *argv[]) printf("RW cros fwid: %s\n", r.cros_fwid_rw); printf("Firmware copy: %s\n", (r.current_image < ARRAY_SIZE(image_names) ? - image_names[r.current_image] : "?")); + image_names[r.current_image] : + "?")); printf("Build info: %s\n", build_string); exit: printf("Tool version: %s %s %s\n", CROS_ECTOOL_VERSION, DATE, BUILDER); @@ -1145,7 +1187,6 @@ exit: return rv; } - int cmd_read_test(int argc, char *argv[]) { struct ec_params_read_test p; @@ -1180,8 +1221,8 @@ int cmd_read_test(int argc, char *argv[]) for (i = 0; i < size; i += sizeof(r.data)) { p.offset = offset + i / sizeof(uint32_t); p.size = MIN(size - i, sizeof(r.data)); - rv = ec_command(EC_CMD_READ_TEST, 0, &p, sizeof(p), - &r, sizeof(r)); + rv = ec_command(EC_CMD_READ_TEST, 0, &p, sizeof(p), &r, + sizeof(r)); if (rv < 0) { fprintf(stderr, "Read error at offset %d\n", i); free(buf); @@ -1210,7 +1251,6 @@ int cmd_read_test(int argc, char *argv[]) return 0; } - int cmd_reboot_ec(int argc, char *argv[]) { struct ec_params_reboot_ec p; @@ -1293,22 +1333,25 @@ int cmd_reboot_ap_on_g3(int argc, char *argv[]) static void cmd_rgbkbd_help(char *cmd) { fprintf(stderr, - " Usage1: %s <key> <RGB> [<RGB> ...]\n" - " Set the color of <key> to <RGB>. Multiple colors for\n" - " adjacent keys can be set at once.\n" - "\n" - " Usage2: %s clear <RGB>\n" - " Set the color of all keys to <RGB>.\n" - "\n" - " Usage3: %s demo <num>\n" - " Run demo-<num>. 0: Off, 1: Flow, 2: Dot.\n" - "\n" - " Usage4: %s scale <key> <val>\n" - " Set the scale parameter of key_<key> to <val>.\n" - " <val> is a 24-bit integer where scale values are encoded\n" - " as R=23:16, G=15:8, B=7:0.\n" - "\n", - cmd, cmd, cmd, cmd); + " Usage1: %s <key> <RGB> [<RGB> ...]\n" + " Set the color of <key> to <RGB>. Multiple colors for\n" + " adjacent keys can be set at once.\n" + "\n" + " Usage2: %s clear <RGB>\n" + " Set the color of all keys to <RGB>.\n" + "\n" + " Usage3: %s demo <num>\n" + " Run demo-<num>. 0: Off, 1: Flow, 2: Dot.\n" + "\n" + " Usage4: %s scale <key> <val>\n" + " Set the scale parameter of key_<key> to <val>.\n" + " <val> is a 24-bit integer where scale values are encoded\n" + " as R=23:16, G=15:8, B=7:0.\n" + "\n" + " Usage5: %s getconfig\n" + " Get the HW config supported.\n" + "\n", + cmd, cmd, cmd, cmd, cmd); } static int cmd_rgbkbd_parse_rgb_text(const char *text, struct rgb_s *color) @@ -1336,7 +1379,7 @@ static int cmd_rgbkbd_set_color(int argc, char *argv[]) int rv = -1; outlen = sizeof(*p) + sizeof(struct rgb_s) * EC_RGBKBD_MAX_KEY_COUNT; - p = malloc(outlen); + p = (struct ec_params_rgbkbd_set_color *)malloc(outlen); if (p == NULL) return -1; memset(p, 0, outlen); @@ -1372,26 +1415,24 @@ static int cmd_rgbkbd(int argc, char *argv[]) { int val; char *e; - int rv = -1;; + int rv = -1; + struct ec_params_rgbkbd p; + struct ec_response_rgbkbd r; - if (argc < 3) { + if (argc < 2) { cmd_rgbkbd_help(argv[0]); return -1; } if (argc == 3 && !strcasecmp(argv[1], "clear")) { /* Usage 2 */ - struct ec_params_rgbkbd p; - p.subcmd = EC_RGBKBD_SUBCMD_CLEAR; if (cmd_rgbkbd_parse_rgb_text(argv[2], &p.color)) return -1; - rv = ec_command(EC_CMD_RGBKBD, 0, &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_RGBKBD, 0, &p, sizeof(p), &r, sizeof(r)); } else if (argc == 3 && !strcasecmp(argv[1], "demo")) { /* Usage 3 */ - struct ec_params_rgbkbd p; - val = strtol(argv[2], &e, 0); if ((e && *e) || val >= EC_RGBKBD_DEMO_COUNT) { fprintf(stderr, "Invalid demo id: %s\n", argv[2]); @@ -1399,11 +1440,9 @@ static int cmd_rgbkbd(int argc, char *argv[]) } p.subcmd = EC_RGBKBD_SUBCMD_DEMO; p.demo = val; - rv = ec_command(EC_CMD_RGBKBD, 0, &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_RGBKBD, 0, &p, sizeof(p), &r, sizeof(r)); } else if (argc == 4 && !strcasecmp(argv[1], "scale")) { /* Usage 4 */ - struct ec_params_rgbkbd p; - val = strtol(argv[2], &e, 0); if ((e && *e) || val > EC_RGBKBD_MAX_KEY_COUNT) { fprintf(stderr, "Invalid key number: %s\n", argv[2]); @@ -1415,7 +1454,35 @@ static int cmd_rgbkbd(int argc, char *argv[]) return -1; } p.subcmd = EC_RGBKBD_SUBCMD_SET_SCALE; - rv = ec_command(EC_CMD_RGBKBD, 0, &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_RGBKBD, 0, &p, sizeof(p), &r, sizeof(r)); + } else if (argc == 2 && !strcasecmp(argv[1], "getconfig")) { + /* Usage 5 */ + const char *type; + + p.subcmd = EC_RGBKBD_SUBCMD_GET_CONFIG; + rv = ec_command(EC_CMD_RGBKBD, 0, &p, sizeof(p), &r, sizeof(r)); + + if (rv < 0) + return rv; + + switch ((enum ec_rgbkbd_type)r.rgbkbd_type) { + case EC_RGBKBD_TYPE_PER_KEY: + type = "EC_RGBKBD_TYPE_PER_KEY"; + break; + case EC_RGBKBD_TYPE_FOUR_ZONES_40_LEDS: + type = "EC_RGBKBD_TYPE_FOUR_ZONES_40_LEDS"; + break; + case EC_RGBKBD_TYPE_FOUR_ZONES_12_LEDS: + type = "EC_RGBKBD_TYPE_FOUR_ZONES_12_LEDS"; + break; + case EC_RGBKBD_TYPE_FOUR_ZONES_4_LEDS: + type = "EC_RGBKBD_TYPE_FOUR_ZONES_4_LEDS"; + break; + default: + type = "EC_RGBKBD_TYPE_UNKNOWN"; + } + + printf("RGBKBD_TYPE: %s\n", type); } else { /* Usage 1 */ rv = cmd_rgbkbd_set_color(argc, argv); @@ -1501,8 +1568,8 @@ int cmd_flash_info(int argc, char *argv[]) if (cmdver >= 1) { /* Fields added in ver.1 available */ - printf("WriteIdealSize %d\nFlags 0x%x\n", - r.write_ideal_size, r.flags); + printf("WriteIdealSize %d\nFlags 0x%x\n", r.write_ideal_size, + r.flags); } return 0; @@ -1590,8 +1657,8 @@ int cmd_flash_read(int argc, char *argv[]) uint8_t *buf; if (argc < 4) { - fprintf(stderr, - "Usage: %s <offset> <size> <filename>\n", argv[0]); + fprintf(stderr, "Usage: %s <offset> <size> <filename>\n", + argv[0]); return -1; } offset = strtol(argv[1], &e, 0); @@ -1654,8 +1721,7 @@ int cmd_flash_write(int argc, char *argv[]) printf("Writing to offset %d...\n", offset); /* Write data in chunks */ - rv = ec_flash_write((const uint8_t *)(buf), offset, - size); + rv = ec_flash_write((const uint8_t *)(buf), offset, size); free(buf); @@ -1705,7 +1771,6 @@ int cmd_flash_erase(int argc, char *argv[]) return 0; } - static void print_flash_protect_flags(const char *desc, uint32_t flags) { printf("%s 0x%08x", desc, flags); @@ -1736,7 +1801,6 @@ static void print_flash_protect_flags(const char *desc, uint32_t flags) printf("\n"); } - int cmd_flash_protect(int argc, char *argv[]) { struct ec_params_flash_protect p; @@ -1759,8 +1823,8 @@ int cmd_flash_protect(int argc, char *argv[]) p.mask |= EC_FLASH_PROTECT_RO_AT_BOOT; } - rv = ec_command(EC_CMD_FLASH_PROTECT, EC_VER_FLASH_PROTECT, - &p, sizeof(p), &r, sizeof(r)); + rv = ec_command(EC_CMD_FLASH_PROTECT, EC_VER_FLASH_PROTECT, &p, + sizeof(p), &r, sizeof(r)); if (rv < 0) return rv; if (rv < sizeof(r)) { @@ -1775,12 +1839,15 @@ int cmd_flash_protect(int argc, char *argv[]) /* Check if we got all the flags we asked for */ if ((r.flags & p.mask) != (p.flags & p.mask)) { - fprintf(stderr, "Unable to set requested flags " + fprintf(stderr, + "Unable to set requested flags " "(wanted mask 0x%08x flags 0x%08x)\n", p.mask, p.flags); if (p.mask & ~r.writable_flags) - fprintf(stderr, "Which is expected, because writable " - "mask is 0x%08x.\n", r.writable_flags); + fprintf(stderr, + "Which is expected, because writable " + "mask is 0x%08x.\n", + r.writable_flags); return -1; } @@ -1816,10 +1883,10 @@ int cmd_rw_hash_pd(int argc, char *argv[]) fprintf(stderr, "Bad RW hash\n"); return -1; } - rwp[0] = (uint8_t) (val >> 0) & 0xff; - rwp[1] = (uint8_t) (val >> 8) & 0xff; - rwp[2] = (uint8_t) (val >> 16) & 0xff; - rwp[3] = (uint8_t) (val >> 24) & 0xff; + rwp[0] = (uint8_t)(val >> 0) & 0xff; + rwp[1] = (uint8_t)(val >> 8) & 0xff; + rwp[2] = (uint8_t)(val >> 16) & 0xff; + rwp[3] = (uint8_t)(val >> 24) & 0xff; rwp += 4; } rv = ec_command(EC_CMD_USB_PD_RW_HASH_ENTRY, 0, p, sizeof(*p), NULL, 0); @@ -1832,8 +1899,8 @@ int cmd_rwsig_status(int argc, char *argv[]) int rv; struct ec_response_rwsig_check_status resp; - rv = ec_command(EC_CMD_RWSIG_CHECK_STATUS, 0, NULL, 0, - &resp, sizeof(resp)); + rv = ec_command(EC_CMD_RWSIG_CHECK_STATUS, 0, NULL, 0, &resp, + sizeof(resp)); if (rv < 0) return rv; @@ -1883,9 +1950,10 @@ enum rwsig_info_fields { RWSIG_INFO_FIELD_HASH_ALG = BIT(2), RWSIG_INFO_FIELD_KEY_IS_VALID = BIT(3), RWSIG_INFO_FIELD_KEY_ID = BIT(4), - RWSIG_INFO_FIELD_ALL = RWSIG_INFO_FIELD_SIG_ALG | - RWSIG_INFO_FIELD_KEY_VERSION | RWSIG_INFO_FIELD_HASH_ALG | - RWSIG_INFO_FIELD_KEY_IS_VALID | RWSIG_INFO_FIELD_KEY_ID + RWSIG_INFO_FIELD_ALL = + RWSIG_INFO_FIELD_SIG_ALG | RWSIG_INFO_FIELD_KEY_VERSION | + RWSIG_INFO_FIELD_HASH_ALG | RWSIG_INFO_FIELD_KEY_IS_VALID | + RWSIG_INFO_FIELD_KEY_ID }; static int rwsig_info(enum rwsig_info_fields fields) @@ -2070,7 +2138,6 @@ int cmd_sysinfo(int argc, char **argv) if (print_prefix) printf("Flags: "); printf("0x%08x\n", r.flags); - } if (fields & SYSINFO_FIELD_CURRENT_IMAGE) { @@ -2082,8 +2149,9 @@ int cmd_sysinfo(int argc, char **argv) return 0; sysinfo_error_usage: - fprintf(stderr, "Usage: %s " - "[flags|reset_flags|firmware_copy]\n", + fprintf(stderr, + "Usage: %s " + "[flags|reset_flags|firmware_copy]\n", argv[0]); return -1; } @@ -2138,8 +2206,8 @@ static void *fp_download_frame(struct ec_response_fp_info *info, int index) void *buffer; uint8_t *ptr; int cmdver = ec_cmd_version_supported(EC_CMD_FP_INFO, 1) ? 1 : 0; - int rsize = cmdver == 1 ? sizeof(*info) - : sizeof(struct ec_response_fp_info_v0); + int rsize = cmdver == 1 ? sizeof(*info) : + sizeof(struct ec_response_fp_info_v0); const int max_attempts = 3; int num_attempts; @@ -2152,7 +2220,7 @@ static void *fp_download_frame(struct ec_response_fp_info *info, int index) return NULL; if (index == FP_FRAME_INDEX_SIMPLE_IMAGE) { - size = (size_t)info->width * info->bpp/8 * info->height; + size = (size_t)info->width * info->bpp / 8 * info->height; index = FP_FRAME_INDEX_RAW_IMAGE; } else if (index == FP_FRAME_INDEX_RAW_IMAGE) { size = info->frame_size; @@ -2174,8 +2242,8 @@ static void *fp_download_frame(struct ec_response_fp_info *info, int index) num_attempts = 0; while (num_attempts < max_attempts) { num_attempts++; - rv = ec_command(EC_CMD_FP_FRAME, 0, &p, sizeof(p), - ptr, stride); + rv = ec_command(EC_CMD_FP_FRAME, 0, &p, sizeof(p), ptr, + stride); if (rv >= 0) break; if (rv == -EECRESULT - EC_RES_ACCESS_DENIED) @@ -2253,7 +2321,7 @@ int cmd_fp_mode(int argc, char *argv[]) printf("finger-up "); if (r.mode & FP_MODE_ENROLL_SESSION) printf("enroll%s ", - r.mode & FP_MODE_ENROLL_IMAGE ? "+image" : ""); + r.mode & FP_MODE_ENROLL_IMAGE ? "+image" : ""); if (r.mode & FP_MODE_MATCH) printf("match "); if (r.mode & FP_MODE_CAPTURE) @@ -2307,7 +2375,7 @@ int cmd_fp_stats(int argc, char *argv[]) printf("Invalid\n"); else printf("%d us (finger: %d)\n", r.matching_time_us, - r.template_matched); + r.template_matched); printf("Last overall time: "); if (r.timestamps_invalid) @@ -2323,8 +2391,8 @@ int cmd_fp_info(int argc, char *argv[]) struct ec_response_fp_info r; int rv; int cmdver = ec_cmd_version_supported(EC_CMD_FP_INFO, 1) ? 1 : 0; - int rsize = cmdver == 1 ? sizeof(r) - : sizeof(struct ec_response_fp_info_v0); + int rsize = cmdver == 1 ? sizeof(r) : + sizeof(struct ec_response_fp_info_v0); uint16_t dead; rv = ec_command(EC_CMD_FP_INFO, cmdver, NULL, 0, &r, rsize); @@ -2332,7 +2400,7 @@ int cmd_fp_info(int argc, char *argv[]) return rv; printf("Fingerprint sensor: vendor %x product %x model %x version %x\n", - r.vendor_id, r.product_id, r.model_id, r.version); + r.vendor_id, r.product_id, r.model_id, r.version); printf("Image: size %dx%d %d bpp\n", r.width, r.height, r.bpp); printf("Error flags: %s%s%s%s\n", r.errors & FP_ERROR_NO_IRQ ? "NO_IRQ " : "", @@ -2437,7 +2505,8 @@ int cmd_fp_frame(int argc, char *argv[]) { struct ec_response_fp_info r; int idx = (argc == 2 && !strcasecmp(argv[1], "raw")) ? - FP_FRAME_INDEX_RAW_IMAGE : FP_FRAME_INDEX_SIMPLE_IMAGE; + FP_FRAME_INDEX_RAW_IMAGE : + FP_FRAME_INDEX_SIMPLE_IMAGE; uint8_t *buffer = (uint8_t *)(fp_download_frame(&r, idx)); uint8_t *ptr = buffer; int x, y; @@ -2472,8 +2541,8 @@ int cmd_fp_template(int argc, char *argv[]) struct ec_params_fp_template *p = (struct ec_params_fp_template *)(ec_outbuf); /* TODO(b/78544921): removing 32 bits is a workaround for the MCU bug */ - int max_chunk = ec_max_outsize - - offsetof(struct ec_params_fp_template, data) - 4; + int max_chunk = ec_max_outsize - + offsetof(struct ec_params_fp_template, data) - 4; int idx = -1; char *e; int size; @@ -2513,8 +2582,9 @@ int cmd_fp_template(int argc, char *argv[]) if (!size) p->size |= FP_TEMPLATE_COMMIT; memcpy(p->data, buffer + offset, tlen); - rv = ec_command(EC_CMD_FP_TEMPLATE, 0, p, tlen + - offsetof(struct ec_params_fp_template, data), + rv = ec_command(EC_CMD_FP_TEMPLATE, 0, p, + tlen + offsetof(struct ec_params_fp_template, + data), NULL, 0); if (rv < 0) break; @@ -2547,8 +2617,8 @@ static int in_gfu_mode(int *opos, int port) p->port = port; p->svid_idx = 0; do { - ec_command(EC_CMD_USB_PD_GET_AMODE, 0, p, sizeof(*p), - ec_inbuf, ec_max_insize); + ec_command(EC_CMD_USB_PD_GET_AMODE, 0, p, sizeof(*p), ec_inbuf, + ec_max_insize); if (!r->svid || (r->svid == USB_VID_GOOGLE)) break; p->svid_idx++; @@ -2598,8 +2668,7 @@ static int enter_gfu_mode(int port) p->opos = opos; p->cmd = PD_ENTER_MODE; - ec_command(EC_CMD_USB_PD_SET_AMODE, 0, p, sizeof(*p), - NULL, 0); + ec_command(EC_CMD_USB_PD_SET_AMODE, 0, p, sizeof(*p), NULL, 0); usleep(500000); /* sleep to allow time for set mode */ gfu_mode = in_gfu_mode(&opos, port); } @@ -2629,8 +2698,8 @@ int cmd_pd_device_info(int argc, char *argv[]) p->port = port; r1 = (struct ec_params_usb_pd_discovery_entry *)ec_inbuf; - rv = ec_command(EC_CMD_USB_PD_DISCOVERY, 0, p, sizeof(*p), - ec_inbuf, ec_max_insize); + rv = ec_command(EC_CMD_USB_PD_DISCOVERY, 0, p, sizeof(*p), ec_inbuf, + ec_max_insize); if (rv < 0) return rv; @@ -2647,8 +2716,8 @@ int cmd_pd_device_info(int argc, char *argv[]) } p->port = port; - rv = ec_command(EC_CMD_USB_PD_DEV_INFO, 0, p, sizeof(*p), - ec_inbuf, ec_max_insize); + rv = ec_command(EC_CMD_USB_PD_DEV_INFO, 0, p, sizeof(*p), ec_inbuf, + ec_max_insize); if (rv < 0) return rv; @@ -2713,8 +2782,8 @@ int cmd_flash_pd(int argc, char *argv[]) p->port = port; p->cmd = USB_PD_FW_ERASE_SIG; p->size = 0; - rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0, - p, p->size + sizeof(*p), NULL, 0); + rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0, p, p->size + sizeof(*p), + NULL, 0); if (rv < 0) goto pd_flash_error; @@ -2725,8 +2794,8 @@ int cmd_flash_pd(int argc, char *argv[]) p->port = port; p->cmd = USB_PD_FW_REBOOT; p->size = 0; - rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0, - p, p->size + sizeof(*p), NULL, 0); + rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0, p, p->size + sizeof(*p), + NULL, 0); if (rv < 0) goto pd_flash_error; @@ -2745,8 +2814,8 @@ int cmd_flash_pd(int argc, char *argv[]) p->port = port; p->cmd = USB_PD_FW_FLASH_ERASE; p->size = 0; - rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0, - p, p->size + sizeof(*p), NULL, 0); + rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0, p, p->size + sizeof(*p), + NULL, 0); /* 3 secs should allow ample time for 2KB page erases at 40ms */ usleep(3000000); @@ -2764,8 +2833,8 @@ int cmd_flash_pd(int argc, char *argv[]) for (i = 0; i < fsize; i += step) { p->size = MIN(fsize - i, step); memcpy(data, buf + i, p->size); - rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0, - p, p->size + sizeof(*p), NULL, 0); + rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0, p, + p->size + sizeof(*p), NULL, 0); if (rv < 0) goto pd_flash_error; @@ -2783,8 +2852,8 @@ int cmd_flash_pd(int argc, char *argv[]) fprintf(stderr, "Rebooting PD into new RW\n"); p->cmd = USB_PD_FW_REBOOT; p->size = 0; - rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0, - p, p->size + sizeof(*p), NULL, 0); + rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0, p, p->size + sizeof(*p), + NULL, 0); if (rv < 0) goto pd_flash_error; @@ -2859,15 +2928,15 @@ int cmd_pd_get_amode(int argc, char *argv[]) p->svid_idx = 0; do { - ec_command(EC_CMD_USB_PD_GET_AMODE, 0, p, sizeof(*p), - ec_inbuf, ec_max_insize); + ec_command(EC_CMD_USB_PD_GET_AMODE, 0, p, sizeof(*p), ec_inbuf, + ec_max_insize); if (!r->svid) break; - printf("%cSVID:0x%04x ", (r->opos) ? '*' : ' ', - r->svid); + printf("%cSVID:0x%04x ", (r->opos) ? '*' : ' ', r->svid); for (i = 0; i < PDO_MODES; i++) { - printf("%c0x%08x ", (r->opos && (r->opos == i + 1)) ? - '*' : ' ', r->vdo[i]); + printf("%c0x%08x ", + (r->opos && (r->opos == i + 1)) ? '*' : ' ', + r->vdo[i]); } printf("\n"); p->svid_idx++; @@ -2898,7 +2967,6 @@ int cmd_serial_test(int argc, char *argv[]) return 0; } - int cmd_port_80_flood(int argc, char *argv[]) { int i; @@ -2970,8 +3038,8 @@ int cmd_smart_discharge(int argc, char *argv[]) } } - rv = ec_command(EC_CMD_SMART_DISCHARGE, 0, p, sizeof(*p), - r, ec_max_insize); + rv = ec_command(EC_CMD_SMART_DISCHARGE, 0, p, sizeof(*p), r, + ec_max_insize); if (rv < 0) { perror("ERROR: EC_CMD_SMART_DISCHARGE failed"); return rv; @@ -2984,10 +3052,10 @@ int cmd_smart_discharge(int argc, char *argv[]) } printf("%-27s %5d h\n", "Hours to zero capacity:", r->hours_to_zero); - printf("%-27s %5d mAh (%d %%)\n", "Stay-up threshold:", - r->dzone.stayup, cap > 0 ? r->dzone.stayup * 100 / cap : -1); - printf("%-27s %5d mAh (%d %%)\n", "Cutoff threshold:", - r->dzone.cutoff, cap > 0 ? r->dzone.cutoff * 100 / cap : -1); + printf("%-27s %5d mAh (%d %%)\n", "Stay-up threshold:", r->dzone.stayup, + cap > 0 ? r->dzone.stayup * 100 / cap : -1); + printf("%-27s %5d mAh (%d %%)\n", "Cutoff threshold:", r->dzone.cutoff, + cap > 0 ? r->dzone.cutoff * 100 / cap : -1); printf("%-27s %5d uA\n", "Hibernate discharge rate:", r->drate.hibern); printf("%-27s %5d uA\n", "Cutoff discharge rate:", r->drate.cutoff); @@ -3041,8 +3109,8 @@ int cmd_stress_test(int argc, char *argv[]) } } - printf("Stress test tool version: %s %s %s\n", - CROS_ECTOOL_VERSION, DATE, BUILDER); + printf("Stress test tool version: %s %s %s\n", CROS_ECTOOL_VERSION, + DATE, BUILDER); start_time = time(NULL); last_update_time = start_time; @@ -3067,16 +3135,16 @@ int cmd_stress_test(int argc, char *argv[]) struct ec_response_hello hello_r; /* Request EC Version Strings */ - rv = ec_command(EC_CMD_GET_VERSION, 0, - NULL, 0, &ver_r, sizeof(ver_r)); + rv = ec_command(EC_CMD_GET_VERSION, 0, NULL, 0, &ver_r, + sizeof(ver_r)); if (rv < 0) { failures++; perror("ERROR: EC_CMD_GET_VERSION failed"); } - ver_r.version_string_ro[sizeof(ver_r.version_string_ro) - 1] - = '\0'; - ver_r.version_string_rw[sizeof(ver_r.version_string_rw) - 1] - = '\0'; + ver_r.version_string_ro[sizeof(ver_r.version_string_ro) - 1] = + '\0'; + ver_r.version_string_rw[sizeof(ver_r.version_string_rw) - 1] = + '\0'; if (strlen(ver_r.version_string_ro) == 0) { failures++; fprintf(stderr, "RO version string is empty\n"); @@ -3089,8 +3157,8 @@ int cmd_stress_test(int argc, char *argv[]) usleep(rand_r(&rand_seed) % max_sleep_usec); /* Request EC Build String */ - rv = ec_command(EC_CMD_GET_BUILD_INFO, 0, - NULL, 0, ec_inbuf, ec_max_insize); + rv = ec_command(EC_CMD_GET_BUILD_INFO, 0, NULL, 0, ec_inbuf, + ec_max_insize); if (rv < 0) { failures++; perror("ERROR: EC_CMD_GET_BUILD_INFO failed"); @@ -3133,8 +3201,7 @@ int cmd_stress_test(int argc, char *argv[]) now = time(NULL); printf("Update: attempt %" PRIu64 " round %" PRIu64 " | took %.f seconds\n", - attempt, round, - difftime(now, last_update_time)); + attempt, round, difftime(now, last_update_time)); last_update_time = now; } @@ -3146,7 +3213,7 @@ int cmd_stress_test(int argc, char *argv[]) now = time(NULL); printf("End time: %s\n", ctime(&now)); printf("Total runtime: %.f seconds\n", - difftime(time(NULL), start_time)); + difftime(time(NULL), start_time)); printf("Total failures: %" PRIu64 "\n", failures); return 0; } @@ -3164,8 +3231,8 @@ int read_mapped_temperature(int id) } else if (id < EC_TEMP_SENSOR_ENTRIES) rv = read_mapped_mem8(EC_MEMMAP_TEMP_SENSOR + id); else if (read_mapped_mem8(EC_MEMMAP_THERMAL_VERSION) >= 2) - rv = read_mapped_mem8(EC_MEMMAP_TEMP_SENSOR_B + - id - EC_TEMP_SENSOR_ENTRIES); + rv = read_mapped_mem8(EC_MEMMAP_TEMP_SENSOR_B + id - + EC_TEMP_SENSOR_ENTRIES); else { /* Sensor in second bank, but second bank isn't supported */ rv = EC_TEMP_SENSOR_NOT_PRESENT; @@ -3180,8 +3247,8 @@ static int get_thermal_fan_percent(int temp, int sensor_id) int rv = 0; p.sensor_num = sensor_id; - rv = ec_command(EC_CMD_THERMAL_GET_THRESHOLD, 1, &p, sizeof(p), - &r, sizeof(r)); + rv = ec_command(EC_CMD_THERMAL_GET_THRESHOLD, 1, &p, sizeof(p), &r, + sizeof(r)); if (rv <= 0 || r.temp_fan_max == r.temp_fan_off) return -1; @@ -3190,7 +3257,7 @@ static int get_thermal_fan_percent(int temp, int sensor_id) if (temp > r.temp_fan_max) return 100; return 100 * (temp - r.temp_fan_off) / - (r.temp_fan_max - r.temp_fan_off); + (r.temp_fan_max - r.temp_fan_off); } static int cmd_temperature_print(int id, int mtemp) @@ -3201,8 +3268,8 @@ static int cmd_temperature_print(int id, int mtemp) int temp = mtemp + EC_TEMP_SENSOR_OFFSET; p.id = id; - rc = ec_command(EC_CMD_TEMP_SENSOR_GET_INFO, 0, &p, sizeof(p), - &r, sizeof(r)); + rc = ec_command(EC_CMD_TEMP_SENSOR_GET_INFO, 0, &p, sizeof(p), &r, + sizeof(r)); if (rc < 0) return rc; printf("%-20s %d K (= %d C) %11d%%\n", r.sensor_name, temp, @@ -3254,8 +3321,7 @@ int cmd_temperature(int argc, char *argv[]) return -1; } - if (id < 0 || - id >= EC_MAX_TEMP_SENSOR_ENTRIES) { + if (id < 0 || id >= EC_MAX_TEMP_SENSOR_ENTRIES) { printf("Sensor ID invalid.\n"); return -1; } @@ -3283,7 +3349,6 @@ int cmd_temperature(int argc, char *argv[]) } } - int cmd_temp_sensor_info(int argc, char *argv[]) { struct ec_params_temp_sensor_get_info p; @@ -3301,8 +3366,8 @@ int cmd_temp_sensor_info(int argc, char *argv[]) if (read_mapped_temperature(p.id) == EC_TEMP_SENSOR_NOT_PRESENT) continue; - rv = ec_command(EC_CMD_TEMP_SENSOR_GET_INFO, 0, - &p, sizeof(p), &r, sizeof(r)); + rv = ec_command(EC_CMD_TEMP_SENSOR_GET_INFO, 0, &p, + sizeof(p), &r, sizeof(r)); if (rv < 0) continue; printf("%d: %d %s\n", p.id, r.sensor_type, @@ -3317,8 +3382,8 @@ int cmd_temp_sensor_info(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_TEMP_SENSOR_GET_INFO, 0, - &p, sizeof(p), &r, sizeof(r)); + rv = ec_command(EC_CMD_TEMP_SENSOR_GET_INFO, 0, &p, sizeof(p), &r, + sizeof(r)); if (rv < 0) return rv; @@ -3328,7 +3393,6 @@ int cmd_temp_sensor_info(int argc, char *argv[]) return 0; } - int cmd_thermal_get_threshold_v0(int argc, char *argv[]) { struct ec_params_thermal_get_threshold p; @@ -3337,8 +3401,8 @@ int cmd_thermal_get_threshold_v0(int argc, char *argv[]) int rv; if (argc != 3) { - fprintf(stderr, - "Usage: %s <sensortypeid> <thresholdid>\n", argv[0]); + fprintf(stderr, "Usage: %s <sensortypeid> <thresholdid>\n", + argv[0]); return -1; } @@ -3354,18 +3418,17 @@ int cmd_thermal_get_threshold_v0(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_THERMAL_GET_THRESHOLD, 0, - &p, sizeof(p), &r, sizeof(r)); + rv = ec_command(EC_CMD_THERMAL_GET_THRESHOLD, 0, &p, sizeof(p), &r, + sizeof(r)); if (rv < 0) return rv; - printf("Threshold %d for sensor type %d is %d K.\n", - p.threshold_id, p.sensor_type, r.value); + printf("Threshold %d for sensor type %d is %d K.\n", p.threshold_id, + p.sensor_type, r.value); return 0; } - int cmd_thermal_set_threshold_v0(int argc, char *argv[]) { struct ec_params_thermal_set_threshold p; @@ -3397,18 +3460,17 @@ int cmd_thermal_set_threshold_v0(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_THERMAL_SET_THRESHOLD, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_THERMAL_SET_THRESHOLD, 0, &p, sizeof(p), NULL, + 0); if (rv < 0) return rv; - printf("Threshold %d for sensor type %d set to %d.\n", - p.threshold_id, p.sensor_type, p.value); + printf("Threshold %d for sensor type %d set to %d.\n", p.threshold_id, + p.sensor_type, p.value); return 0; } - int cmd_thermal_get_threshold_v1(int argc, char *argv[]) { struct ec_params_thermal_get_threshold_v1 p; @@ -3420,31 +3482,27 @@ int cmd_thermal_get_threshold_v1(int argc, char *argv[]) printf("sensor warn high halt fan_off fan_max name\n"); for (i = 0; i < EC_MAX_TEMP_SENSOR_ENTRIES; i++) { - - if (read_mapped_temperature(i) == - EC_TEMP_SENSOR_NOT_PRESENT) + if (read_mapped_temperature(i) == EC_TEMP_SENSOR_NOT_PRESENT) continue; /* ask for one */ p.sensor_num = i; - rv = ec_command(EC_CMD_THERMAL_GET_THRESHOLD, 1, - &p, sizeof(p), &r, sizeof(r)); - if (rv <= 0) /* stop on first failure */ + rv = ec_command(EC_CMD_THERMAL_GET_THRESHOLD, 1, &p, sizeof(p), + &r, sizeof(r)); + if (rv <= 0) /* stop on first failure */ break; /* ask for its name, too */ pi.id = i; - rv = ec_command(EC_CMD_TEMP_SENSOR_GET_INFO, 0, - &pi, sizeof(pi), &ri, sizeof(ri)); + rv = ec_command(EC_CMD_TEMP_SENSOR_GET_INFO, 0, &pi, sizeof(pi), + &ri, sizeof(ri)); /* print what we know */ - printf(" %2d %3d %3d %3d %3d %3d %s\n", - i, + printf(" %2d %3d %3d %3d %3d %3d %s\n", i, r.temp_host[EC_TEMP_THRESH_WARN], r.temp_host[EC_TEMP_THRESH_HIGH], - r.temp_host[EC_TEMP_THRESH_HALT], - r.temp_fan_off, r.temp_fan_max, - rv > 0 ? ri.sensor_name : "?"); + r.temp_host[EC_TEMP_THRESH_HALT], r.temp_fan_off, + r.temp_fan_max, rv > 0 ? ri.sensor_name : "?"); } if (i) printf("(all temps in degrees Kelvin)\n"); @@ -3474,8 +3532,8 @@ int cmd_thermal_set_threshold_v1(int argc, char *argv[]) } p.sensor_num = n; - rv = ec_command(EC_CMD_THERMAL_GET_THRESHOLD, 1, - &p, sizeof(p), &r, sizeof(r)); + rv = ec_command(EC_CMD_THERMAL_GET_THRESHOLD, 1, &p, sizeof(p), &r, + sizeof(r)); if (rv <= 0) return rv; @@ -3495,7 +3553,7 @@ int cmd_thermal_set_threshold_v1(int argc, char *argv[]) case 2: case 3: case 4: - s.cfg.temp_host[i-2] = val; + s.cfg.temp_host[i - 2] = val; break; case 5: s.cfg.temp_fan_off = val; @@ -3506,8 +3564,8 @@ int cmd_thermal_set_threshold_v1(int argc, char *argv[]) } } - rv = ec_command(EC_CMD_THERMAL_SET_THRESHOLD, 1, - &s, sizeof(s), NULL, 0); + rv = ec_command(EC_CMD_THERMAL_SET_THRESHOLD, 1, &s, sizeof(s), NULL, + 0); return rv; } @@ -3534,7 +3592,6 @@ int cmd_thermal_set_threshold(int argc, char *argv[]) return -1; } - static int get_num_fans(void) { int idx, rv; @@ -3564,13 +3621,13 @@ int cmd_thermal_auto_fan_ctrl(int argc, char *argv[]) char *e; int cmdver = 1; - if (!ec_cmd_version_supported(EC_CMD_THERMAL_AUTO_FAN_CTRL, cmdver) - || (argc == 1)) { + if (!ec_cmd_version_supported(EC_CMD_THERMAL_AUTO_FAN_CTRL, cmdver) || + (argc == 1)) { /* If no argument is provided then enable auto fan ctrl */ /* for all fans by using version 0 of the host command */ - rv = ec_command(EC_CMD_THERMAL_AUTO_FAN_CTRL, 0, - NULL, 0, NULL, 0); + rv = ec_command(EC_CMD_THERMAL_AUTO_FAN_CTRL, 0, NULL, 0, NULL, + 0); if (rv < 0) return rv; @@ -3590,8 +3647,8 @@ int cmd_thermal_auto_fan_ctrl(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_THERMAL_AUTO_FAN_CTRL, cmdver, - &p_v1, sizeof(p_v1), NULL, 0); + rv = ec_command(EC_CMD_THERMAL_AUTO_FAN_CTRL, cmdver, &p_v1, + sizeof(p_v1), NULL, 0); if (rv < 0) return rv; @@ -3654,7 +3711,6 @@ int cmd_pwm_get_fan_rpm(int argc, char *argv[]) return 0; } - int cmd_pwm_set_fan_rpm(int argc, char *argv[]) { struct ec_params_pwm_set_fan_target_rpm_v1 p_v1; @@ -3669,8 +3725,7 @@ int cmd_pwm_set_fan_rpm(int argc, char *argv[]) cmdver = 0; if (argc != 2) { - fprintf(stderr, - "Usage: %s <targetrpm>\n", argv[0]); + fprintf(stderr, "Usage: %s <targetrpm>\n", argv[0]); return -1; } p_v0.rpm = strtol(argv[1], &e, 0); @@ -3679,8 +3734,8 @@ int cmd_pwm_set_fan_rpm(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_PWM_SET_FAN_TARGET_RPM, cmdver, - &p_v0, sizeof(p_v0), NULL, 0); + rv = ec_command(EC_CMD_PWM_SET_FAN_TARGET_RPM, cmdver, &p_v0, + sizeof(p_v0), NULL, 0); if (rv < 0) return rv; @@ -3710,8 +3765,8 @@ int cmd_pwm_set_fan_rpm(int argc, char *argv[]) cmdver = 0; p_v0.rpm = p_v1.rpm; - rv = ec_command(EC_CMD_PWM_SET_FAN_TARGET_RPM, cmdver, - &p_v0, sizeof(p_v0), NULL, 0); + rv = ec_command(EC_CMD_PWM_SET_FAN_TARGET_RPM, cmdver, &p_v0, + sizeof(p_v0), NULL, 0); if (rv < 0) return rv; @@ -3723,8 +3778,8 @@ int cmd_pwm_set_fan_rpm(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_PWM_SET_FAN_TARGET_RPM, cmdver, - &p_v1, sizeof(p_v1), NULL, 0); + rv = ec_command(EC_CMD_PWM_SET_FAN_TARGET_RPM, cmdver, &p_v1, + sizeof(p_v1), NULL, 0); if (rv < 0) return rv; @@ -3739,8 +3794,8 @@ int cmd_pwm_get_keyboard_backlight(int argc, char *argv[]) struct ec_response_pwm_get_keyboard_backlight r; int rv; - rv = ec_command(EC_CMD_PWM_GET_KEYBOARD_BACKLIGHT, 0, - NULL, 0, &r, sizeof(r)); + rv = ec_command(EC_CMD_PWM_GET_KEYBOARD_BACKLIGHT, 0, NULL, 0, &r, + sizeof(r)); if (rv < 0) return rv; @@ -3752,7 +3807,6 @@ int cmd_pwm_get_keyboard_backlight(int argc, char *argv[]) return 0; } - int cmd_pwm_set_keyboard_backlight(int argc, char *argv[]) { struct ec_params_pwm_set_keyboard_backlight p; @@ -3769,8 +3823,8 @@ int cmd_pwm_set_keyboard_backlight(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_PWM_SET_KEYBOARD_BACKLIGHT, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_PWM_SET_KEYBOARD_BACKLIGHT, 0, &p, sizeof(p), + NULL, 0); if (rv < 0) return rv; @@ -3813,7 +3867,6 @@ int cmd_pwm_get_duty(int argc, char *argv[]) return 0; } - int cmd_pwm_set_duty(int argc, char *argv[]) { struct ec_params_pwm_set_duty p; @@ -3847,8 +3900,7 @@ int cmd_pwm_set_duty(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_PWM_SET_DUTY, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_PWM_SET_DUTY, 0, &p, sizeof(p), NULL, 0); if (rv < 0) return rv; @@ -3867,8 +3919,7 @@ int cmd_fanduty(int argc, char *argv[]) struct ec_params_pwm_set_fan_duty_v0 p_v0; if (argc != 2) { - fprintf(stderr, - "Usage: %s <percent>\n", argv[0]); + fprintf(stderr, "Usage: %s <percent>\n", argv[0]); return -1; } p_v0.percent = strtol(argv[1], &e, 0); @@ -3877,8 +3928,8 @@ int cmd_fanduty(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_PWM_SET_FAN_DUTY, 0, - &p_v0, sizeof(p_v0), NULL, 0); + rv = ec_command(EC_CMD_PWM_SET_FAN_DUTY, 0, &p_v0, sizeof(p_v0), + NULL, 0); if (rv < 0) return rv; @@ -3889,9 +3940,9 @@ int cmd_fanduty(int argc, char *argv[]) if (argc > 3 || (argc == 2 && !strcmp(argv[1], "help")) || argc == 1) { printf("Usage: %s [idx] <percent>\n", argv[0]); printf("'%s 0 50' - Set fan 0 duty cycle to 50 percent\n", - argv[0]); + argv[0]); printf("'%s 30' - Set all fans duty cycle to 30 percent\n", - argv[0]); + argv[0]); return -1; } @@ -3910,8 +3961,8 @@ int cmd_fanduty(int argc, char *argv[]) cmdver = 0; p_v0.percent = p_v1.percent; - rv = ec_command(EC_CMD_PWM_SET_FAN_DUTY, cmdver, - &p_v0, sizeof(p_v0), NULL, 0); + rv = ec_command(EC_CMD_PWM_SET_FAN_DUTY, cmdver, &p_v0, + sizeof(p_v0), NULL, 0); if (rv < 0) return rv; @@ -3923,8 +3974,8 @@ int cmd_fanduty(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_PWM_SET_FAN_DUTY, cmdver, - &p_v1, sizeof(p_v1), NULL, 0); + rv = ec_command(EC_CMD_PWM_SET_FAN_DUTY, cmdver, &p_v1, + sizeof(p_v1), NULL, 0); if (rv < 0) return rv; @@ -3936,9 +3987,7 @@ int cmd_fanduty(int argc, char *argv[]) #define LBMSG(state) #state #include "lightbar_msg_list.h" -static const char * const lightbar_cmds[] = { - LIGHTBAR_MSG_LIST -}; +static const char *const lightbar_cmds[] = { LIGHTBAR_MSG_LIST }; #undef LBMSG /* Size of field <FLD> in structure <ST> */ @@ -3957,36 +4006,36 @@ static const struct { { ST_CMD_SIZE, 0 }, { ST_CMD_SIZE, 0 }, { ST_CMD_SIZE, 0 }, - { ST_PRM_SIZE(set_brightness), 0}, - { ST_PRM_SIZE(seq), 0}, - { ST_PRM_SIZE(reg), 0}, - { ST_PRM_SIZE(set_rgb), 0}, + { ST_PRM_SIZE(set_brightness), 0 }, + { ST_PRM_SIZE(seq), 0 }, + { ST_PRM_SIZE(reg), 0 }, + { ST_PRM_SIZE(set_rgb), 0 }, { ST_CMD_SIZE, ST_RSP_SIZE(get_seq) }, - { ST_PRM_SIZE(demo), 0}, + { ST_PRM_SIZE(demo), 0 }, { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v0) }, - { ST_PRM_SIZE(set_params_v0), 0}, + { ST_PRM_SIZE(set_params_v0), 0 }, { ST_CMD_SIZE, ST_RSP_SIZE(version) }, { ST_CMD_SIZE, ST_RSP_SIZE(get_brightness) }, { ST_PRM_SIZE(get_rgb), ST_RSP_SIZE(get_rgb) }, { ST_CMD_SIZE, ST_RSP_SIZE(get_demo) }, { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v1) }, - { ST_PRM_SIZE(set_params_v1), 0}, - { ST_PRM_SIZE(set_program), 0}, - { ST_PRM_SIZE(manual_suspend_ctrl), 0}, + { ST_PRM_SIZE(set_params_v1), 0 }, + { ST_PRM_SIZE(set_program), 0 }, + { ST_PRM_SIZE(manual_suspend_ctrl), 0 }, { ST_CMD_SIZE, 0 }, { ST_CMD_SIZE, 0 }, { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_timing) }, - { ST_PRM_SIZE(set_v2par_timing), 0}, + { ST_PRM_SIZE(set_v2par_timing), 0 }, { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_tap) }, - { ST_PRM_SIZE(set_v2par_tap), 0}, + { ST_PRM_SIZE(set_v2par_tap), 0 }, { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_osc) }, - { ST_PRM_SIZE(set_v2par_osc), 0}, + { ST_PRM_SIZE(set_v2par_osc), 0 }, { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_bright) }, - { ST_PRM_SIZE(set_v2par_bright), 0}, + { ST_PRM_SIZE(set_v2par_bright), 0 }, { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_thlds) }, - { ST_PRM_SIZE(set_v2par_thlds), 0}, + { ST_PRM_SIZE(set_v2par_thlds), 0 }, { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_colors) }, - { ST_PRM_SIZE(set_v2par_colors), 0}, + { ST_PRM_SIZE(set_v2par_colors), 0 }, }; BUILD_ASSERT(ARRAY_SIZE(lb_command_paramcount) == LIGHTBAR_NUM_CMDS); @@ -4003,16 +4052,20 @@ static int lb_help(const char *cmd) printf(" %s init - load default vals\n", cmd); printf(" %s brightness [NUM] - get/set intensity(0-ff)\n", cmd); printf(" %s seq [NUM|SEQUENCE] - run given pattern" - " (no arg for list)\n", cmd); + " (no arg for list)\n", + cmd); printf(" %s CTRL REG VAL - set LED controller regs\n", cmd); printf(" %s LED RED GREEN BLUE - set color manually" - " (LED=4 for all)\n", cmd); + " (LED=4 for all)\n", + cmd); printf(" %s LED - get current LED color\n", cmd); printf(" %s demo [0|1] - turn demo mode on & off\n", cmd); printf(" %s params [setfile] - get params" - " (or set from file)\n", cmd); + " (or set from file)\n", + cmd); printf(" %s params2 group [setfile] - get params by group\n" - " (or set from file)\n", cmd); + " (or set from file)\n", + cmd); printf(" %s program file - load program from file\n", cmd); return 0; } @@ -4027,15 +4080,14 @@ static uint8_t lb_find_msg_by_name(const char *str) return LIGHTBAR_NUM_SEQUENCES; } -static int lb_do_cmd(enum lightbar_command cmd, - struct ec_params_lightbar *in, +static int lb_do_cmd(enum lightbar_command cmd, struct ec_params_lightbar *in, struct ec_response_lightbar *out) { int rv; in->cmd = cmd; - rv = ec_command(EC_CMD_LIGHTBAR_CMD, 0, - in, lb_command_paramcount[cmd].insize, - out, lb_command_paramcount[cmd].outsize); + rv = ec_command(EC_CMD_LIGHTBAR_CMD, 0, in, + lb_command_paramcount[cmd].insize, out, + lb_command_paramcount[cmd].outsize); return (rv < 0 ? rv : 0); } @@ -4072,38 +4124,50 @@ static int lb_read_params_v0_from_file(const char *filename, fp = fopen(filename, "rb"); if (!fp) { - fprintf(stderr, "Can't open %s: %s\n", - filename, strerror(errno)); + fprintf(stderr, "Can't open %s: %s\n", filename, + strerror(errno)); return 1; } /* We must read the correct number of params from each line */ -#define READ(N) do { \ - line++; \ - want = (N); \ - got = -1; \ - if (!fgets(buf, sizeof(buf), fp)) \ - goto done; \ - got = sscanf(buf, "%i %i %i %i", \ - &val[0], &val[1], &val[2], &val[3]); \ - if (want != got) \ - goto done; \ +#define READ(N) \ + do { \ + line++; \ + want = (N); \ + got = -1; \ + if (!fgets(buf, sizeof(buf), fp)) \ + goto done; \ + got = sscanf(buf, "%i %i %i %i", &val[0], &val[1], &val[2], \ + &val[3]); \ + if (want != got) \ + goto done; \ } while (0) - /* Do it */ - READ(1); p->google_ramp_up = val[0]; - READ(1); p->google_ramp_down = val[0]; - READ(1); p->s3s0_ramp_up = val[0]; - READ(1); p->s0_tick_delay[0] = val[0]; - READ(1); p->s0_tick_delay[1] = val[0]; - READ(1); p->s0a_tick_delay[0] = val[0]; - READ(1); p->s0a_tick_delay[1] = val[0]; - READ(1); p->s0s3_ramp_down = val[0]; - READ(1); p->s3_sleep_for = val[0]; - READ(1); p->s3_ramp_up = val[0]; - READ(1); p->s3_ramp_down = val[0]; - READ(1); p->new_s0 = val[0]; + READ(1); + p->google_ramp_up = val[0]; + READ(1); + p->google_ramp_down = val[0]; + READ(1); + p->s3s0_ramp_up = val[0]; + READ(1); + p->s0_tick_delay[0] = val[0]; + READ(1); + p->s0_tick_delay[1] = val[0]; + READ(1); + p->s0a_tick_delay[0] = val[0]; + READ(1); + p->s0a_tick_delay[1] = val[0]; + READ(1); + p->s0s3_ramp_down = val[0]; + READ(1); + p->s3_sleep_for = val[0]; + READ(1); + p->s3_ramp_up = val[0]; + READ(1); + p->s3_ramp_down = val[0]; + READ(1); + p->new_s0 = val[0]; READ(2); p->osc_min[0] = val[0]; @@ -4191,39 +4255,30 @@ static void lb_show_params_v0(const struct lightbar_params_v0 *p) printf("%d\t\t# .s3_ramp_up\n", p->s3_ramp_up); printf("%d\t\t# .s3_ramp_down\n", p->s3_ramp_down); printf("%d\t\t# .new_s0\n", p->new_s0); - printf("0x%02x 0x%02x\t# .osc_min (battery, AC)\n", - p->osc_min[0], p->osc_min[1]); - printf("0x%02x 0x%02x\t# .osc_max (battery, AC)\n", - p->osc_max[0], p->osc_max[1]); - printf("%d %d\t\t# .w_ofs (battery, AC)\n", - p->w_ofs[0], p->w_ofs[1]); + printf("0x%02x 0x%02x\t# .osc_min (battery, AC)\n", p->osc_min[0], + p->osc_min[1]); + printf("0x%02x 0x%02x\t# .osc_max (battery, AC)\n", p->osc_max[0], + p->osc_max[1]); + printf("%d %d\t\t# .w_ofs (battery, AC)\n", p->w_ofs[0], p->w_ofs[1]); printf("0x%02x 0x%02x\t# .bright_bl_off_fixed (battery, AC)\n", p->bright_bl_off_fixed[0], p->bright_bl_off_fixed[1]); printf("0x%02x 0x%02x\t# .bright_bl_on_min (battery, AC)\n", p->bright_bl_on_min[0], p->bright_bl_on_min[1]); printf("0x%02x 0x%02x\t# .bright_bl_on_max (battery, AC)\n", p->bright_bl_on_max[0], p->bright_bl_on_max[1]); - printf("%d %d %d\t\t# .battery_threshold\n", - p->battery_threshold[0], - p->battery_threshold[1], - p->battery_threshold[2]); - printf("%d %d %d %d\t\t# .s0_idx[] (battery)\n", - p->s0_idx[0][0], p->s0_idx[0][1], - p->s0_idx[0][2], p->s0_idx[0][3]); - printf("%d %d %d %d\t\t# .s0_idx[] (AC)\n", - p->s0_idx[1][0], p->s0_idx[1][1], - p->s0_idx[1][2], p->s0_idx[1][3]); - printf("%d %d %d %d\t# .s3_idx[] (battery)\n", - p->s3_idx[0][0], p->s3_idx[0][1], - p->s3_idx[0][2], p->s3_idx[0][3]); - printf("%d %d %d %d\t# .s3_idx[] (AC)\n", - p->s3_idx[1][0], p->s3_idx[1][1], - p->s3_idx[1][2], p->s3_idx[1][3]); + printf("%d %d %d\t\t# .battery_threshold\n", p->battery_threshold[0], + p->battery_threshold[1], p->battery_threshold[2]); + printf("%d %d %d %d\t\t# .s0_idx[] (battery)\n", p->s0_idx[0][0], + p->s0_idx[0][1], p->s0_idx[0][2], p->s0_idx[0][3]); + printf("%d %d %d %d\t\t# .s0_idx[] (AC)\n", p->s0_idx[1][0], + p->s0_idx[1][1], p->s0_idx[1][2], p->s0_idx[1][3]); + printf("%d %d %d %d\t# .s3_idx[] (battery)\n", p->s3_idx[0][0], + p->s3_idx[0][1], p->s3_idx[0][2], p->s3_idx[0][3]); + printf("%d %d %d %d\t# .s3_idx[] (AC)\n", p->s3_idx[1][0], + p->s3_idx[1][1], p->s3_idx[1][2], p->s3_idx[1][3]); for (i = 0; i < ARRAY_SIZE(p->color); i++) - printf("0x%02x 0x%02x 0x%02x\t# color[%d]\n", - p->color[i].r, - p->color[i].g, - p->color[i].b, i); + printf("0x%02x 0x%02x 0x%02x\t# color[%d]\n", p->color[i].r, + p->color[i].g, p->color[i].b, i); } static int lb_read_params_v1_from_file(const char *filename, @@ -4239,46 +4294,65 @@ static int lb_read_params_v1_from_file(const char *filename, fp = fopen(filename, "rb"); if (!fp) { - fprintf(stderr, "Can't open %s: %s\n", - filename, strerror(errno)); + fprintf(stderr, "Can't open %s: %s\n", filename, + strerror(errno)); return 1; } /* We must read the correct number of params from each line */ -#define READ(N) do { \ - line++; \ - want = (N); \ - got = -1; \ - if (!fgets(buf, sizeof(buf), fp)) \ - goto done; \ - got = sscanf(buf, "%i %i %i %i", \ - &val[0], &val[1], &val[2], &val[3]); \ - if (want != got) \ - goto done; \ +#define READ(N) \ + do { \ + line++; \ + want = (N); \ + got = -1; \ + if (!fgets(buf, sizeof(buf), fp)) \ + goto done; \ + got = sscanf(buf, "%i %i %i %i", &val[0], &val[1], &val[2], \ + &val[3]); \ + if (want != got) \ + goto done; \ } while (0) - /* Do it */ - READ(1); p->google_ramp_up = val[0]; - READ(1); p->google_ramp_down = val[0]; - READ(1); p->s3s0_ramp_up = val[0]; - READ(1); p->s0_tick_delay[0] = val[0]; - READ(1); p->s0_tick_delay[1] = val[0]; - READ(1); p->s0a_tick_delay[0] = val[0]; - READ(1); p->s0a_tick_delay[1] = val[0]; - READ(1); p->s0s3_ramp_down = val[0]; - READ(1); p->s3_sleep_for = val[0]; - READ(1); p->s3_ramp_up = val[0]; - READ(1); p->s3_ramp_down = val[0]; - READ(1); p->tap_tick_delay = val[0]; - READ(1); p->tap_gate_delay = val[0]; - READ(1); p->tap_display_time = val[0]; - - READ(1); p->tap_pct_red = val[0]; - READ(1); p->tap_pct_green = val[0]; - READ(1); p->tap_seg_min_on = val[0]; - READ(1); p->tap_seg_max_on = val[0]; - READ(1); p->tap_seg_osc = val[0]; + READ(1); + p->google_ramp_up = val[0]; + READ(1); + p->google_ramp_down = val[0]; + READ(1); + p->s3s0_ramp_up = val[0]; + READ(1); + p->s0_tick_delay[0] = val[0]; + READ(1); + p->s0_tick_delay[1] = val[0]; + READ(1); + p->s0a_tick_delay[0] = val[0]; + READ(1); + p->s0a_tick_delay[1] = val[0]; + READ(1); + p->s0s3_ramp_down = val[0]; + READ(1); + p->s3_sleep_for = val[0]; + READ(1); + p->s3_ramp_up = val[0]; + READ(1); + p->s3_ramp_down = val[0]; + READ(1); + p->tap_tick_delay = val[0]; + READ(1); + p->tap_gate_delay = val[0]; + READ(1); + p->tap_display_time = val[0]; + + READ(1); + p->tap_pct_red = val[0]; + READ(1); + p->tap_pct_green = val[0]; + READ(1); + p->tap_seg_min_on = val[0]; + READ(1); + p->tap_seg_max_on = val[0]; + READ(1); + p->tap_seg_osc = val[0]; READ(3); p->tap_idx[0] = val[0]; p->tap_idx[1] = val[1]; @@ -4377,41 +4451,32 @@ static void lb_show_params_v1(const struct lightbar_params_v1 *p) printf("%d\t\t# .tap_seg_min_on\n", p->tap_seg_min_on); printf("%d\t\t# .tap_seg_max_on\n", p->tap_seg_max_on); printf("%d\t\t# .tap_seg_osc\n", p->tap_seg_osc); - printf("%d %d %d\t\t# .tap_idx\n", - p->tap_idx[0], p->tap_idx[1], p->tap_idx[2]); - printf("0x%02x 0x%02x\t# .osc_min (battery, AC)\n", - p->osc_min[0], p->osc_min[1]); - printf("0x%02x 0x%02x\t# .osc_max (battery, AC)\n", - p->osc_max[0], p->osc_max[1]); - printf("%d %d\t\t# .w_ofs (battery, AC)\n", - p->w_ofs[0], p->w_ofs[1]); + printf("%d %d %d\t\t# .tap_idx\n", p->tap_idx[0], p->tap_idx[1], + p->tap_idx[2]); + printf("0x%02x 0x%02x\t# .osc_min (battery, AC)\n", p->osc_min[0], + p->osc_min[1]); + printf("0x%02x 0x%02x\t# .osc_max (battery, AC)\n", p->osc_max[0], + p->osc_max[1]); + printf("%d %d\t\t# .w_ofs (battery, AC)\n", p->w_ofs[0], p->w_ofs[1]); printf("0x%02x 0x%02x\t# .bright_bl_off_fixed (battery, AC)\n", p->bright_bl_off_fixed[0], p->bright_bl_off_fixed[1]); printf("0x%02x 0x%02x\t# .bright_bl_on_min (battery, AC)\n", p->bright_bl_on_min[0], p->bright_bl_on_min[1]); printf("0x%02x 0x%02x\t# .bright_bl_on_max (battery, AC)\n", p->bright_bl_on_max[0], p->bright_bl_on_max[1]); - printf("%d %d %d\t# .battery_threshold\n", - p->battery_threshold[0], - p->battery_threshold[1], - p->battery_threshold[2]); - printf("%d %d %d %d\t\t# .s0_idx[] (battery)\n", - p->s0_idx[0][0], p->s0_idx[0][1], - p->s0_idx[0][2], p->s0_idx[0][3]); - printf("%d %d %d %d\t\t# .s0_idx[] (AC)\n", - p->s0_idx[1][0], p->s0_idx[1][1], - p->s0_idx[1][2], p->s0_idx[1][3]); - printf("%d %d %d %d\t# .s3_idx[] (battery)\n", - p->s3_idx[0][0], p->s3_idx[0][1], - p->s3_idx[0][2], p->s3_idx[0][3]); - printf("%d %d %d %d\t# .s3_idx[] (AC)\n", - p->s3_idx[1][0], p->s3_idx[1][1], - p->s3_idx[1][2], p->s3_idx[1][3]); + printf("%d %d %d\t# .battery_threshold\n", p->battery_threshold[0], + p->battery_threshold[1], p->battery_threshold[2]); + printf("%d %d %d %d\t\t# .s0_idx[] (battery)\n", p->s0_idx[0][0], + p->s0_idx[0][1], p->s0_idx[0][2], p->s0_idx[0][3]); + printf("%d %d %d %d\t\t# .s0_idx[] (AC)\n", p->s0_idx[1][0], + p->s0_idx[1][1], p->s0_idx[1][2], p->s0_idx[1][3]); + printf("%d %d %d %d\t# .s3_idx[] (battery)\n", p->s3_idx[0][0], + p->s3_idx[0][1], p->s3_idx[0][2], p->s3_idx[0][3]); + printf("%d %d %d %d\t# .s3_idx[] (AC)\n", p->s3_idx[1][0], + p->s3_idx[1][1], p->s3_idx[1][2], p->s3_idx[1][3]); for (i = 0; i < ARRAY_SIZE(p->color); i++) - printf("0x%02x 0x%02x 0x%02x\t# color[%d]\n", - p->color[i].r, - p->color[i].g, - p->color[i].b, i); + printf("0x%02x 0x%02x 0x%02x\t# color[%d]\n", p->color[i].r, + p->color[i].g, p->color[i].b, i); } static int lb_rd_timing_v2par_from_file(const char *filename, @@ -4426,38 +4491,53 @@ static int lb_rd_timing_v2par_from_file(const char *filename, fp = fopen(filename, "rb"); if (!fp) { - fprintf(stderr, "Can't open %s: %s\n", - filename, strerror(errno)); + fprintf(stderr, "Can't open %s: %s\n", filename, + strerror(errno)); return 1; } /* We must read the correct number of params from each line */ -#define READ(N) do { \ - line++; \ - want = (N); \ - got = -1; \ - if (!fgets(buf, sizeof(buf), fp)) \ - goto done; \ - got = sscanf(buf, "%i %i %i %i", \ - &val[0], &val[1], &val[2], &val[3]); \ - if (want != got) \ - goto done; \ +#define READ(N) \ + do { \ + line++; \ + want = (N); \ + got = -1; \ + if (!fgets(buf, sizeof(buf), fp)) \ + goto done; \ + got = sscanf(buf, "%i %i %i %i", &val[0], &val[1], &val[2], \ + &val[3]); \ + if (want != got) \ + goto done; \ } while (0) - READ(1); p->google_ramp_up = val[0]; - READ(1); p->google_ramp_down = val[0]; - READ(1); p->s3s0_ramp_up = val[0]; - READ(1); p->s0_tick_delay[0] = val[0]; - READ(1); p->s0_tick_delay[1] = val[0]; - READ(1); p->s0a_tick_delay[0] = val[0]; - READ(1); p->s0a_tick_delay[1] = val[0]; - READ(1); p->s0s3_ramp_down = val[0]; - READ(1); p->s3_sleep_for = val[0]; - READ(1); p->s3_ramp_up = val[0]; - READ(1); p->s3_ramp_down = val[0]; - READ(1); p->tap_tick_delay = val[0]; - READ(1); p->tap_gate_delay = val[0]; - READ(1); p->tap_display_time = val[0]; + READ(1); + p->google_ramp_up = val[0]; + READ(1); + p->google_ramp_down = val[0]; + READ(1); + p->s3s0_ramp_up = val[0]; + READ(1); + p->s0_tick_delay[0] = val[0]; + READ(1); + p->s0_tick_delay[1] = val[0]; + READ(1); + p->s0a_tick_delay[0] = val[0]; + READ(1); + p->s0a_tick_delay[1] = val[0]; + READ(1); + p->s0s3_ramp_down = val[0]; + READ(1); + p->s3_sleep_for = val[0]; + READ(1); + p->s3_ramp_up = val[0]; + READ(1); + p->s3_ramp_down = val[0]; + READ(1); + p->tap_tick_delay = val[0]; + READ(1); + p->tap_gate_delay = val[0]; + READ(1); + p->tap_display_time = val[0]; #undef READ /* Yay */ @@ -4482,29 +4562,35 @@ static int lb_rd_tap_v2par_from_file(const char *filename, fp = fopen(filename, "rb"); if (!fp) { - fprintf(stderr, "Can't open %s: %s\n", - filename, strerror(errno)); + fprintf(stderr, "Can't open %s: %s\n", filename, + strerror(errno)); return 1; } /* We must read the correct number of params from each line */ -#define READ(N) do { \ - line++; \ - want = (N); \ - got = -1; \ - if (!fgets(buf, sizeof(buf), fp)) \ - goto done; \ - got = sscanf(buf, "%i %i %i %i", \ - &val[0], &val[1], &val[2], &val[3]); \ - if (want != got) \ - goto done; \ +#define READ(N) \ + do { \ + line++; \ + want = (N); \ + got = -1; \ + if (!fgets(buf, sizeof(buf), fp)) \ + goto done; \ + got = sscanf(buf, "%i %i %i %i", &val[0], &val[1], &val[2], \ + &val[3]); \ + if (want != got) \ + goto done; \ } while (0) - READ(1); p->tap_pct_red = val[0]; - READ(1); p->tap_pct_green = val[0]; - READ(1); p->tap_seg_min_on = val[0]; - READ(1); p->tap_seg_max_on = val[0]; - READ(1); p->tap_seg_osc = val[0]; + READ(1); + p->tap_pct_red = val[0]; + READ(1); + p->tap_pct_green = val[0]; + READ(1); + p->tap_seg_min_on = val[0]; + READ(1); + p->tap_seg_max_on = val[0]; + READ(1); + p->tap_seg_osc = val[0]; READ(3); p->tap_idx[0] = val[0]; p->tap_idx[1] = val[1]; @@ -4533,22 +4619,23 @@ static int lb_rd_osc_v2par_from_file(const char *filename, fp = fopen(filename, "rb"); if (!fp) { - fprintf(stderr, "Can't open %s: %s\n", - filename, strerror(errno)); + fprintf(stderr, "Can't open %s: %s\n", filename, + strerror(errno)); return 1; } /* We must read the correct number of params from each line */ -#define READ(N) do { \ - line++; \ - want = (N); \ - got = -1; \ - if (!fgets(buf, sizeof(buf), fp)) \ - goto done; \ - got = sscanf(buf, "%i %i %i %i", \ - &val[0], &val[1], &val[2], &val[3]); \ - if (want != got) \ - goto done; \ +#define READ(N) \ + do { \ + line++; \ + want = (N); \ + got = -1; \ + if (!fgets(buf, sizeof(buf), fp)) \ + goto done; \ + got = sscanf(buf, "%i %i %i %i", &val[0], &val[1], &val[2], \ + &val[3]); \ + if (want != got) \ + goto done; \ } while (0) READ(2); @@ -4584,22 +4671,23 @@ static int lb_rd_bright_v2par_from_file(const char *filename, fp = fopen(filename, "rb"); if (!fp) { - fprintf(stderr, "Can't open %s: %s\n", - filename, strerror(errno)); + fprintf(stderr, "Can't open %s: %s\n", filename, + strerror(errno)); return 1; } /* We must read the correct number of params from each line */ -#define READ(N) do { \ - line++; \ - want = (N); \ - got = -1; \ - if (!fgets(buf, sizeof(buf), fp)) \ - goto done; \ - got = sscanf(buf, "%i %i %i %i", \ - &val[0], &val[1], &val[2], &val[3]); \ - if (want != got) \ - goto done; \ +#define READ(N) \ + do { \ + line++; \ + want = (N); \ + got = -1; \ + if (!fgets(buf, sizeof(buf), fp)) \ + goto done; \ + got = sscanf(buf, "%i %i %i %i", &val[0], &val[1], &val[2], \ + &val[3]); \ + if (want != got) \ + goto done; \ } while (0) READ(2); @@ -4637,22 +4725,23 @@ static int lb_rd_thlds_v2par_from_file(const char *filename, fp = fopen(filename, "rb"); if (!fp) { - fprintf(stderr, "Can't open %s: %s\n", - filename, strerror(errno)); + fprintf(stderr, "Can't open %s: %s\n", filename, + strerror(errno)); return 1; } /* We must read the correct number of params from each line */ -#define READ(N) do { \ - line++; \ - want = (N); \ - got = -1; \ - if (!fgets(buf, sizeof(buf), fp)) \ - goto done; \ - got = sscanf(buf, "%i %i %i %i", \ - &val[0], &val[1], &val[2], &val[3]); \ - if (want != got) \ - goto done; \ +#define READ(N) \ + do { \ + line++; \ + want = (N); \ + got = -1; \ + if (!fgets(buf, sizeof(buf), fp)) \ + goto done; \ + got = sscanf(buf, "%i %i %i %i", &val[0], &val[1], &val[2], \ + &val[3]); \ + if (want != got) \ + goto done; \ } while (0) READ(3); @@ -4684,22 +4773,23 @@ static int lb_rd_colors_v2par_from_file(const char *filename, fp = fopen(filename, "rb"); if (!fp) { - fprintf(stderr, "Can't open %s: %s\n", - filename, strerror(errno)); + fprintf(stderr, "Can't open %s: %s\n", filename, + strerror(errno)); return 1; } /* We must read the correct number of params from each line */ -#define READ(N) do { \ - line++; \ - want = (N); \ - got = -1; \ - if (!fgets(buf, sizeof(buf), fp)) \ - goto done; \ - got = sscanf(buf, "%i %i %i %i", \ - &val[0], &val[1], &val[2], &val[3]); \ - if (want != got) \ - goto done; \ +#define READ(N) \ + do { \ + line++; \ + want = (N); \ + got = -1; \ + if (!fgets(buf, sizeof(buf), fp)) \ + goto done; \ + got = sscanf(buf, "%i %i %i %i", &val[0], &val[1], &val[2], \ + &val[3]); \ + if (want != got) \ + goto done; \ } while (0) READ(4); @@ -4769,18 +4859,17 @@ static void lb_show_v2par_tap(const struct lightbar_params_v2_tap *p) printf("%d\t\t# .tap_seg_min_on\n", p->tap_seg_min_on); printf("%d\t\t# .tap_seg_max_on\n", p->tap_seg_max_on); printf("%d\t\t# .tap_seg_osc\n", p->tap_seg_osc); - printf("%d %d %d\t\t# .tap_idx\n", - p->tap_idx[0], p->tap_idx[1], p->tap_idx[2]); + printf("%d %d %d\t\t# .tap_idx\n", p->tap_idx[0], p->tap_idx[1], + p->tap_idx[2]); } static void lb_show_v2par_osc(const struct lightbar_params_v2_oscillation *p) { - printf("0x%02x 0x%02x\t# .osc_min (battery, AC)\n", - p->osc_min[0], p->osc_min[1]); - printf("0x%02x 0x%02x\t# .osc_max (battery, AC)\n", - p->osc_max[0], p->osc_max[1]); - printf("%d %d\t\t# .w_ofs (battery, AC)\n", - p->w_ofs[0], p->w_ofs[1]); + printf("0x%02x 0x%02x\t# .osc_min (battery, AC)\n", p->osc_min[0], + p->osc_min[1]); + printf("0x%02x 0x%02x\t# .osc_max (battery, AC)\n", p->osc_max[0], + p->osc_max[1]); + printf("%d %d\t\t# .w_ofs (battery, AC)\n", p->w_ofs[0], p->w_ofs[1]); } static void lb_show_v2par_bright(const struct lightbar_params_v2_brightness *p) @@ -4795,34 +4884,26 @@ static void lb_show_v2par_bright(const struct lightbar_params_v2_brightness *p) static void lb_show_v2par_thlds(const struct lightbar_params_v2_thresholds *p) { - printf("%d %d %d\t# .battery_threshold\n", - p->battery_threshold[0], - p->battery_threshold[1], - p->battery_threshold[2]); + printf("%d %d %d\t# .battery_threshold\n", p->battery_threshold[0], + p->battery_threshold[1], p->battery_threshold[2]); } static void lb_show_v2par_colors(const struct lightbar_params_v2_colors *p) { int i; - printf("%d %d %d %d\t\t# .s0_idx[] (battery)\n", - p->s0_idx[0][0], p->s0_idx[0][1], - p->s0_idx[0][2], p->s0_idx[0][3]); - printf("%d %d %d %d\t\t# .s0_idx[] (AC)\n", - p->s0_idx[1][0], p->s0_idx[1][1], - p->s0_idx[1][2], p->s0_idx[1][3]); - printf("%d %d %d %d\t# .s3_idx[] (battery)\n", - p->s3_idx[0][0], p->s3_idx[0][1], - p->s3_idx[0][2], p->s3_idx[0][3]); - printf("%d %d %d %d\t# .s3_idx[] (AC)\n", - p->s3_idx[1][0], p->s3_idx[1][1], - p->s3_idx[1][2], p->s3_idx[1][3]); + printf("%d %d %d %d\t\t# .s0_idx[] (battery)\n", p->s0_idx[0][0], + p->s0_idx[0][1], p->s0_idx[0][2], p->s0_idx[0][3]); + printf("%d %d %d %d\t\t# .s0_idx[] (AC)\n", p->s0_idx[1][0], + p->s0_idx[1][1], p->s0_idx[1][2], p->s0_idx[1][3]); + printf("%d %d %d %d\t# .s3_idx[] (battery)\n", p->s3_idx[0][0], + p->s3_idx[0][1], p->s3_idx[0][2], p->s3_idx[0][3]); + printf("%d %d %d %d\t# .s3_idx[] (AC)\n", p->s3_idx[1][0], + p->s3_idx[1][1], p->s3_idx[1][2], p->s3_idx[1][3]); for (i = 0; i < ARRAY_SIZE(p->color); i++) - printf("0x%02x 0x%02x 0x%02x\t# color[%d]\n", - p->color[i].r, - p->color[i].g, - p->color[i].b, i); + printf("0x%02x 0x%02x 0x%02x\t# color[%d]\n", p->color[i].r, + p->color[i].g, p->color[i].b, i); } static int lb_load_program(const char *filename, struct lightbar_program *prog) @@ -4833,19 +4914,18 @@ static int lb_load_program(const char *filename, struct lightbar_program *prog) fp = fopen(filename, "rb"); if (!fp) { - fprintf(stderr, "Can't open %s: %s\n", - filename, strerror(errno)); + fprintf(stderr, "Can't open %s: %s\n", filename, + strerror(errno)); return 1; } rc = fseek(fp, 0, SEEK_END); if (rc) { - fprintf(stderr, "Couldn't find end of file %s", - filename); + fprintf(stderr, "Couldn't find end of file %s", filename); fclose(fp); return 1; } - rc = (int) ftell(fp); + rc = (int)ftell(fp); if (rc > EC_LB_PROG_LEN) { fprintf(stderr, "File %s is too long, aborting\n", filename); fclose(fp); @@ -4869,12 +4949,10 @@ static int cmd_lightbar_params_v0(int argc, char **argv) int r; if (argc > 2) { - r = lb_read_params_v0_from_file(argv[2], - ¶m.set_params_v0); + r = lb_read_params_v0_from_file(argv[2], ¶m.set_params_v0); if (r) return r; - return lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V0, - ¶m, &resp); + return lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V0, ¶m, &resp); } r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V0, ¶m, &resp); if (!r) @@ -4889,12 +4967,10 @@ static int cmd_lightbar_params_v1(int argc, char **argv) int r; if (argc > 2) { - r = lb_read_params_v1_from_file(argv[2], - ¶m.set_params_v1); + r = lb_read_params_v1_from_file(argv[2], ¶m.set_params_v1); if (r) return r; - return lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V1, - ¶m, &resp); + return lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V1, ¶m, &resp); } r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V1, ¶m, &resp); if (!r) @@ -4943,8 +5019,8 @@ static int cmd_lightbar_params_v2(int argc, char **argv) &p.set_v2par_timing); if (r) return r; - r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_TIMING, - &p, &resp); + r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_TIMING, &p, + &resp); if (r) return r; } @@ -4958,8 +5034,8 @@ static int cmd_lightbar_params_v2(int argc, char **argv) &p.set_v2par_tap); if (r) return r; - r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_TAP, - &p, &resp); + r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_TAP, &p, + &resp); if (r) return r; } @@ -4989,13 +5065,12 @@ static int cmd_lightbar_params_v2(int argc, char **argv) &p.set_v2par_bright); if (r) return r; - r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_BRIGHTNESS, - &p, &resp); + r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_BRIGHTNESS, &p, + &resp); if (r) return r; } - r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_BRIGHTNESS, &p, - &resp); + r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_BRIGHTNESS, &p, &resp); if (r) return r; lb_show_v2par_bright(&resp.get_params_v2_bright); @@ -5005,13 +5080,12 @@ static int cmd_lightbar_params_v2(int argc, char **argv) &p.set_v2par_thlds); if (r) return r; - r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_THRESHOLDS, - &p, &resp); + r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_THRESHOLDS, &p, + &resp); if (r) return r; } - r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_THRESHOLDS, &p, - &resp); + r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_THRESHOLDS, &p, &resp); if (r) return r; lb_show_v2par_thlds(&resp.get_params_v2_thlds); @@ -5021,8 +5095,8 @@ static int cmd_lightbar_params_v2(int argc, char **argv) &p.set_v2par_colors); if (r) return r; - r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_COLORS, - &p, &resp); + r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_COLORS, &p, + &resp); if (r) return r; } @@ -5043,14 +5117,13 @@ static int cmd_lightbar(int argc, char **argv) struct ec_params_lightbar param; struct ec_response_lightbar resp; - if (1 == argc) { /* no args = dump 'em all */ + if (1 == argc) { /* no args = dump 'em all */ r = lb_do_cmd(LIGHTBAR_CMD_DUMP, ¶m, &resp); if (r) return r; for (i = 0; i < ARRAY_SIZE(resp.dump.vals); i++) { printf(" %02x %02x %02x\n", - resp.dump.vals[i].reg, - resp.dump.vals[i].ic0, + resp.dump.vals[i].reg, resp.dump.vals[i].ic0, resp.dump.vals[i].ic1); } return 0; @@ -5086,8 +5159,8 @@ static int cmd_lightbar(int argc, char **argv) if (!strcasecmp(argv[1], "version")) { r = lb_do_cmd(LIGHTBAR_CMD_VERSION, ¶m, &resp); if (!r) - printf("version %d flags 0x%x\n", - resp.version.num, resp.version.flags); + printf("version %d flags 0x%x\n", resp.version.num, + resp.version.flags); return r; } @@ -5096,12 +5169,11 @@ static int cmd_lightbar(int argc, char **argv) int rv; if (argc > 2) { param.set_brightness.num = 0xff & - strtoull(argv[2], &e, 16); - return lb_do_cmd(LIGHTBAR_CMD_SET_BRIGHTNESS, - ¶m, &resp); + strtoull(argv[2], &e, 16); + return lb_do_cmd(LIGHTBAR_CMD_SET_BRIGHTNESS, ¶m, + &resp); } - rv = lb_do_cmd(LIGHTBAR_CMD_GET_BRIGHTNESS, - ¶m, &resp); + rv = lb_do_cmd(LIGHTBAR_CMD_GET_BRIGHTNESS, ¶m, &resp); if (rv) return rv; printf("%02x\n", resp.get_brightness.num); @@ -5176,10 +5248,8 @@ static int cmd_lightbar(int argc, char **argv) r = lb_do_cmd(LIGHTBAR_CMD_GET_RGB, ¶m, &resp); if (r) return r; - printf("%02x %02x %02x\n", - resp.get_rgb.red, - resp.get_rgb.green, - resp.get_rgb.blue); + printf("%02x %02x %02x\n", resp.get_rgb.red, + resp.get_rgb.green, resp.get_rgb.blue); return 0; } } @@ -5192,7 +5262,10 @@ static int cmd_lightbar(int argc, char **argv) #define ST_PRM_SIZE(SUBCMD) \ (ST_CMD_SIZE + ST_FLD_SIZE(ec_params_motion_sense, SUBCMD)) #define ST_RSP_SIZE(SUBCMD) ST_FLD_SIZE(ec_response_motion_sense, SUBCMD) -#define ST_BOTH_SIZES(SUBCMD) { ST_PRM_SIZE(SUBCMD), ST_RSP_SIZE(SUBCMD) } +#define ST_BOTH_SIZES(SUBCMD) \ + { \ + ST_PRM_SIZE(SUBCMD), ST_RSP_SIZE(SUBCMD) \ + } /* * For ectool only, assume no more than 16 sensors. More advanced @@ -5205,22 +5278,17 @@ static const struct { uint8_t outsize; uint8_t insize; } ms_command_sizes[] = { - { - ST_PRM_SIZE(dump), - ST_RSP_SIZE(dump) + - sizeof(struct ec_response_motion_sensor_data) * - ECTOOL_MAX_SENSOR - }, + { ST_PRM_SIZE(dump), + ST_RSP_SIZE(dump) + sizeof(struct ec_response_motion_sensor_data) * + ECTOOL_MAX_SENSOR }, ST_BOTH_SIZES(info_4), ST_BOTH_SIZES(ec_rate), ST_BOTH_SIZES(sensor_odr), ST_BOTH_SIZES(sensor_range), ST_BOTH_SIZES(kb_wake_angle), ST_BOTH_SIZES(data), - { - ST_CMD_SIZE, - ST_RSP_SIZE(fifo_info) + sizeof(uint16_t) * ECTOOL_MAX_SENSOR - }, + { ST_CMD_SIZE, + ST_RSP_SIZE(fifo_info) + sizeof(uint16_t) * ECTOOL_MAX_SENSOR }, ST_BOTH_SIZES(fifo_flush), ST_BOTH_SIZES(fifo_read), ST_BOTH_SIZES(perform_calib), @@ -5246,40 +5314,43 @@ static int ms_help(const char *cmd) { printf("Usage:\n"); printf(" %s - dump all motion data\n", - cmd); + cmd); printf(" %s active - print active flag\n", cmd); printf(" %s info NUM - print sensor info\n", cmd); printf(" %s ec_rate NUM [RATE_MS] - set/get sample rate\n", - cmd); - printf(" %s odr NUM [ODR [ROUNDUP]] - set/get sensor ODR\n", - cmd); + cmd); + printf(" %s odr NUM [ODR [ROUNDUP]] - set/get sensor ODR\n", cmd); printf(" %s range NUM [RANGE [ROUNDUP]] - set/get sensor range\n", - cmd); + cmd); printf(" %s offset NUM [-- X Y Z [TEMP]] - set/get sensor offset\n", - cmd); + cmd); printf(" %s kb_wake NUM - set/get KB wake ang\n", - cmd); + cmd); printf(" %s fifo_info - print fifo info\n", cmd); printf(" %s fifo_int_enable [0/1] - enable/disable/get fifo " - "interrupt status\n", cmd); + "interrupt status\n", + cmd); printf(" %s fifo_read MAX_DATA - read fifo data\n", cmd); printf(" %s fifo_flush NUM - trigger fifo interrupt\n", - cmd); + cmd); printf(" %s list_activities - list supported " - "activities\n", cmd); + "activities\n", + cmd); printf(" %s set_activity ACT EN - enable/disable activity\n", - cmd); + cmd); printf(" %s get_activity ACT - get activity status\n", - cmd); + cmd); printf(" %s lid_angle - print lid angle\n", cmd); printf(" %s spoof -- NUM [0/1] [X Y Z] - enable/disable spoofing\n", - cmd); + cmd); printf(" %s spoof -- NUM activity ACT [0/1] [STATE] - enable/disable " - "activity spoofing\n", cmd); + "activity spoofing\n", + cmd); printf(" %s tablet_mode_angle ANG HYS - set/get tablet mode " - "angle\n", cmd); + "angle\n", + cmd); printf(" %s calibrate NUM - run sensor calibration\n", - cmd); + cmd); return 0; } @@ -5290,11 +5361,9 @@ static void motionsense_display_activities(uint32_t activities) printf("%d: Significant motion\n", MOTIONSENSE_ACTIVITY_SIG_MOTION); if (activities & BIT(MOTIONSENSE_ACTIVITY_DOUBLE_TAP)) - printf("%d: Double tap\n", - MOTIONSENSE_ACTIVITY_DOUBLE_TAP); + printf("%d: Double tap\n", MOTIONSENSE_ACTIVITY_DOUBLE_TAP); if (activities & BIT(MOTIONSENSE_ACTIVITY_ORIENTATION)) - printf("%d: Orientation\n", - MOTIONSENSE_ACTIVITY_ORIENTATION); + printf("%d: Orientation\n", MOTIONSENSE_ACTIVITY_ORIENTATION); if (activities & BIT(MOTIONSENSE_ACTIVITY_BODY_DETECTION)) printf("%d: Body Detection\n", MOTIONSENSE_ACTIVITY_BODY_DETECTION); @@ -5315,32 +5384,30 @@ static int cmd_motionsense(int argc, char **argv) * for kernel_CrosECSysfsAccel. */ const char *motion_status_string[2][2] = { - { "Motion sensing inactive", "0"}, - { "Motion sensing active", "1"}, + { "Motion sensing inactive", "0" }, + { "Motion sensing active", "1" }, }; /* No motionsense command has more than 7 args. */ if (argc > 7) return ms_help(argv[0]); - if ((argc == 1) || - (argc == 2 && !strcasecmp(argv[1], "active"))) { + if ((argc == 1) || (argc == 2 && !strcasecmp(argv[1], "active"))) { param.cmd = MOTIONSENSE_CMD_DUMP; param.dump.max_sensor_count = ECTOOL_MAX_SENSOR; - rv = ec_command( - EC_CMD_MOTION_SENSE_CMD, 1, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv > 0) { - printf("%s\n", motion_status_string[ - !!(resp->dump.module_flags & - MOTIONSENSE_MODULE_FLAG_ACTIVE)][ - status_only]); + printf("%s\n", motion_status_string[!!( + resp->dump.module_flags & + MOTIONSENSE_MODULE_FLAG_ACTIVE)] + [status_only]); if (status_only) return 0; if (resp->dump.sensor_count > ECTOOL_MAX_SENSOR) { printf("Too many sensors to handle: %d", - resp->dump.sensor_count); + resp->dump.sensor_count); return -1; } for (i = 0; i < resp->dump.sensor_count; i++) { @@ -5352,11 +5419,11 @@ static int cmd_motionsense(int argc, char **argv) */ printf("Sensor %d: ", i); if (resp->dump.sensor[i].flags & - MOTIONSENSE_SENSOR_FLAG_PRESENT) + MOTIONSENSE_SENSOR_FLAG_PRESENT) printf("%d\t%d\t%d\n", - resp->dump.sensor[i].data[0], - resp->dump.sensor[i].data[1], - resp->dump.sensor[i].data[2]); + resp->dump.sensor[i].data[0], + resp->dump.sensor[i].data[1], + resp->dump.sensor[i].data[2]); else printf("None\n"); } @@ -5380,9 +5447,9 @@ static int cmd_motionsense(int argc, char **argv) return -1; } - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, version, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, version, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; @@ -5529,11 +5596,11 @@ static int cmd_motionsense(int argc, char **argv) if (version >= 3) { printf("Min Frequency: %d mHz\n", - resp->info_3.min_frequency); + resp->info_3.min_frequency); printf("Max Frequency: %d mHz\n", - resp->info_3.max_frequency); + resp->info_3.max_frequency); printf("FIFO Max Event Count: %d\n", - resp->info_3.fifo_max_event_count); + resp->info_3.fifo_max_event_count); } if (version >= 4) { printf("Flags: %d\n", @@ -5558,9 +5625,9 @@ static int cmd_motionsense(int argc, char **argv) } } - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; @@ -5596,9 +5663,9 @@ static int cmd_motionsense(int argc, char **argv) } } - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; @@ -5634,9 +5701,9 @@ static int cmd_motionsense(int argc, char **argv) } } - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; @@ -5657,9 +5724,9 @@ static int cmd_motionsense(int argc, char **argv) } } - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; @@ -5680,16 +5747,16 @@ static int cmd_motionsense(int argc, char **argv) EC_MOTION_SENSE_NO_VALUE; if (argc == 4) { - param.tablet_mode_threshold.lid_angle = strtol(argv[2], - &e, 0); + param.tablet_mode_threshold.lid_angle = + strtol(argv[2], &e, 0); if (e && *e) { fprintf(stderr, "Bad %s arg.\n", argv[2]); return -1; } - param.tablet_mode_threshold.hys_degree = strtol(argv[3], - &e, 0); + param.tablet_mode_threshold.hys_degree = + strtol(argv[3], &e, 0); if (e && *e) { fprintf(stderr, "Bad %s arg.\n", argv[3]); return -1; @@ -5698,9 +5765,9 @@ static int cmd_motionsense(int argc, char **argv) return ms_help(argv[0]); } - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; @@ -5717,17 +5784,17 @@ static int cmd_motionsense(int argc, char **argv) param.cmd = MOTIONSENSE_CMD_DUMP; param.dump.max_sensor_count = 0; - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; sensor_count = resp->dump.sensor_count; param.cmd = MOTIONSENSE_CMD_FIFO_INFO; - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; @@ -5749,9 +5816,9 @@ static int cmd_motionsense(int argc, char **argv) param.fifo_int_enable.enable = strtol(argv[2], &e, 0); else param.fifo_int_enable.enable = EC_MOTION_SENSE_NO_VALUE; - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; @@ -5767,7 +5834,7 @@ static int cmd_motionsense(int argc, char **argv) } fifo_read_buffer = { .number_data = UINT32_MAX, }; - int print_data = 0, max_data = strtol(argv[2], &e, 0); + int print_data = 0, max_data = strtol(argv[2], &e, 0); if (e && *e) { fprintf(stderr, "Bad %s arg.\n", argv[2]); @@ -5781,8 +5848,7 @@ static int cmd_motionsense(int argc, char **argv) MIN(ARRAY_SIZE(fifo_read_buffer.data), max_data - print_data); - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, - ¶m, + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, ¶m, ms_command_sizes[param.cmd].outsize, &fifo_read_buffer, ec_max_insize); if (rv < 0) @@ -5792,24 +5858,21 @@ static int cmd_motionsense(int argc, char **argv) for (i = 0; i < fifo_read_buffer.number_data; i++) { vector = &fifo_read_buffer.data[i]; if (vector->flags & - (MOTIONSENSE_SENSOR_FLAG_TIMESTAMP | - MOTIONSENSE_SENSOR_FLAG_FLUSH)) { - + (MOTIONSENSE_SENSOR_FLAG_TIMESTAMP | + MOTIONSENSE_SENSOR_FLAG_FLUSH)) { printf("Timestamp:%" PRIx32 "%s\n", - vector->timestamp, - (vector->flags & - MOTIONSENSE_SENSOR_FLAG_FLUSH ? - " - Flush" : "")); + vector->timestamp, + (vector->flags & MOTIONSENSE_SENSOR_FLAG_FLUSH ? + " - Flush" : + "")); } else { printf("Sensor %d: %d\t%d\t%d " "(as uint16: %u\t%u\t%u)\n", - vector->sensor_num, - vector->data[0], - vector->data[1], - vector->data[2], - vector->data[0], - vector->data[1], - vector->data[2]); + vector->sensor_num, + vector->data[0], vector->data[1], + vector->data[2], vector->data[0], + vector->data[1], + vector->data[2]); } } } @@ -5824,9 +5887,9 @@ static int cmd_motionsense(int argc, char **argv) return -1; } - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); return rv < 0 ? rv : 0; } @@ -5840,18 +5903,18 @@ static int cmd_motionsense(int argc, char **argv) return -1; } - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; printf("--- Calibrated well ---\n"); printf("New offset vector: X:%d, Y:%d, Z:%d\n", - resp->perform_calib.offset[0], - resp->perform_calib.offset[1], - resp->perform_calib.offset[2]); + resp->perform_calib.offset[0], + resp->perform_calib.offset[1], + resp->perform_calib.offset[2]); if ((uint16_t)resp->perform_calib.temp == EC_MOTION_SENSE_INVALID_CALIB_TEMP) printf("Temperature at calibration unknown\n"); @@ -5877,19 +5940,24 @@ static int cmd_motionsense(int argc, char **argv) /* Regarded as a command to set offset */ if (argc >= 6 && argc < 8) { /* Set offset : X, Y, Z */ - param.sensor_offset.flags = MOTION_SENSE_SET_OFFSET; + param.sensor_offset.flags = + MOTION_SENSE_SET_OFFSET; for (i = 0; i < 3; i++) { - param.sensor_offset.offset[i] = strtol(argv[3+i], &e, 0); + param.sensor_offset.offset[i] = + strtol(argv[3 + i], &e, 0); if (e && *e) { - fprintf(stderr, "Bad %s arg.\n", argv[3+i]); + fprintf(stderr, "Bad %s arg.\n", + argv[3 + i]); return -1; } } if (argc == 7) { /* Set offset : Temperature */ - param.sensor_offset.temp = strtol(argv[6], &e, 0); + param.sensor_offset.temp = + strtol(argv[6], &e, 0); if (e && *e) { - fprintf(stderr, "Bad %s arg.\n", argv[6]); + fprintf(stderr, "Bad %s arg.\n", + argv[6]); return -1; } } @@ -5898,17 +5966,17 @@ static int cmd_motionsense(int argc, char **argv) } } - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; printf("Offset vector: X:%d, Y:%d, Z:%d\n", - resp->sensor_offset.offset[0], - resp->sensor_offset.offset[1], - resp->sensor_offset.offset[2]); + resp->sensor_offset.offset[0], + resp->sensor_offset.offset[1], + resp->sensor_offset.offset[2]); if ((uint16_t)resp->sensor_offset.temp == EC_MOTION_SENSE_INVALID_CALIB_TEMP) printf("temperature at calibration unknown\n"); @@ -5921,9 +5989,9 @@ static int cmd_motionsense(int argc, char **argv) if (argc == 2 && !strcasecmp(argv[1], "list_activities")) { param.cmd = MOTIONSENSE_CMD_LIST_ACTIVITIES; - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; @@ -5938,9 +6006,9 @@ static int cmd_motionsense(int argc, char **argv) param.set_activity.activity = strtol(argv[2], &e, 0); param.set_activity.enable = strtol(argv[3], &e, 0); - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; return 0; @@ -5949,9 +6017,9 @@ static int cmd_motionsense(int argc, char **argv) param.cmd = MOTIONSENSE_CMD_GET_ACTIVITY; param.get_activity.activity = strtol(argv[2], &e, 0); - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; printf("State: %d\n", resp->get_activity.state); @@ -5959,9 +6027,9 @@ static int cmd_motionsense(int argc, char **argv) } if (argc == 2 && !strcasecmp(argv[1], "lid_angle")) { param.cmd = MOTIONSENSE_CMD_LID_ANGLE; - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; @@ -6022,7 +6090,7 @@ static int cmd_motionsense(int argc, char **argv) } else if (argc != 5) { return ms_help(argv[0]); } - /* spoof accel data */ + /* spoof accel data */ } else if (argc >= 4) { int enable, i; int16_t val; @@ -6048,10 +6116,10 @@ static int cmd_motionsense(int argc, char **argv) param.spoof.spoof_enable = MOTIONSENSE_SPOOF_MODE_CUSTOM; for (i = 0; i < 3; i++) { - val = strtol(argv[4+i], &e, 0); + val = strtol(argv[4 + i], &e, 0); if (e && *e) { fprintf(stderr, "Bad %s arg.\n", - argv[4+i]); + argv[4 + i]); return -1; } param.spoof.components[i] = val; @@ -6064,9 +6132,9 @@ static int cmd_motionsense(int argc, char **argv) } } - rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, - ¶m, ms_command_sizes[param.cmd].outsize, - resp, ms_command_sizes[param.cmd].insize); + rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, ¶m, + ms_command_sizes[param.cmd].outsize, resp, + ms_command_sizes[param.cmd].insize); if (rv < 0) return rv; @@ -6091,8 +6159,8 @@ int cmd_next_event(int argc, char *argv[]) int rv; int i; - rv = ec_command(EC_CMD_GET_NEXT_EVENT, 0, - NULL, 0, rdata, ec_max_insize); + rv = ec_command(EC_CMD_GET_NEXT_EVENT, 0, NULL, 0, rdata, + ec_max_insize); if (rv < 0) return rv; @@ -6145,7 +6213,8 @@ int cmd_led(int argc, char *argv[]) if (argc < 3) { fprintf(stderr, "Usage: %s <name> <query | auto | " - "off | <color> | <color>=<value>...>\n", argv[0]); + "off | <color> | <color>=<value>...>\n", + argv[0]); return -1; } @@ -6161,16 +6230,15 @@ int cmd_led(int argc, char *argv[]) if (!strcasecmp(argv[2], "query")) { p.flags = EC_LED_FLAGS_QUERY; - rv = ec_command(EC_CMD_LED_CONTROL, 1, &p, sizeof(p), - &r, sizeof(r)); + rv = ec_command(EC_CMD_LED_CONTROL, 1, &p, sizeof(p), &r, + sizeof(r)); printf("Brightness range for LED %d:\n", p.led_id); if (rv < 0) { fprintf(stderr, "Error: Unsupported LED.\n"); return rv; } for (i = 0; i < EC_LED_COLOR_COUNT; ++i) - printf("\t%s\t: 0x%x\n", - led_color_names[i], + printf("\t%s\t: 0x%x\n", led_color_names[i], r.brightness_range[i]); return 0; } @@ -6211,7 +6279,6 @@ int cmd_led(int argc, char *argv[]) return (rv < 0 ? rv : 0); } - int cmd_usb_charge_set_mode(int argc, char *argv[]) { struct ec_params_usb_charge_set_mode p; @@ -6237,18 +6304,17 @@ int cmd_usb_charge_set_mode(int argc, char *argv[]) p.inhibit_charge = 0; if (argc == 4) { p.inhibit_charge = strtol(argv[3], &e, 0); - if ((e && *e) || (p.inhibit_charge != 0 && - p.inhibit_charge != 1)) { + if ((e && *e) || + (p.inhibit_charge != 0 && p.inhibit_charge != 1)) { fprintf(stderr, "Bad value\n"); return -1; } } printf("Setting port %d to mode %d inhibit_charge %d...\n", - p.usb_port_id, p.mode, p.inhibit_charge); + p.usb_port_id, p.mode, p.inhibit_charge); - rv = ec_command(EC_CMD_USB_CHARGE_SET_MODE, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_USB_CHARGE_SET_MODE, 0, &p, sizeof(p), NULL, 0); if (rv < 0) return rv; @@ -6256,7 +6322,6 @@ int cmd_usb_charge_set_mode(int argc, char *argv[]) return 0; } - int cmd_usb_mux(int argc, char *argv[]) { struct ec_params_usb_mux p; @@ -6274,8 +6339,7 @@ int cmd_usb_mux(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_USB_MUX, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_USB_MUX, 0, &p, sizeof(p), NULL, 0); if (rv < 0) return rv; @@ -6284,13 +6348,12 @@ int cmd_usb_mux(int argc, char *argv[]) return 0; } - int cmd_usb_pd(int argc, char *argv[]) { - const char *role_str[] = {"", "toggle", "toggle-off", "sink", "source", - "freeze"}; - const char *mux_str[] = {"", "none", "usb", "dp", "dock", "auto"}; - const char *swap_str[] = {"", "dr_swap", "pr_swap", "vconn_swap"}; + const char *role_str[] = { "", "toggle", "toggle-off", + "sink", "source", "freeze" }; + const char *mux_str[] = { "", "none", "usb", "dp", "dock", "auto" }; + const char *swap_str[] = { "", "dr_swap", "pr_swap", "vconn_swap" }; struct ec_params_usb_pd_control p; struct ec_response_usb_pd_control_v2 *r_v2 = (struct ec_response_usb_pd_control_v2 *)ec_inbuf; @@ -6377,7 +6440,6 @@ int cmd_usb_pd(int argc, char *argv[]) } } - if (!option_ok) { fprintf(stderr, "Unknown option: %s\n", argv[i]); return -1; @@ -6391,8 +6453,8 @@ int cmd_usb_pd(int argc, char *argv[]) else cmdver = 0; - rv = ec_command(EC_CMD_USB_PD_CONTROL, cmdver, &p, sizeof(p), - ec_inbuf, ec_max_insize); + rv = ec_command(EC_CMD_USB_PD_CONTROL, cmdver, &p, sizeof(p), ec_inbuf, + ec_max_insize); if (rv < 0 || argc != 2) return (rv < 0) ? rv : 0; @@ -6407,9 +6469,11 @@ int cmd_usb_pd(int argc, char *argv[]) "Role:%s %s%s, Polarity:CC%d\n", p.port, (r_v1->enabled & PD_CTRL_RESP_ENABLED_COMMS) ? - "enabled" : "disabled", + "enabled" : + "disabled", (r_v1->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) ? - "connected" : "disconnected", + "connected" : + "disconnected", r_v1->state, (r_v1->role & PD_CTRL_RESP_ROLE_POWER) ? "SRC" : "SNK", @@ -6455,21 +6519,26 @@ int cmd_usb_pd(int argc, char *argv[]) } printf("Cable type:%s\n", - r_v2->control_flags & USB_PD_CTRL_ACTIVE_CABLE ? - "Active" : "Passive"); + r_v2->control_flags & USB_PD_CTRL_ACTIVE_CABLE ? + "Active" : + "Passive"); printf("TBT Adapter type:%s\n", - r_v2->control_flags & - USB_PD_CTRL_TBT_LEGACY_ADAPTER ? - "Legacy" : "Gen3"); + r_v2->control_flags & + USB_PD_CTRL_TBT_LEGACY_ADAPTER ? + "Legacy" : + "Gen3"); printf("Optical Cable:%s\n", - r_v2->control_flags & - USB_PD_CTRL_OPTICAL_CABLE ? "True" : "False"); + r_v2->control_flags & USB_PD_CTRL_OPTICAL_CABLE ? + "True" : + "False"); printf("Link LSRX Communication:%s-directional\n", - r_v2->control_flags & - USB_PD_CTRL_ACTIVE_LINK_UNIDIR ? "Uni" : "Bi"); + r_v2->control_flags & + USB_PD_CTRL_ACTIVE_LINK_UNIDIR ? + "Uni" : + "Bi"); printf("TBT Cable Speed:"); switch (r_v2->cable_speed) { @@ -6488,20 +6557,24 @@ int cmd_usb_pd(int argc, char *argv[]) printf("\n"); printf("Rounded support: 3rd Gen %srounded support\n", - r_v2->cable_gen ? "and 4th Gen " : ""); + r_v2->cable_gen ? "and 4th Gen " : ""); } /* If connected to a PD device, then print port partner info */ if ((r_v1->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) && (r_v1->enabled & PD_CTRL_RESP_ENABLED_PD_CAPABLE)) printf("PD Partner Capabilities:\n%s%s%s%s", - (r_v1->role & PD_CTRL_RESP_ROLE_DR_POWER) ? - " DR power\n" : "", - (r_v1->role & PD_CTRL_RESP_ROLE_DR_DATA) ? - " DR data\n" : "", - (r_v1->role & PD_CTRL_RESP_ROLE_USB_COMM) ? - " USB capable\n" : "", - (r_v1->role & PD_CTRL_RESP_ROLE_UNCONSTRAINED) ? - " Unconstrained power\n" : ""); + (r_v1->role & PD_CTRL_RESP_ROLE_DR_POWER) ? + " DR power\n" : + "", + (r_v1->role & PD_CTRL_RESP_ROLE_DR_DATA) ? + " DR data\n" : + "", + (r_v1->role & PD_CTRL_RESP_ROLE_USB_COMM) ? + " USB capable\n" : + "", + (r_v1->role & PD_CTRL_RESP_ROLE_UNCONSTRAINED) ? + " Unconstrained power\n" : + ""); } return 0; } @@ -6529,8 +6602,7 @@ int cmd_usb_pd_dps(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_USB_PD_DPS_CONTROL, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_USB_PD_DPS_CONTROL, 0, &p, sizeof(p), NULL, 0); if (rv < 0) return rv; @@ -6556,8 +6628,7 @@ static void print_pd_power_info(struct ec_response_usb_pd_power_info *r) printf("Unknown"); } - if ((r->role == USB_PD_PORT_POWER_SOURCE) && - (r->meas.current_max)) + if ((r->role == USB_PD_PORT_POWER_SOURCE) && (r->meas.current_max)) printf(" %dmA", r->meas.current_max); if ((r->role == USB_PD_PORT_POWER_DISCONNECTED) || @@ -6596,9 +6667,8 @@ static void print_pd_power_info(struct ec_response_usb_pd_power_info *r) printf(" Unknown"); break; } - printf(" %dmV / %dmA, max %dmV / %dmA", - r->meas.voltage_now, r->meas.current_lim, r->meas.voltage_max, - r->meas.current_max); + printf(" %dmV / %dmA, max %dmV / %dmA", r->meas.voltage_now, + r->meas.current_lim, r->meas.voltage_max, r->meas.current_max); if (r->max_power) printf(" / %dmW", r->max_power / 1000); printf("\n"); @@ -6618,17 +6688,16 @@ int cmd_usb_pd_mux_info(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_USB_PD_PORTS, 0, NULL, 0, - ec_inbuf, ec_max_insize); + rv = ec_command(EC_CMD_USB_PD_PORTS, 0, NULL, 0, ec_inbuf, + ec_max_insize); if (rv < 0) return rv; num_ports = ((struct ec_response_usb_pd_ports *)ec_inbuf)->num_ports; for (i = 0; i < num_ports; i++) { p.port = i; - rv = ec_command(EC_CMD_USB_PD_MUX_INFO, 0, - &p, sizeof(p), - &r, sizeof(r)); + rv = ec_command(EC_CMD_USB_PD_MUX_INFO, 0, &p, sizeof(p), &r, + sizeof(r)); if (rv < 0) return rv; @@ -6642,29 +6711,27 @@ int cmd_usb_pd_mux_info(int argc, char *argv[]) printf("%d\t", i); printf("%d\t", !!(r.flags & USB_PD_MUX_USB_ENABLED)); printf("%d\t", !!(r.flags & USB_PD_MUX_DP_ENABLED)); - printf("%s\t", - r.flags & USB_PD_MUX_POLARITY_INVERTED ? - "INVERTED" : "NORMAL"); + printf("%s\t", r.flags & USB_PD_MUX_POLARITY_INVERTED ? + "INVERTED" : + "NORMAL"); printf("%d\t", !!(r.flags & USB_PD_MUX_HPD_IRQ)); printf("%d\n", !!(r.flags & USB_PD_MUX_HPD_LVL)); } else { /* Human-readable mux info. */ printf("Port %d: ", i); - printf("USB=%d ", - !!(r.flags & USB_PD_MUX_USB_ENABLED)); + printf("USB=%d ", !!(r.flags & USB_PD_MUX_USB_ENABLED)); printf("DP=%d ", !!(r.flags & USB_PD_MUX_DP_ENABLED)); printf("POLARITY=%s ", - r.flags & USB_PD_MUX_POLARITY_INVERTED ? - "INVERTED" : "NORMAL"); - printf("HPD_IRQ=%d ", - !!(r.flags & USB_PD_MUX_HPD_IRQ)); - printf("HPD_LVL=%d ", - !!(r.flags & USB_PD_MUX_HPD_LVL)); + r.flags & USB_PD_MUX_POLARITY_INVERTED ? + "INVERTED" : + "NORMAL"); + printf("HPD_IRQ=%d ", !!(r.flags & USB_PD_MUX_HPD_IRQ)); + printf("HPD_LVL=%d ", !!(r.flags & USB_PD_MUX_HPD_LVL)); printf("SAFE=%d ", !!(r.flags & USB_PD_MUX_SAFE_MODE)); printf("TBT=%d ", - !!(r.flags & USB_PD_MUX_TBT_COMPAT_ENABLED)); + !!(r.flags & USB_PD_MUX_TBT_COMPAT_ENABLED)); printf("USB4=%d ", - !!(r.flags & USB_PD_MUX_USB4_ENABLED)); + !!(r.flags & USB_PD_MUX_USB4_ENABLED)); printf("\n"); } } @@ -6680,8 +6747,8 @@ int cmd_usb_pd_power(int argc, char *argv[]) int num_ports, i, rv; char *e; - rv = ec_command(EC_CMD_USB_PD_PORTS, 0, NULL, 0, - ec_inbuf, ec_max_insize); + rv = ec_command(EC_CMD_USB_PD_PORTS, 0, NULL, 0, ec_inbuf, + ec_max_insize); if (rv < 0) return rv; num_ports = ((struct ec_response_usb_pd_ports *)r)->num_ports; @@ -6689,9 +6756,8 @@ int cmd_usb_pd_power(int argc, char *argv[]) if (argc < 2) { for (i = 0; i < num_ports; i++) { p.port = i; - rv = ec_command(EC_CMD_USB_PD_POWER_INFO, 0, - &p, sizeof(p), - ec_inbuf, ec_max_insize); + rv = ec_command(EC_CMD_USB_PD_POWER_INFO, 0, &p, + sizeof(p), ec_inbuf, ec_max_insize); if (rv < 0) return rv; @@ -6704,8 +6770,7 @@ int cmd_usb_pd_power(int argc, char *argv[]) fprintf(stderr, "Bad port.\n"); return -1; } - rv = ec_command(EC_CMD_USB_PD_POWER_INFO, 0, - &p, sizeof(p), + rv = ec_command(EC_CMD_USB_PD_POWER_INFO, 0, &p, sizeof(p), ec_inbuf, ec_max_insize); if (rv < 0) return rv; @@ -6724,8 +6789,7 @@ int cmd_kbpress(int argc, char *argv[]) int rv; if (argc != 4) { - fprintf(stderr, - "Usage: %s <row> <col> <0|1>\n", argv[0]); + fprintf(stderr, "Usage: %s <row> <col> <0|1>\n", argv[0]); return -1; } p.row = strtol(argv[1], &e, 0); @@ -6745,11 +6809,9 @@ int cmd_kbpress(int argc, char *argv[]) } printf("%s row %d col %d.\n", p.pressed ? "Pressing" : "Releasing", - p.row, - p.col); + p.row, p.col); - rv = ec_command(EC_CMD_MKBP_SIMULATE_KEY, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_MKBP_SIMULATE_KEY, 0, &p, sizeof(p), NULL, 0); if (rv < 0) return rv; printf("Done.\n"); @@ -6761,14 +6823,14 @@ int cmd_keyboard_factory_test(int argc, char *argv[]) struct ec_response_keyboard_factory_test r; int rv; - rv = ec_command(EC_CMD_KEYBOARD_FACTORY_TEST, 0, - NULL, 0, &r, sizeof(r)); + rv = ec_command(EC_CMD_KEYBOARD_FACTORY_TEST, 0, NULL, 0, &r, + sizeof(r)); if (rv < 0) return rv; if (r.shorted != 0) printf("Keyboard %d and %d pin are shorted.\n", - r.shorted & 0x00ff, r.shorted >> 8); + r.shorted & 0x00ff, r.shorted >> 8); else printf("Keyboard factory test passed.\n"); @@ -6779,8 +6841,8 @@ int cmd_panic_info(int argc, char *argv[]) { int rv; - rv = ec_command(EC_CMD_GET_PANIC_INFO, 0, NULL, 0, - ec_inbuf, ec_max_insize); + rv = ec_command(EC_CMD_GET_PANIC_INFO, 0, NULL, 0, ec_inbuf, + ec_max_insize); if (rv < 0) return rv; @@ -6792,7 +6854,6 @@ int cmd_panic_info(int argc, char *argv[]) return parse_panic_info((char *)(ec_inbuf), rv); } - int cmd_power_info(int argc, char *argv[]) { struct ec_response_power_info_v1 r; @@ -6832,7 +6893,6 @@ int cmd_power_info(int argc, char *argv[]) return 0; } - int cmd_pse(int argc, char *argv[]) { struct ec_params_pse p; @@ -6895,7 +6955,6 @@ int cmd_pse(int argc, char *argv[]) return 0; } - int cmd_pstore_info(int argc, char *argv[]) { struct ec_response_pstore_info r; @@ -6909,7 +6968,6 @@ int cmd_pstore_info(int argc, char *argv[]) return 0; } - int cmd_pstore_read(int argc, char *argv[]) { struct ec_params_pstore_read p; @@ -6921,8 +6979,8 @@ int cmd_pstore_read(int argc, char *argv[]) char *buf; if (argc < 4) { - fprintf(stderr, - "Usage: %s <offset> <size> <filename>\n", argv[0]); + fprintf(stderr, "Usage: %s <offset> <size> <filename>\n", + argv[0]); return -1; } offset = strtol(argv[1], &e, 0); @@ -6947,8 +7005,8 @@ int cmd_pstore_read(int argc, char *argv[]) for (i = 0; i < size; i += EC_PSTORE_SIZE_MAX) { p.offset = offset + i; p.size = MIN(size - i, EC_PSTORE_SIZE_MAX); - rv = ec_command(EC_CMD_PSTORE_READ, 0, - &p, sizeof(p), rdata, sizeof(rdata)); + rv = ec_command(EC_CMD_PSTORE_READ, 0, &p, sizeof(p), rdata, + sizeof(rdata)); if (rv < 0) { fprintf(stderr, "Read error at offset %d\n", i); free(buf); @@ -6966,7 +7024,6 @@ int cmd_pstore_read(int argc, char *argv[]) return 0; } - int cmd_pstore_write(int argc, char *argv[]) { struct ec_params_pstore_write p; @@ -6998,8 +7055,7 @@ int cmd_pstore_write(int argc, char *argv[]) p.offset = offset + i; p.size = MIN(size - i, EC_PSTORE_SIZE_MAX); memcpy(p.data, buf + i, p.size); - rv = ec_command(EC_CMD_PSTORE_WRITE, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_PSTORE_WRITE, 0, &p, sizeof(p), NULL, 0); if (rv < 0) { fprintf(stderr, "Write error at offset %d\n", i); free(buf); @@ -7012,7 +7068,6 @@ int cmd_pstore_write(int argc, char *argv[]) return 0; } - int cmd_host_event_get_raw(int argc, char *argv[]) { uint32_t events = read_mapped_mem32(EC_MEMMAP_HOST_EVENTS); @@ -7026,14 +7081,12 @@ int cmd_host_event_get_raw(int argc, char *argv[]) return 0; } - int cmd_host_event_get_b(int argc, char *argv[]) { struct ec_response_host_event_mask r; int rv; - rv = ec_command(EC_CMD_HOST_EVENT_GET_B, 0, - NULL, 0, &r, sizeof(r)); + rv = ec_command(EC_CMD_HOST_EVENT_GET_B, 0, NULL, 0, &r, sizeof(r)); if (rv < 0) return rv; if (rv < sizeof(r)) { @@ -7050,14 +7103,13 @@ int cmd_host_event_get_b(int argc, char *argv[]) return 0; } - int cmd_host_event_get_smi_mask(int argc, char *argv[]) { struct ec_response_host_event_mask r; int rv; - rv = ec_command(EC_CMD_HOST_EVENT_GET_SMI_MASK, 0, - NULL, 0, &r, sizeof(r)); + rv = ec_command(EC_CMD_HOST_EVENT_GET_SMI_MASK, 0, NULL, 0, &r, + sizeof(r)); if (rv < 0) return rv; @@ -7065,14 +7117,13 @@ int cmd_host_event_get_smi_mask(int argc, char *argv[]) return 0; } - int cmd_host_event_get_sci_mask(int argc, char *argv[]) { struct ec_response_host_event_mask r; int rv; - rv = ec_command(EC_CMD_HOST_EVENT_GET_SCI_MASK, 0, - NULL, 0, &r, sizeof(r)); + rv = ec_command(EC_CMD_HOST_EVENT_GET_SCI_MASK, 0, NULL, 0, &r, + sizeof(r)); if (rv < 0) return rv; @@ -7080,14 +7131,13 @@ int cmd_host_event_get_sci_mask(int argc, char *argv[]) return 0; } - int cmd_host_event_get_wake_mask(int argc, char *argv[]) { struct ec_response_host_event_mask r; int rv; - rv = ec_command(EC_CMD_HOST_EVENT_GET_WAKE_MASK, 0, - NULL, 0, &r, sizeof(r)); + rv = ec_command(EC_CMD_HOST_EVENT_GET_WAKE_MASK, 0, NULL, 0, &r, + sizeof(r)); if (rv < 0) return rv; @@ -7095,7 +7145,6 @@ int cmd_host_event_get_wake_mask(int argc, char *argv[]) return 0; } - int cmd_host_event_set_smi_mask(int argc, char *argv[]) { struct ec_params_host_event_mask p; @@ -7112,8 +7161,8 @@ int cmd_host_event_set_smi_mask(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_HOST_EVENT_SET_SMI_MASK, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_HOST_EVENT_SET_SMI_MASK, 0, &p, sizeof(p), NULL, + 0); if (rv < 0) return rv; @@ -7121,7 +7170,6 @@ int cmd_host_event_set_smi_mask(int argc, char *argv[]) return 0; } - int cmd_host_event_set_sci_mask(int argc, char *argv[]) { struct ec_params_host_event_mask p; @@ -7138,8 +7186,8 @@ int cmd_host_event_set_sci_mask(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_HOST_EVENT_SET_SCI_MASK, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_HOST_EVENT_SET_SCI_MASK, 0, &p, sizeof(p), NULL, + 0); if (rv < 0) return rv; @@ -7147,7 +7195,6 @@ int cmd_host_event_set_sci_mask(int argc, char *argv[]) return 0; } - int cmd_host_event_set_wake_mask(int argc, char *argv[]) { struct ec_params_host_event_mask p; @@ -7164,8 +7211,8 @@ int cmd_host_event_set_wake_mask(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_HOST_EVENT_SET_WAKE_MASK, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_HOST_EVENT_SET_WAKE_MASK, 0, &p, sizeof(p), NULL, + 0); if (rv < 0) return rv; @@ -7173,7 +7220,6 @@ int cmd_host_event_set_wake_mask(int argc, char *argv[]) return 0; } - int cmd_host_event_clear(int argc, char *argv[]) { struct ec_params_host_event_mask p; @@ -7190,8 +7236,7 @@ int cmd_host_event_clear(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_HOST_EVENT_CLEAR, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_HOST_EVENT_CLEAR, 0, &p, sizeof(p), NULL, 0); if (rv < 0) return rv; @@ -7199,7 +7244,6 @@ int cmd_host_event_clear(int argc, char *argv[]) return 0; } - int cmd_host_event_clear_b(int argc, char *argv[]) { struct ec_params_host_event_mask p; @@ -7216,8 +7260,7 @@ int cmd_host_event_clear_b(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_HOST_EVENT_CLEAR_B, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_HOST_EVENT_CLEAR_B, 0, &p, sizeof(p), NULL, 0); if (rv < 0) return rv; @@ -7225,7 +7268,6 @@ int cmd_host_event_clear_b(int argc, char *argv[]) return 0; } - int cmd_switches(int argc, char *argv[]) { uint8_t s = read_mapped_mem8(EC_MEMMAP_SWITCHES); @@ -7242,7 +7284,6 @@ int cmd_switches(int argc, char *argv[]) return 0; } - int cmd_wireless(int argc, char *argv[]) { char *e; @@ -7271,8 +7312,8 @@ int cmd_wireless(int argc, char *argv[]) struct ec_params_switch_enable_wireless_v0 p; p.enabled = now_flags; - rv = ec_command(EC_CMD_SWITCH_ENABLE_WIRELESS, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_SWITCH_ENABLE_WIRELESS, 0, &p, sizeof(p), + NULL, 0); if (rv < 0) return rv; @@ -7307,19 +7348,18 @@ int cmd_wireless(int argc, char *argv[]) } rv = ec_command(EC_CMD_SWITCH_ENABLE_WIRELESS, - EC_VER_SWITCH_ENABLE_WIRELESS, - &p, sizeof(p), &r, sizeof(r)); + EC_VER_SWITCH_ENABLE_WIRELESS, &p, sizeof(p), + &r, sizeof(r)); if (rv < 0) return rv; - printf("Now=0x%x, suspend=0x%x\n", - r.now_flags, r.suspend_flags); + printf("Now=0x%x, suspend=0x%x\n", r.now_flags, + r.suspend_flags); } return 0; } - static void cmd_locate_chip_help(const char *const cmd) { fprintf(stderr, @@ -7331,15 +7371,12 @@ static void cmd_locate_chip_help(const char *const cmd) cmd); } -static const char *bus_type[] = { - "I2C", - "EMBEDDED" -}; +static const char *bus_type[] = { "I2C", "EMBEDDED" }; int cmd_locate_chip(int argc, char *argv[]) { struct ec_params_locate_chip p; - struct ec_response_locate_chip r = {0}; + struct ec_response_locate_chip r = { 0 }; char *e; int rv; @@ -7382,8 +7419,8 @@ int cmd_locate_chip(int argc, char *argv[]) if (rv < 0) return rv; - if (r.bus_type >= EC_BUS_TYPE_COUNT - || r.bus_type >= ARRAY_SIZE(bus_type)) { + if (r.bus_type >= EC_BUS_TYPE_COUNT || + r.bus_type >= ARRAY_SIZE(bus_type)) { fprintf(stderr, "Unknown bus type (%d)\n", r.bus_type); return -1; } @@ -7415,8 +7452,8 @@ int cmd_lcd_backlight(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_SWITCH_ENABLE_BKLIGHT, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_SWITCH_ENABLE_BKLIGHT, 0, &p, sizeof(p), NULL, + 0); if (rv < 0) return rv; @@ -7426,8 +7463,7 @@ int cmd_lcd_backlight(int argc, char *argv[]) static void cmd_basestate_help(void) { - fprintf(stderr, - "Usage: ectool basestate [attach | detach | reset]\n"); + fprintf(stderr, "Usage: ectool basestate [attach | detach | reset]\n"); } int cmd_basestate(int argc, char *argv[]) @@ -7450,8 +7486,7 @@ int cmd_basestate(int argc, char *argv[]) return -1; } - return ec_command(EC_CMD_SET_BASE_STATE, 0, - &p, sizeof(p), NULL, 0); + return ec_command(EC_CMD_SET_BASE_STATE, 0, &p, sizeof(p), NULL, 0); } int cmd_ext_power_limit(int argc, char *argv[]) @@ -7461,8 +7496,7 @@ int cmd_ext_power_limit(int argc, char *argv[]) char *e; if (argc != 3) { - fprintf(stderr, - "Usage: %s <max_current_mA> <max_voltage_mV>\n", + fprintf(stderr, "Usage: %s <max_current_mA> <max_voltage_mV>\n", argv[0]); return -1; } @@ -7480,11 +7514,10 @@ int cmd_ext_power_limit(int argc, char *argv[]) } /* Send version 1 of command */ - return ec_command(EC_CMD_EXTERNAL_POWER_LIMIT, 1, &p, sizeof(p), - NULL, 0); + return ec_command(EC_CMD_EXTERNAL_POWER_LIMIT, 1, &p, sizeof(p), NULL, + 0); } - int cmd_charge_current_limit(int argc, char *argv[]) { struct ec_params_current_limit p; @@ -7502,8 +7535,7 @@ int cmd_charge_current_limit(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_CHARGE_CURRENT_LIMIT, 0, &p, sizeof(p), - NULL, 0); + rv = ec_command(EC_CMD_CHARGE_CURRENT_LIMIT, 0, &p, sizeof(p), NULL, 0); return rv; } @@ -7513,16 +7545,16 @@ static void cmd_charge_control_help(const char *cmd, const char *msg) fprintf(stderr, "ERROR: %s\n", msg); fprintf(stderr, - "\n" - " Usage: %s\n" - " Get current settings.\n" - " Usage: %s normal|idle|discharge\n" - " Set charge mode (and disable battery sustainer).\n" - " Usage: %s normal <lower> <upper>\n" - " Enable battery sustainer. <lower> and <upper> are battery SoC\n" - " between which EC tries to keep the battery level.\n" - "\n", - cmd, cmd, cmd); + "\n" + " Usage: %s\n" + " Get current settings.\n" + " Usage: %s normal|idle|discharge\n" + " Set charge mode (and disable battery sustainer).\n" + " Usage: %s normal <lower> <upper>\n" + " Enable battery sustainer. <lower> and <upper> are battery SoC\n" + " between which EC tries to keep the battery level.\n" + "\n", + cmd, cmd, cmd); } int cmd_charge_control(int argc, char *argv[]) @@ -7530,7 +7562,7 @@ int cmd_charge_control(int argc, char *argv[]) struct ec_params_charge_control p; struct ec_response_charge_control r; int version = 2; - const char * const charge_mode_text[] = EC_CHARGE_MODE_TEXT; + const char *const charge_mode_text[] = EC_CHARGE_MODE_TEXT; char *e; int rv; @@ -7544,19 +7576,22 @@ int cmd_charge_control(int argc, char *argv[]) return -1; } p.cmd = EC_CHARGE_CONTROL_CMD_GET; - rv = ec_command(EC_CMD_CHARGE_CONTROL, version, - &p, sizeof(p), &r, sizeof(r)); + rv = ec_command(EC_CMD_CHARGE_CONTROL, version, &p, sizeof(p), + &r, sizeof(r)); if (rv < 0) { fprintf(stderr, "Command failed.\n"); return rv; } printf("Charge mode = %s (%d)\n", - r.mode < ARRAY_SIZE(charge_mode_text) - ? charge_mode_text[r.mode] : "UNDEFINED", + r.mode < ARRAY_SIZE(charge_mode_text) ? + charge_mode_text[r.mode] : + "UNDEFINED", r.mode); printf("Battery sustainer = %s (%d%% ~ %d%%)\n", - (r.sustain_soc.lower != -1 && r.sustain_soc.upper != -1) - ? "on" : "off", + (r.sustain_soc.lower != -1 && + r.sustain_soc.upper != -1) ? + "on" : + "off", r.sustain_soc.lower, r.sustain_soc.upper); return 0; } @@ -7569,20 +7604,21 @@ int cmd_charge_control(int argc, char *argv[]) p.sustain_soc.upper = -1; } else if (argc == 4) { if (version < 2) { - cmd_charge_control_help(argv[0], + cmd_charge_control_help( + argv[0], "Old EC doesn't support sustainer."); return -1; } p.sustain_soc.lower = strtol(argv[2], &e, 0); if (e && *e) { - cmd_charge_control_help(argv[0], - "Bad character in <lower>"); + cmd_charge_control_help( + argv[0], "Bad character in <lower>"); return -1; } p.sustain_soc.upper = strtol(argv[3], &e, 0); if (e && *e) { - cmd_charge_control_help(argv[0], - "Bad character in <upper>"); + cmd_charge_control_help( + argv[0], "Bad character in <upper>"); return -1; } } else { @@ -7615,8 +7651,10 @@ int cmd_charge_control(int argc, char *argv[]) switch (p.mode) { case CHARGE_CONTROL_NORMAL: printf("Charge state machine is in normal mode%s.\n", - (p.sustain_soc.lower == -1 || p.sustain_soc.upper == -1) - ? "" : " with sustainer enabled"); + (p.sustain_soc.lower == -1 || + p.sustain_soc.upper == -1) ? + "" : + " with sustainer enabled"); break; case CHARGE_CONTROL_IDLE: printf("Charge state machine force idle.\n"); @@ -7630,7 +7668,6 @@ int cmd_charge_control(int argc, char *argv[]) return 0; } - static void print_bool(const char *name, bool value) { printf("%s = %s\n", name, value ? "true" : "false"); @@ -7677,7 +7714,6 @@ usage: return -1; } - #define ST_CMD_SIZE ST_FLD_SIZE(ec_params_charge_state, cmd) #define ST_PRM_SIZE(SUBCMD) \ (ST_CMD_SIZE + ST_FLD_SIZE(ec_params_charge_state, SUBCMD)) @@ -7691,7 +7727,7 @@ static const struct { /* Order must match enum charge_state_command */ { ST_CMD_SIZE, ST_RSP_SIZE(get_state) }, { ST_PRM_SIZE(get_param), ST_RSP_SIZE(get_param) }, - { ST_PRM_SIZE(set_param), 0}, + { ST_PRM_SIZE(set_param), 0 }, }; BUILD_ASSERT(ARRAY_SIZE(cs_paramcount) == CHARGE_STATE_NUM_CMDS); @@ -7705,20 +7741,16 @@ static int cs_do_cmd(struct ec_params_charge_state *to_ec, int rv; int cmd = to_ec->cmd; - rv = ec_command(EC_CMD_CHARGE_STATE, 0, - to_ec, cs_paramcount[cmd].to_ec_size, - from_ec, cs_paramcount[cmd].from_ec_size); + rv = ec_command(EC_CMD_CHARGE_STATE, 0, to_ec, + cs_paramcount[cmd].to_ec_size, from_ec, + cs_paramcount[cmd].from_ec_size); return (rv < 0 ? 1 : 0); } -static const char * const base_params[] = { - "chg_voltage", - "chg_current", - "chg_input_current", - "chg_status", - "chg_option", - "limit_power", +static const char *const base_params[] = { + "chg_voltage", "chg_current", "chg_input_current", + "chg_status", "chg_option", "limit_power", }; BUILD_ASSERT(ARRAY_SIZE(base_params) == CS_NUM_BASE_PARAMS); @@ -7825,8 +7857,8 @@ int cmd_gpio_get(int argc, char *argv[]) } strcpy(p.name, argv[1]); - rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p, - sizeof(p), &r, sizeof(r)); + rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p, sizeof(p), &r, + sizeof(r)); if (rv < 0) return rv; @@ -7860,21 +7892,21 @@ int cmd_gpio_get(int argc, char *argv[]) } strcpy(p_v1.get_value_by_name.name, argv[1]); - rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p_v1, - sizeof(p_v1), &r_v1, sizeof(r_v1)); + rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p_v1, sizeof(p_v1), + &r_v1, sizeof(r_v1)); if (rv < 0) return rv; printf("GPIO %s = %d\n", p_v1.get_value_by_name.name, - r_v1.get_value_by_name.val); + r_v1.get_value_by_name.val); return 0; } /* Need GPIO count for EC_GPIO_GET_COUNT or EC_GPIO_GET_INFO */ p_v1.subcmd = EC_GPIO_GET_COUNT; - rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p_v1, - sizeof(p_v1), &r_v1, sizeof(r_v1)); + rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p_v1, sizeof(p_v1), &r_v1, + sizeof(r_v1)); if (rv < 0) return rv; @@ -7890,19 +7922,18 @@ int cmd_gpio_get(int argc, char *argv[]) for (i = 0; i < num_gpios; i++) { p_v1.get_info.index = i; - rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p_v1, - sizeof(p_v1), &r_v1, sizeof(r_v1)); + rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p_v1, sizeof(p_v1), + &r_v1, sizeof(r_v1)); if (rv < 0) return rv; printf("%2d %-32s 0x%04X\n", r_v1.get_info.val, - r_v1.get_info.name, r_v1.get_info.flags); + r_v1.get_info.name, r_v1.get_info.flags); } return 0; } - int cmd_gpio_set(int argc, char *argv[]) { struct ec_params_gpio_set p; @@ -7947,6 +7978,8 @@ void print_battery_flags(int flags) printf(" CHARGING"); if (flags & EC_BATT_FLAG_LEVEL_CRITICAL) printf(" LEVEL_CRITICAL"); + if (flags & EC_BATT_FLAG_CUT_OFF) + printf(" CUT_OFF"); printf("\n"); } @@ -7961,16 +7994,14 @@ int get_battery_command(int index) printf("Battery %d info:\n", index); static_p.index = index; - rv = ec_command(EC_CMD_BATTERY_GET_STATIC, 1, - &static_p, sizeof(static_p), - &static_r, sizeof(static_r)); + rv = ec_command(EC_CMD_BATTERY_GET_STATIC, 1, &static_p, + sizeof(static_p), &static_r, sizeof(static_r)); if (rv < 0) return -1; dynamic_p.index = index; - rv = ec_command(EC_CMD_BATTERY_GET_DYNAMIC, 0, - &dynamic_p, sizeof(dynamic_p), - &dynamic_r, sizeof(dynamic_r)); + rv = ec_command(EC_CMD_BATTERY_GET_DYNAMIC, 0, &dynamic_p, + sizeof(dynamic_p), &dynamic_r, sizeof(dynamic_r)); if (rv < 0) return -1; @@ -8021,7 +8052,7 @@ int get_battery_command(int index) if (!is_battery_range(dynamic_r.remaining_capacity)) goto cmd_error; printf(" Remaining capacity %u mAh\n", - dynamic_r.remaining_capacity); + dynamic_r.remaining_capacity); if (!is_battery_range(dynamic_r.desired_voltage)) goto cmd_error; @@ -8062,8 +8093,7 @@ int cmd_battery(int argc, char *argv[]) * Read non-primary batteries through hostcmd, and all batteries * if longer strings are supported for static info. */ - if (index > 0 || - ec_cmd_version_supported(EC_CMD_BATTERY_GET_STATIC, 1)) + if (index > 0 || ec_cmd_version_supported(EC_CMD_BATTERY_GET_STATIC, 1)) return get_battery_command(index); val = read_mapped_mem8(EC_MEMMAP_BATTERY_VERSION); @@ -8077,25 +8107,25 @@ int cmd_battery(int argc, char *argv[]) printf("Battery info:\n"); rv = read_mapped_string(EC_MEMMAP_BATT_MFGR, batt_text, - sizeof(batt_text)); + sizeof(batt_text)); if (rv < 0 || !is_string_printable(batt_text)) goto cmd_error; printf(" OEM name: %s\n", batt_text); rv = read_mapped_string(EC_MEMMAP_BATT_MODEL, batt_text, - sizeof(batt_text)); + sizeof(batt_text)); if (rv < 0 || !is_string_printable(batt_text)) goto cmd_error; printf(" Model number: %s\n", batt_text); rv = read_mapped_string(EC_MEMMAP_BATT_TYPE, batt_text, - sizeof(batt_text)); + sizeof(batt_text)); if (rv < 0 || !is_string_printable(batt_text)) goto cmd_error; printf(" Chemistry : %s\n", batt_text); rv = read_mapped_string(EC_MEMMAP_BATT_SERIAL, batt_text, - sizeof(batt_text)); + sizeof(batt_text)); printf(" Serial number: %s\n", batt_text); val = read_mapped_mem32(EC_MEMMAP_BATT_DCAP); @@ -8179,10 +8209,11 @@ int cmd_battery_cut_off(int argc, char *argv[]) if (rv < 0) { fprintf(stderr, "Failed to cut off battery, rv=%d\n", rv); - fprintf(stderr, "It is expected if the rv is -%d " - "(EC_RES_INVALID_COMMAND) if the battery " - "doesn't support cut-off function.\n", - EC_RES_INVALID_COMMAND); + fprintf(stderr, + "It is expected if the rv is -%d " + "(EC_RES_INVALID_COMMAND) if the battery " + "doesn't support cut-off function.\n", + EC_RES_INVALID_COMMAND); } else { printf("\n"); printf("SUCCESS. The battery has arranged a cut-off.\n"); @@ -8234,8 +8265,8 @@ int cmd_battery_vendor_param(int argc, char *argv[]) } } - rv = ec_command(EC_CMD_BATTERY_VENDOR_PARAM, 0, &p, sizeof(p), - &r, sizeof(r)); + rv = ec_command(EC_CMD_BATTERY_VENDOR_PARAM, 0, &p, sizeof(p), &r, + sizeof(r)); if (rv < 0) return rv; @@ -8269,28 +8300,30 @@ int cmd_board_version(int argc, char *argv[]) static void cmd_cbi_help(char *cmd) { fprintf(stderr, - " Usage: %s get <tag> [get_flag]\n" - " Usage: %s set <tag> <value/string> <size> [set_flag]\n" - " Usage: %s remove <tag> [set_flag]\n" - " <tag> is one of:\n" - " 0: BOARD_VERSION\n" - " 1: OEM_ID\n" - " 2: SKU_ID\n" - " 3: DRAM_PART_NUM (string)\n" - " 4: OEM_NAME (string)\n" - " 5: MODEL_ID\n" - " 6: FW_CONFIG\n" - " 7: PCB_VENDOR\n" - " 8: SSFC\n" - " 9: REWORK_ID\n" - " <size> is the size of the data in byte. It should be zero for\n" - " string types.\n" - " <value/string> is an integer or a string to be set\n" - " [get_flag] is combination of:\n" - " 01b: Invalidate cache and reload data from EEPROM\n" - " [set_flag] is combination of:\n" - " 01b: Skip write to EEPROM. Use for back-to-back writes\n" - " 10b: Set all fields to defaults first\n", cmd, cmd, cmd); + " Usage: %s get <tag> [get_flag]\n" + " Usage: %s set <tag> <value/string> <size> [set_flag]\n" + " Usage: %s remove <tag> [set_flag]\n" + " <tag> is one of:\n" + " 0: BOARD_VERSION\n" + " 1: OEM_ID\n" + " 2: SKU_ID\n" + " 3: DRAM_PART_NUM (string)\n" + " 4: OEM_NAME (string)\n" + " 5: MODEL_ID\n" + " 6: FW_CONFIG\n" + " 7: PCB_VENDOR\n" + " 8: SSFC\n" + " 9: REWORK_ID\n" + " 10: FACTORY_CALIBRATION_DATA\n" + " <size> is the size of the data in byte. It should be zero for\n" + " string types.\n" + " <value/string> is an integer or a string to be set\n" + " [get_flag] is combination of:\n" + " 01b: Invalidate cache and reload data from EEPROM\n" + " [set_flag] is combination of:\n" + " 01b: Skip write to EEPROM. Use for back-to-back writes\n" + " 10b: Set all fields to defaults first\n", + cmd, cmd, cmd); } static int cmd_cbi_is_string_field(enum cbi_data_tag tag) @@ -8347,15 +8380,15 @@ static int cmd_cbi(int argc, char *argv[]) if (cmd_cbi_is_string_field(tag)) { printf("%.*s", rv, (const char *)ec_inbuf); } else { - const uint8_t * const buffer = + const uint8_t *const buffer = (const uint8_t *const)(ec_inbuf); uint64_t int_value = 0; - for(i = 0; i < rv; i++) + for (i = 0; i < rv; i++) int_value |= (uint64_t)buffer[i] << (i * 8); - printf("As uint: %llu (0x%llx)\n", - (unsigned long long)int_value, - (unsigned long long)int_value); + printf("As uint: %llu (0x%llx)\n", + (unsigned long long)int_value, + (unsigned long long)int_value); printf("As binary:"); for (i = 0; i < rv; i++) { if (i % 32 == 31) @@ -8367,7 +8400,7 @@ static int cmd_cbi(int argc, char *argv[]) return 0; } else if (!strcasecmp(argv[1], "set")) { struct ec_params_set_cbi *p = - (struct ec_params_set_cbi *)ec_outbuf; + (struct ec_params_set_cbi *)ec_outbuf; void *val_ptr; uint64_t val = 0; uint8_t size; @@ -8397,11 +8430,11 @@ static int cmd_cbi(int argc, char *argv[]) size = strtol(argv[4], &e, 0); if (tag == CBI_TAG_REWORK_ID) { if ((e && *e) || size < 1 || size > 8 || - (size < 8 && val >= (1ull << size*8))) + (size < 8 && val >= (1ull << size * 8))) bad_size = 1; } else { if ((e && *e) || size < 1 || 4 < size || - val >= (1ull << size*8)) + val >= (1ull << size * 8)) bad_size = 1; } if (bad_size == 1) { @@ -8427,11 +8460,12 @@ static int cmd_cbi(int argc, char *argv[]) return -1; } } - rv = ec_command(EC_CMD_SET_CROS_BOARD_INFO, 0, - p, sizeof(*p) + size, NULL, 0); + rv = ec_command(EC_CMD_SET_CROS_BOARD_INFO, 0, p, + sizeof(*p) + size, NULL, 0); if (rv < 0) { if (rv == -EC_RES_ACCESS_DENIED - EECRESULT) - fprintf(stderr, "Write-protect is enabled or " + fprintf(stderr, + "Write-protect is enabled or " "EC explicitly refused to change the " "requested field.\n"); else @@ -8451,11 +8485,12 @@ static int cmd_cbi(int argc, char *argv[]) return -1; } } - rv = ec_command(EC_CMD_SET_CROS_BOARD_INFO, 0, - &p, sizeof(p), NULL, 0); + rv = ec_command(EC_CMD_SET_CROS_BOARD_INFO, 0, &p, sizeof(p), + NULL, 0); if (rv < 0) { if (rv == -EC_RES_ACCESS_DENIED - EECRESULT) - fprintf(stderr, "Write-protect is enabled or " + fprintf(stderr, + "Write-protect is enabled or " "EC explicitly refused to change the " "requested field.\n"); else @@ -8496,8 +8531,8 @@ int cmd_proto_info(int argc, char *argv[]) printf("Protocol info:\n"); - rv = ec_command(EC_CMD_GET_PROTOCOL_INFO, 0, NULL, 0, - &info, sizeof(info)); + rv = ec_command(EC_CMD_GET_PROTOCOL_INFO, 0, NULL, 0, &info, + sizeof(info)); if (rv < 0) { fprintf(stderr, "Protocol info unavailable. EC probably only " "supports protocol version 2.\n"); @@ -8533,7 +8568,6 @@ static int ec_hash_help(const char *cmd) return 0; } - static int ec_hash_print(const struct ec_response_vboot_hash *r) { int i; @@ -8565,7 +8599,6 @@ static int ec_hash_print(const struct ec_response_vboot_hash *r) return 0; } - int cmd_ec_hash(int argc, char *argv[]) { struct ec_params_vboot_hash p; @@ -8577,8 +8610,8 @@ int cmd_ec_hash(int argc, char *argv[]) if (argc < 2) { /* Get hash status */ p.cmd = EC_VBOOT_HASH_GET; - rv = ec_command(EC_CMD_VBOOT_HASH, 0, - &p, sizeof(p), &r, sizeof(r)); + rv = ec_command(EC_CMD_VBOOT_HASH, 0, &p, sizeof(p), &r, + sizeof(r)); if (rv < 0) return rv; @@ -8588,8 +8621,8 @@ int cmd_ec_hash(int argc, char *argv[]) if (argc == 2 && !strcasecmp(argv[1], "abort")) { /* Abort hash calculation */ p.cmd = EC_VBOOT_HASH_ABORT; - rv = ec_command(EC_CMD_VBOOT_HASH, 0, - &p, sizeof(p), &r, sizeof(r)); + rv = ec_command(EC_CMD_VBOOT_HASH, 0, &p, sizeof(p), &r, + sizeof(r)); return (rv < 0 ? rv : 0); } @@ -8660,7 +8693,6 @@ int cmd_ec_hash(int argc, char *argv[]) return ec_hash_print(&r); } - int cmd_rtc_get(int argc, char *argv[]) { struct ec_response_rtc r; @@ -8674,7 +8706,6 @@ int cmd_rtc_get(int argc, char *argv[]) return 0; } - int cmd_rtc_set(int argc, char *argv[]) { struct ec_params_rtc p; @@ -8754,8 +8785,8 @@ int cmd_console(int argc, char *argv[]) /* Loop and read from the snapshot until it's done */ while (1) { - rv = ec_command(EC_CMD_CONSOLE_READ, 0, - NULL, 0, ec_inbuf, ec_max_insize); + rv = ec_command(EC_CMD_CONSOLE_READ, 0, NULL, 0, ec_inbuf, + ec_max_insize); if (rv < 0) return rv; @@ -8771,17 +8802,16 @@ int cmd_console(int argc, char *argv[]) return 0; } struct param_info { - const char *name; /* name of this parameter */ - const char *help; /* help message */ - int size; /* size in bytes */ - int offset; /* offset within structure */ + const char *name; /* name of this parameter */ + const char *help; /* help message */ + int size; /* size in bytes */ + int offset; /* offset within structure */ }; -#define FIELD(fname, field, help_str) \ - { \ - .name = fname, \ - .help = help_str, \ - .size = sizeof(((struct ec_mkbp_config *)NULL)->field), \ +#define FIELD(fname, field, help_str) \ + { \ + .name = fname, .help = help_str, \ + .size = sizeof(((struct ec_mkbp_config *)NULL)->field), \ .offset = __builtin_offsetof(struct ec_mkbp_config, field), \ } @@ -8802,7 +8832,8 @@ static const struct param_info keyconfig_params[] = { }; static const struct param_info *find_field(const struct param_info *params, - int count, const char *name, unsigned int *nump) + int count, const char *name, + unsigned int *nump) { const struct param_info *param; int i; @@ -8846,7 +8877,7 @@ static int show_fields(struct ec_mkbp_config *config, int argc, char *argv[]) int i; if (!argc) { - mask = -1U; /* show all fields */ + mask = -1U; /* show all fields */ } else { mask = 0; while (argc > 0) { @@ -8938,7 +8969,8 @@ static int cmd_keyconfig(int argc, char *argv[]) const struct param_info *param; int i; - fprintf(stderr, "Usage: %s get [<param>] - print params\n" + fprintf(stderr, + "Usage: %s get [<param>] - print params\n" "\t%s set [<param>> <value>]\n" " Available params are: (all time values are in us)", argv[0], argv[0]); @@ -8974,14 +9006,14 @@ static int cmd_keyconfig(int argc, char *argv[]) return 0; } -static const char * const mkbp_button_strings[] = { +static const char *const mkbp_button_strings[] = { [EC_MKBP_POWER_BUTTON] = "Power", [EC_MKBP_VOL_UP] = "Volume up", [EC_MKBP_VOL_DOWN] = "Volume down", [EC_MKBP_RECOVERY] = "Recovery", }; -static const char * const mkbp_switch_strings[] = { +static const char *const mkbp_switch_strings[] = { [EC_MKBP_LID_OPEN] = "Lid open", [EC_MKBP_TABLET_MODE] = "Tablet mode", [EC_MKBP_BASE_ATTACHED] = "Base attached", @@ -9010,8 +9042,7 @@ static int cmd_mkbp_get(int argc, char *argv[]) } p.info_type = EC_MKBP_INFO_SUPPORTED; - rv = ec_command(EC_CMD_MKBP_INFO, 0, &p, sizeof(p), &r, - sizeof(r)); + rv = ec_command(EC_CMD_MKBP_INFO, 0, &p, sizeof(p), &r, sizeof(r)); if (rv < 0) return rv; if (p.event_type == EC_MKBP_EVENT_BUTTON) @@ -9022,8 +9053,7 @@ static int cmd_mkbp_get(int argc, char *argv[]) return -1; p.info_type = EC_MKBP_INFO_CURRENT; - rv = ec_command(EC_CMD_MKBP_INFO, 0, &p, sizeof(p), &r, - sizeof(r)); + rv = ec_command(EC_CMD_MKBP_INFO, 0, &p, sizeof(p), &r, sizeof(r)); if (rv < 0) return rv; @@ -9063,9 +9093,10 @@ static int cmd_mkbp_wake_mask(int argc, char *argv[]) int rv; if (argc < 3) { - fprintf(stderr, "Usage: %s get <event|hostevent>\n" - "\t%s set <event|hostevent> <mask>\n", argv[0], - argv[0]); + fprintf(stderr, + "Usage: %s get <event|hostevent>\n" + "\t%s set <event|hostevent> <mask>\n", + argv[0], argv[0]); return -1; } @@ -9104,15 +9135,16 @@ static int cmd_mkbp_wake_mask(int argc, char *argv[]) } } - rv = ec_command(EC_CMD_MKBP_WAKE_MASK, 0, &p, sizeof(p), &r, - sizeof(r)); + rv = ec_command(EC_CMD_MKBP_WAKE_MASK, 0, &p, sizeof(p), &r, sizeof(r)); if (rv < 0) { - if (rv == -EECRESULT-EC_RES_INVALID_PARAM) { - fprintf(stderr, "Unknown mask, or mask is not in use. " + if (rv == -EECRESULT - EC_RES_INVALID_PARAM) { + fprintf(stderr, + "Unknown mask, or mask is not in use. " "You may need to enable the " - "CONFIG_MKBP_%s_WAKEUP_MASK option in the EC.\n" - , p.mask_type == EC_MKBP_EVENT_WAKE_MASK ? - "EVENT" : "HOSTEVENT"); + "CONFIG_MKBP_%s_WAKEUP_MASK option in the EC.\n", + p.mask_type == EC_MKBP_EVENT_WAKE_MASK ? + "EVENT" : + "HOSTEVENT"); } return rv; } @@ -9137,8 +9169,8 @@ static int cmd_tmp006cal_v0(int idx, int argc, char *argv[]) /* Get current values */ pg.index = idx; - rv = ec_command(EC_CMD_TMP006_GET_CALIBRATION, 0, - &pg, sizeof(pg), &rg, sizeof(rg)); + rv = ec_command(EC_CMD_TMP006_GET_CALIBRATION, 0, &pg, sizeof(pg), &rg, + sizeof(rg)); if (rv < 0) return rv; @@ -9187,8 +9219,8 @@ static int cmd_tmp006cal_v0(int idx, int argc, char *argv[]) } /* Set 'em */ - return ec_command(EC_CMD_TMP006_SET_CALIBRATION, 0, - &ps, sizeof(ps), NULL, 0); + return ec_command(EC_CMD_TMP006_SET_CALIBRATION, 0, &ps, sizeof(ps), + NULL, 0); } /* Index is already checked. argv[0] is first param value */ @@ -9204,15 +9236,15 @@ static int cmd_tmp006cal_v1(int idx, int argc, char *argv[]) int i, rv, cmdsize; /* Algorithm 1 parameter names */ - static const char * const alg1_pname[] = { - "s0", "a1", "a2", "b0", "b1", "b2", "c2", - "d0", "d1", "ds", "e0", "e1", + static const char *const alg1_pname[] = { + "s0", "a1", "a2", "b0", "b1", "b2", + "c2", "d0", "d1", "ds", "e0", "e1", }; /* Get current values */ pg.index = idx; - rv = ec_command(EC_CMD_TMP006_GET_CALIBRATION, 1, - &pg, sizeof(pg), rg, ec_max_insize); + rv = ec_command(EC_CMD_TMP006_GET_CALIBRATION, 1, &pg, sizeof(pg), rg, + ec_max_insize); if (rv < 0) return rv; @@ -9254,8 +9286,8 @@ static int cmd_tmp006cal_v1(int idx, int argc, char *argv[]) /* Set 'em */ cmdsize = sizeof(*ps) + ps->num_params * sizeof(ps->val[0]); - return ec_command(EC_CMD_TMP006_SET_CALIBRATION, 1, - ps, cmdsize, NULL, 0); + return ec_command(EC_CMD_TMP006_SET_CALIBRATION, 1, ps, cmdsize, NULL, + 0); } int cmd_tmp006cal(int argc, char *argv[]) @@ -9372,8 +9404,8 @@ static int cmd_hang_detect(int argc, char *argv[]) } enum port_80_event { - PORT_80_EVENT_RESUME = 0x1001, /* S3->S0 transition */ - PORT_80_EVENT_RESET = 0x1002, /* RESET transition */ + PORT_80_EVENT_RESUME = 0x1001, /* S3->S0 transition */ + PORT_80_EVENT_RESET = 0x1002, /* RESET transition */ }; int cmd_port80_read(int argc, char *argv[]) @@ -9389,18 +9421,17 @@ int cmd_port80_read(int argc, char *argv[]) if (!ec_cmd_version_supported(EC_CMD_PORT80_READ, cmdver)) { /* fall back to last boot */ struct ec_response_port80_last_boot r; - rv = ec_command(EC_CMD_PORT80_LAST_BOOT, 0, - NULL, 0, &r, sizeof(r)); + rv = ec_command(EC_CMD_PORT80_LAST_BOOT, 0, NULL, 0, &r, + sizeof(r)); fprintf(stderr, "Last boot %2x\n", r.code); printf("done.\n"); return 0; } - /* read writes and history_size */ p.subcmd = EC_PORT80_GET_INFO; - rv = ec_command(EC_CMD_PORT80_READ, cmdver, - &p, sizeof(p), &rsp, sizeof(rsp)); + rv = ec_command(EC_CMD_PORT80_READ, cmdver, &p, sizeof(p), &rsp, + sizeof(rsp)); if (rv < 0) { fprintf(stderr, "Read error at writes\n"); return rv; @@ -9408,8 +9439,7 @@ int cmd_port80_read(int argc, char *argv[]) writes = rsp.get_info.writes; history_size = rsp.get_info.history_size; - history = (uint16_t *)( - malloc(history_size * sizeof(uint16_t))); + history = (uint16_t *)(malloc(history_size * sizeof(uint16_t))); if (!history) { fprintf(stderr, "Unable to allocate buffer.\n"); return -1; @@ -9427,15 +9457,15 @@ int cmd_port80_read(int argc, char *argv[]) for (i = 0; i < history_size; i += EC_PORT80_SIZE_MAX) { p.read_buffer.offset = i; p.read_buffer.num_entries = EC_PORT80_SIZE_MAX; - rv = ec_command(EC_CMD_PORT80_READ, cmdver, - &p, sizeof(p), &rsp, sizeof(rsp)); + rv = ec_command(EC_CMD_PORT80_READ, cmdver, &p, sizeof(p), &rsp, + sizeof(rsp)); if (rv < 0) { fprintf(stderr, "Read error at offset %d\n", i); free(history); return rv; } memcpy((void *)(history + i), rsp.data.codes, - EC_PORT80_SIZE_MAX*sizeof(uint16_t)); + EC_PORT80_SIZE_MAX * sizeof(uint16_t)); } head = writes; @@ -9516,8 +9546,8 @@ int cmd_charge_port_override(int argc, char *argv[]) } } - rv = ec_command(EC_CMD_PD_CHARGE_PORT_OVERRIDE, 0, &p, sizeof(p), - NULL, 0); + rv = ec_command(EC_CMD_PD_CHARGE_PORT_OVERRIDE, 0, &p, sizeof(p), NULL, + 0); if (rv < 0) return rv; @@ -9528,28 +9558,30 @@ int cmd_charge_port_override(int argc, char *argv[]) static void cmd_pchg_help(char *cmd) { fprintf(stderr, - " Usage1: %s\n" - " Print the number of ports.\n" - "\n" - " Usage2: %s <port>\n" - " Print the status of <port>.\n" - "\n" - " Usage3: %s <port> reset\n" - " Reset <port>.\n" - "\n" - " Usage4: %s <port> update <version> <addr1> <file1> <addr2> <file2> ...\n" - " Update firmware of <port>.\n", - cmd, cmd, cmd, cmd); + " Usage1: %s\n" + " Print the number of ports.\n" + "\n" + " Usage2: %s <port>\n" + " Print the status of <port>.\n" + "\n" + " Usage3: %s <port> reset\n" + " Reset <port>.\n" + "\n" + " Usage4: %s <port> update <version> <addr1> <file1> <addr2> <file2> ...\n" + " Update firmware of <port>.\n", + cmd, cmd, cmd, cmd); } static int cmd_pchg_info(const struct ec_response_pchg *res) { - static const char * const pchg_state_text[] = EC_PCHG_STATE_TEXT; + static const char *const pchg_state_text[] = EC_PCHG_STATE_TEXT; BUILD_ASSERT(ARRAY_SIZE(pchg_state_text) == PCHG_STATE_COUNT); - printf("State: %s (%d)\n", res->state < PCHG_STATE_COUNT - ? pchg_state_text[res->state] : "UNDEF", res->state); + printf("State: %s (%d)\n", + res->state < PCHG_STATE_COUNT ? pchg_state_text[res->state] : + "UNDEF", + res->state); printf("Battery: %u%%\n", res->battery_percentage); printf("Errors: 0x%x\n", res->error); printf("FW Version: 0x%x\n", res->fw_version); @@ -9577,8 +9609,8 @@ static int cmd_pchg_wait_event(int port, uint32_t expected) return 0; } - fprintf(stderr, "\nExpected event=0x%x but received 0x%x\n", - expected, *e); + fprintf(stderr, "\nExpected event=0x%x but received 0x%x\n", expected, + *e); return -1; } @@ -9617,8 +9649,8 @@ static int cmd_pchg_update_open(int port, uint32_t version, rv = ec_command(EC_CMD_PCHG, 2, &p, sizeof(p), &rv2, sizeof(rv2)); if (rv == -EC_RES_INVALID_VERSION - EECRESULT) /* We can use v2 because it's a superset of v1. */ - rv = ec_command(EC_CMD_PCHG, 1, &p, sizeof(p), - &rv2, sizeof(struct ec_response_pchg)); + rv = ec_command(EC_CMD_PCHG, 1, &p, sizeof(p), &rv2, + sizeof(struct ec_response_pchg)); if (rv < 0) { fprintf(stderr, "EC_CMD_PCHG failed: %d\n", rv); return rv; @@ -9632,8 +9664,8 @@ static int cmd_pchg_update_open(int port, uint32_t version, if (rv) return rv; - printf("Opened update session (port=%d ver=0x%x bsize=%d):\n", - port, version, r->block_size); + printf("Opened update session (port=%d ver=0x%x bsize=%d):\n", port, + version, r->block_size); *block_size = r->block_size; crc32_ctx_init(crc); @@ -9654,8 +9686,8 @@ static int cmd_pchg_update_write(int port, uint32_t address, fp = fopen(filename, "rb"); if (!fp) { - fprintf(stderr, "\nCan't open %s: %s\n", - filename, strerror(errno)); + fprintf(stderr, "\nCan't open %s: %s\n", filename, + strerror(errno)); return -1; } @@ -9675,8 +9707,8 @@ static int cmd_pchg_update_write(int port, uint32_t address, crc32_ctx_hash(crc, p->data, len); p->size = len; - rv = ec_command(EC_CMD_PCHG_UPDATE, 0, p, - sizeof(*p) + len, NULL, 0); + rv = ec_command(EC_CMD_PCHG_UPDATE, 0, p, sizeof(*p) + len, + NULL, 0); if (rv < 0) { fprintf(stderr, "\nFailed to write FW: %d\n", rv); fclose(fp); @@ -9775,8 +9807,8 @@ static int cmd_pchg(int argc, char *argv[]) u->cmd = EC_PCHG_UPDATE_CMD_RESET_TO_NORMAL; rv = ec_command(EC_CMD_PCHG_UPDATE, 0, u, sizeof(*u), NULL, 0); if (rv < 0) { - fprintf(stderr, "\nFailed to reset port %d: %d\n", - port, rv); + fprintf(stderr, "\nFailed to reset port %d: %d\n", port, + rv); cmd_pchg_help(argv[0]); return rv; } @@ -9824,12 +9856,12 @@ static int cmd_pchg(int argc, char *argv[]) cmd_pchg_help(argv[0]); return -1; } - rv = cmd_pchg_update_write(port, address, argv[i+1], + rv = cmd_pchg_update_write(port, address, argv[i + 1], block_size, &crc); if (rv < 0) { fprintf(stderr, "\nFailed to write file '%s': %d", - argv[i+i], rv); + argv[i + i], rv); return -1; } } @@ -9867,8 +9899,8 @@ int cmd_pd_log(int argc, char *argv[]) while (1) { now = time(NULL); - rv = ec_command(EC_CMD_PD_GET_LOG_ENTRY, 0, - NULL, 0, &u, sizeof(u)); + rv = ec_command(EC_CMD_PD_GET_LOG_ENTRY, 0, NULL, 0, &u, + sizeof(u)); if (rv < 0) return rv; @@ -9878,8 +9910,9 @@ int cmd_pd_log(int argc, char *argv[]) } /* the timestamp is in 1024th of seconds */ - milliseconds = ((uint64_t)u.r.timestamp << - PD_LOG_TIMESTAMP_SHIFT) / 1000; + milliseconds = + ((uint64_t)u.r.timestamp << PD_LOG_TIMESTAMP_SHIFT) / + 1000; /* the timestamp is the number of milliseconds in the past */ seconds = (milliseconds + 999) / 1000; milliseconds -= seconds * 1000; @@ -9887,18 +9920,18 @@ int cmd_pd_log(int argc, char *argv[]) localtime_r(&now, <ime); strftime(time_str, sizeof(time_str), "%F %T", <ime); printf("%s.%03lld P%d ", time_str, -milliseconds, - PD_LOG_PORT(u.r.size_port)); + PD_LOG_PORT(u.r.size_port)); if (u.r.type == PD_EVENT_MCU_CHARGE) { if (u.r.data & CHARGE_FLAGS_OVERRIDE) printf("override "); if (u.r.data & CHARGE_FLAGS_DELAYED_OVERRIDE) printf("pending_override "); memcpy(&pinfo.meas, u.r.payload, - sizeof(struct usb_chg_measures)); + sizeof(struct usb_chg_measures)); pinfo.dualrole = !!(u.r.data & CHARGE_FLAGS_DUAL_ROLE); pinfo.role = u.r.data & CHARGE_FLAGS_ROLE_MASK; - pinfo.type = (u.r.data & CHARGE_FLAGS_TYPE_MASK) - >> CHARGE_FLAGS_TYPE_SHIFT; + pinfo.type = (u.r.data & CHARGE_FLAGS_TYPE_MASK) >> + CHARGE_FLAGS_TYPE_SHIFT; pinfo.max_power = 0; print_pd_power_info(&pinfo); } else if (u.r.type == PD_EVENT_MCU_CONNECT) { @@ -9908,25 +9941,24 @@ int cmd_pd_log(int argc, char *argv[]) } else if (u.r.type == PD_EVENT_ACC_RW_FAIL) { printf("RW signature check failed\n"); } else if (u.r.type == PD_EVENT_PS_FAULT) { - static const char * const fault_names[] = { + static const char *const fault_names[] = { "---", "OCP", "fast OCP", "OVP", "Discharge" }; const char *fault = u.r.data < ARRAY_SIZE(fault_names) ? - fault_names[u.r.data] : "???"; + fault_names[u.r.data] : + "???"; printf("Power supply fault: %s\n", fault); } else if (u.r.type == PD_EVENT_VIDEO_DP_MODE) { - printf("DP mode %sabled\n", (u.r.data == 1) ? - "en" : "dis"); + printf("DP mode %sabled\n", + (u.r.data == 1) ? "en" : "dis"); } else if (u.r.type == PD_EVENT_VIDEO_CODEC) { - memcpy(&minfo, u.r.payload, - sizeof(struct mcdp_info)); + memcpy(&minfo, u.r.payload, sizeof(struct mcdp_info)); printf("HDMI info: family:%04x chipid:%04x " "irom:%d.%d.%d fw:%d.%d.%d\n", MCDP_FAMILY(minfo.family), - MCDP_CHIPID(minfo.chipid), - minfo.irom.major, minfo.irom.minor, - minfo.irom.build, minfo.fw.major, - minfo.fw.minor, minfo.fw.build); + MCDP_CHIPID(minfo.chipid), minfo.irom.major, + minfo.irom.minor, minfo.irom.build, + minfo.fw.major, minfo.fw.minor, minfo.fw.build); } else { /* Unknown type */ int i; printf("Event %02x (%04x) [", u.r.type, u.r.data); @@ -9989,7 +10021,8 @@ int cmd_pd_chip_info(int argc, char *argv[]) int cmdver = 1; if (argc < 2 || 3 < argc) { - fprintf(stderr, "Usage: %s <port> [<live>]\n" + fprintf(stderr, + "Usage: %s <port> [<live>]\n" "live parameter can take values 0 or 1\n" "0 -> Return hard-coded value for VID/PID and\n" " cached value for Firmware Version\n" @@ -10045,8 +10078,7 @@ int cmd_pd_write_log(int argc, char *argv[]) char *e; if (argc < 3) { - fprintf(stderr, "Usage: %s <log_type> <port>\n", - argv[0]); + fprintf(stderr, "Usage: %s <log_type> <port>\n", argv[0]); return -1; } @@ -10129,7 +10161,7 @@ int cmd_typec_control(int argc, char *argv[]) conversion_result = strtol(argv[3], &endptr, 0); if ((endptr && *endptr) || conversion_result > UINT8_MAX || - conversion_result < 0) { + conversion_result < 0) { fprintf(stderr, "Bad mode\n"); return -1; } @@ -10143,7 +10175,7 @@ int cmd_typec_control(int argc, char *argv[]) conversion_result = strtol(argv[3], &endptr, 0); if ((endptr && *endptr) || conversion_result > UINT8_MAX || - conversion_result < 0) { + conversion_result < 0) { fprintf(stderr, "Bad reply\n"); return -1; } @@ -10157,7 +10189,7 @@ int cmd_typec_control(int argc, char *argv[]) conversion_result = strtol(argv[3], &endptr, 0); if ((endptr && *endptr) || conversion_result > UINT8_MAX || - conversion_result < 0) { + conversion_result < 0) { fprintf(stderr, "Bad index\n"); return -1; } @@ -10183,8 +10215,8 @@ int cmd_typec_control(int argc, char *argv[]) break; } - rv = ec_command(EC_CMD_TYPEC_CONTROL, 0, &p, sizeof(p), - ec_inbuf, ec_max_insize); + rv = ec_command(EC_CMD_TYPEC_CONTROL, 0, &p, sizeof(p), ec_inbuf, + ec_max_insize); if (rv < 0) return -1; @@ -10195,7 +10227,7 @@ int cmd_typec_discovery(int argc, char *argv[]) { struct ec_params_typec_discovery p; struct ec_response_typec_discovery *r = - (struct ec_response_typec_discovery *)ec_inbuf; + (struct ec_response_typec_discovery *)ec_inbuf; char *e; int rv, i, j; @@ -10205,7 +10237,8 @@ int cmd_typec_discovery(int argc, char *argv[]) " <port> is the type-c port to query\n" " <type> is one of:\n" " 0: SOP\n" - " 1: SOP prime\n", argv[0]); + " 1: SOP prime\n", + argv[0]); return -1; } @@ -10221,8 +10254,8 @@ int cmd_typec_discovery(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_TYPEC_DISCOVERY, 0, &p, sizeof(p), - ec_inbuf, ec_max_insize); + rv = ec_command(EC_CMD_TYPEC_DISCOVERY, 0, &p, sizeof(p), ec_inbuf, + ec_max_insize); if (rv < 0) return -1; @@ -10252,10 +10285,8 @@ int cmd_typec_discovery(int argc, char *argv[]) /* Print shared fields of sink and source cap PDOs */ static inline void print_pdo_fixed(uint32_t pdo) { - printf(" Fixed: %dmV %dmA %s%s%s%s", - PDO_FIXED_VOLTAGE(pdo), - PDO_FIXED_CURRENT(pdo), - pdo & PDO_FIXED_DUAL_ROLE ? "DRP " : "", + printf(" Fixed: %dmV %dmA %s%s%s%s", PDO_FIXED_VOLTAGE(pdo), + PDO_FIXED_CURRENT(pdo), pdo & PDO_FIXED_DUAL_ROLE ? "DRP " : "", pdo & PDO_FIXED_UNCONSTRAINED ? "UP " : "", pdo & PDO_FIXED_COMM_CAP ? "USB " : "", pdo & PDO_FIXED_DATA_SWAP ? "DRD" : ""); @@ -10264,24 +10295,21 @@ static inline void print_pdo_fixed(uint32_t pdo) static inline void print_pdo_battery(uint32_t pdo) { printf(" Battery: max %dmV min %dmV max %dmW\n", - PDO_BATT_MAX_VOLTAGE(pdo), - PDO_BATT_MIN_VOLTAGE(pdo), + PDO_BATT_MAX_VOLTAGE(pdo), PDO_BATT_MIN_VOLTAGE(pdo), PDO_BATT_MAX_POWER(pdo)); } static inline void print_pdo_variable(uint32_t pdo) { printf(" Variable: max %dmV min %dmV max %dmA\n", - PDO_VAR_MAX_VOLTAGE(pdo), - PDO_VAR_MIN_VOLTAGE(pdo), + PDO_VAR_MAX_VOLTAGE(pdo), PDO_VAR_MIN_VOLTAGE(pdo), PDO_VAR_MAX_CURRENT(pdo)); } static inline void print_pdo_augmented(uint32_t pdo) { printf(" Augmented: max %dmV min %dmV max %dmA\n", - PDO_AUG_MAX_VOLTAGE(pdo), - PDO_AUG_MIN_VOLTAGE(pdo), + PDO_AUG_MAX_VOLTAGE(pdo), PDO_AUG_MIN_VOLTAGE(pdo), PDO_AUG_MAX_CURRENT(pdo)); } @@ -10289,7 +10317,7 @@ int cmd_typec_status(int argc, char *argv[]) { struct ec_params_typec_status p; struct ec_response_typec_status *r = - (struct ec_response_typec_status *)ec_inbuf; + (struct ec_response_typec_status *)ec_inbuf; char *endptr; int rv, i; const char *desc; @@ -10297,7 +10325,8 @@ int cmd_typec_status(int argc, char *argv[]) if (argc != 2) { fprintf(stderr, "Usage: %s <port>\n" - " <port> is the type-c port to query\n", argv[0]); + " <port> is the type-c port to query\n", + argv[0]); return -1; } @@ -10307,8 +10336,8 @@ int cmd_typec_status(int argc, char *argv[]) return -1; } - rv = ec_command(EC_CMD_TYPEC_STATUS, 0, &p, sizeof(p), - ec_inbuf, ec_max_insize); + rv = ec_command(EC_CMD_TYPEC_STATUS, 0, &p, sizeof(p), ec_inbuf, + ec_max_insize); if (rv == -EC_RES_INVALID_COMMAND - EECRESULT) /* Fall back to PD_CONTROL to support older ECs */ return cmd_usb_pd(argc, argv); @@ -10317,15 +10346,14 @@ int cmd_typec_status(int argc, char *argv[]) printf("Port C%d: %s, %s State:%s\n" "Role:%s %s%s, Polarity:CC%d\n", - p.port, - r->pd_enabled ? "enabled" : "disabled", - r->dev_connected ? "connected" : "disconnected", - r->tc_state, - (r->power_role == PD_ROLE_SOURCE) ? "SRC" : "SNK", - (r->data_role == PD_ROLE_DFP) ? "DFP" : - (r->data_role == PD_ROLE_UFP) ? "UFP" : "", - (r->vconn_role == PD_ROLE_VCONN_SRC) ? " VCONN" : "", - (r->polarity % 2 + 1)); + p.port, r->pd_enabled ? "enabled" : "disabled", + r->dev_connected ? "connected" : "disconnected", r->tc_state, + (r->power_role == PD_ROLE_SOURCE) ? "SRC" : "SNK", + (r->data_role == PD_ROLE_DFP) ? "DFP" : + (r->data_role == PD_ROLE_UFP) ? "UFP" : + "", + (r->vconn_role == PD_ROLE_VCONN_SRC) ? " VCONN" : "", + (r->polarity % 2 + 1)); switch (r->cc_state) { case PD_CC_NONE: @@ -10384,8 +10412,9 @@ int cmd_typec_status(int argc, char *argv[]) " SAFE=%d TBT=%d USB4=%d\n", !!(r->mux_state & USB_PD_MUX_USB_ENABLED), !!(r->mux_state & USB_PD_MUX_DP_ENABLED), - (r->mux_state & USB_PD_MUX_POLARITY_INVERTED) ? - "INVERTED" : "NORMAL", + (r->mux_state & USB_PD_MUX_POLARITY_INVERTED) ? + "INVERTED" : + "NORMAL", !!(r->mux_state & USB_PD_MUX_HPD_IRQ), !!(r->mux_state & USB_PD_MUX_HPD_LVL), !!(r->mux_state & USB_PD_MUX_SAFE_MODE), @@ -10444,8 +10473,8 @@ int cmd_typec_status(int argc, char *argv[]) if (pdo_type == PDO_TYPE_FIXED) { print_pdo_fixed(pdo); /* Note: FRS bits are reserved in PD 2.0 spec */ - printf("%s\n", pdo & PDO_FIXED_FRS_CURR_MASK ? - "FRS" : ""); + printf("%s\n", + pdo & PDO_FIXED_FRS_CURR_MASK ? "FRS" : ""); } else if (pdo_type == PDO_TYPE_BATTERY) { print_pdo_battery(pdo); } else if (pdo_type == PDO_TYPE_VARIABLE) { @@ -10458,7 +10487,7 @@ int cmd_typec_status(int argc, char *argv[]) return 0; } -int cmd_tp_self_test(int argc, char* argv[]) +int cmd_tp_self_test(int argc, char *argv[]) { int rv; @@ -10472,13 +10501,13 @@ int cmd_tp_self_test(int argc, char* argv[]) return rv; } -int cmd_tp_frame_get(int argc, char* argv[]) +int cmd_tp_frame_get(int argc, char *argv[]) { int i, j; uint32_t remaining = 0, offset = 0; int rv = EC_SUCCESS; uint8_t *data; - struct ec_response_tp_frame_info* r; + struct ec_response_tp_frame_info *r; struct ec_params_tp_frame_get p; data = (uint8_t *)(malloc(ec_max_insize)); @@ -10512,11 +10541,13 @@ int cmd_tp_frame_get(int argc, char* argv[]) p.offset = offset; p.size = MIN(remaining, ec_max_insize); - rv = ec_command(EC_CMD_TP_FRAME_GET, 0, - &p, sizeof(p), data, p.size); + rv = ec_command(EC_CMD_TP_FRAME_GET, 0, &p, sizeof(p), + data, p.size); if (rv < 0) { - fprintf(stderr, "Failed to get frame data " - "at offset 0x%x\n", offset); + fprintf(stderr, + "Failed to get frame data " + "at offset 0x%x\n", + offset); goto err; } @@ -10538,25 +10569,41 @@ err: int cmd_wait_event(int argc, char *argv[]) { + static const char *const mkbp_event_text[] = EC_MKBP_EVENT_TEXT; + static const char *const host_event_text[] = HOST_EVENT_TEXT; + int rv, i; struct ec_response_get_next_event_v1 buffer; long timeout = 5000; long event_type; char *e; + BUILD_ASSERT(ARRAY_SIZE(mkbp_event_text) == EC_MKBP_EVENT_COUNT); + BUILD_ASSERT(ARRAY_SIZE(host_event_text) == 33); /* events start at 1 */ + if (!ec_pollevent) { fprintf(stderr, "Polling for MKBP event not supported\n"); return -EINVAL; } if (argc < 2) { - fprintf(stderr, "Usage: %s <type> [<timeout>]\n", - argv[0]); + fprintf(stderr, "Usage: %s <type> [<timeout>]\n", argv[0]); + fprintf(stderr, "\n"); + fprintf(stderr, "type: MKBP event number or name.\n"); + for (int i = 0; i < ARRAY_SIZE(mkbp_event_text); i++) { + const char *name = mkbp_event_text[i]; + + if (name) { + fprintf(stderr, " %s or %d\n", name, i); + } + } + return -1; } - event_type = strtol(argv[1], &e, 0); - if ((e && *e) || event_type < 0 || event_type >= EC_MKBP_EVENT_COUNT) { + rv = find_enum_from_text(argv[1], mkbp_event_text, + ARRAY_SIZE(mkbp_event_text), &event_type); + if (rv < 0 || event_type < 0 || event_type >= EC_MKBP_EVENT_COUNT) { fprintf(stderr, "Bad event type '%s'.\n", argv[1]); return -1; } @@ -10577,6 +10624,20 @@ int cmd_wait_event(int argc, char *argv[]) printf("%02x ", buffer.data.key_matrix[i]); printf("\n"); + switch (event_type) { + case EC_MKBP_EVENT_HOST_EVENT: + printf("Host events:"); + for (int evt = 1; evt <= 32; evt++) { + if (buffer.data.host_event & EC_HOST_EVENT_MASK(evt)) { + const char *name = host_event_text[evt]; + + printf(" %s", name ? name : "UNKNOWN"); + } + } + printf("\n"); + break; + } + return 0; } @@ -10595,7 +10656,6 @@ static void cmd_cec_help(const char *cmd) " enable: Enable or disable CEC\n" " <val> is 1 to enable, 0 to disable\n", cmd, cmd, cmd, cmd); - } static int cmd_cec_write(int argc, char *argv[]) @@ -10668,8 +10728,8 @@ static int cmd_cec_read(int argc, char *argv[]) } } - rv = wait_event(EC_MKBP_EVENT_CEC_MESSAGE, &buffer, - sizeof(buffer), timeout); + rv = wait_event(EC_MKBP_EVENT_CEC_MESSAGE, &buffer, sizeof(buffer), + timeout); if (rv < 0) return rv; @@ -10717,18 +10777,15 @@ static int cmd_cec_set(int argc, char *argv[]) p.cmd = cmd; p.val = val; - return ec_command(EC_CMD_CEC_SET, - 0, &p, sizeof(p), NULL, 0); + return ec_command(EC_CMD_CEC_SET, 0, &p, sizeof(p), NULL, 0); } - static int cmd_cec_get(int argc, char *argv[]) { int rv, cmd; struct ec_params_cec_get p; struct ec_response_cec_get r; - if (argc != 3) { fprintf(stderr, "Invalid number of params\n"); cmd_cec_help(argv[0]); @@ -10742,7 +10799,6 @@ static int cmd_cec_get(int argc, char *argv[]) } p.cmd = cmd; - rv = ec_command(EC_CMD_CEC_GET, 0, &p, sizeof(p), &r, sizeof(r)); if (rv < 0) return rv; @@ -10776,150 +10832,150 @@ int cmd_cec(int argc, char *argv[]) /* NULL-terminated list of commands */ const struct command commands[] = { - {"adcread", cmd_adc_read}, - {"addentropy", cmd_add_entropy}, - {"apreset", cmd_apreset}, - {"autofanctrl", cmd_thermal_auto_fan_ctrl}, - {"backlight", cmd_lcd_backlight}, - {"basestate", cmd_basestate}, - {"battery", cmd_battery}, - {"batterycutoff", cmd_battery_cut_off}, - {"batteryparam", cmd_battery_vendor_param}, - {"boardversion", cmd_board_version}, - {"button", cmd_button}, - {"cbi", cmd_cbi}, - {"chargecurrentlimit", cmd_charge_current_limit}, - {"chargecontrol", cmd_charge_control}, - {"chargeoverride", cmd_charge_port_override}, - {"chargesplash", cmd_chargesplash}, - {"chargestate", cmd_charge_state}, - {"chipinfo", cmd_chipinfo}, - {"cmdversions", cmd_cmdversions}, - {"console", cmd_console}, - {"cec", cmd_cec}, - {"echash", cmd_ec_hash}, - {"eventclear", cmd_host_event_clear}, - {"eventclearb", cmd_host_event_clear_b}, - {"eventget", cmd_host_event_get_raw}, - {"eventgetb", cmd_host_event_get_b}, - {"eventgetscimask", cmd_host_event_get_sci_mask}, - {"eventgetsmimask", cmd_host_event_get_smi_mask}, - {"eventgetwakemask", cmd_host_event_get_wake_mask}, - {"eventsetscimask", cmd_host_event_set_sci_mask}, - {"eventsetsmimask", cmd_host_event_set_smi_mask}, - {"eventsetwakemask", cmd_host_event_set_wake_mask}, - {"extpwrlimit", cmd_ext_power_limit}, - {"fanduty", cmd_fanduty}, - {"flasherase", cmd_flash_erase}, - {"flasheraseasync", cmd_flash_erase}, - {"flashprotect", cmd_flash_protect}, - {"flashread", cmd_flash_read}, - {"flashwrite", cmd_flash_write}, - {"flashinfo", cmd_flash_info}, - {"flashspiinfo", cmd_flash_spi_info}, - {"flashpd", cmd_flash_pd}, - {"forcelidopen", cmd_force_lid_open}, - {"fpcontext", cmd_fp_context}, - {"fpencstatus", cmd_fp_enc_status}, - {"fpframe", cmd_fp_frame}, - {"fpinfo", cmd_fp_info}, - {"fpmode", cmd_fp_mode}, - {"fpseed", cmd_fp_seed}, - {"fpstats", cmd_fp_stats}, - {"fptemplate", cmd_fp_template}, - {"gpioget", cmd_gpio_get}, - {"gpioset", cmd_gpio_set}, - {"hangdetect", cmd_hang_detect}, - {"hello", cmd_hello}, - {"hibdelay", cmd_hibdelay}, - {"hostevent", cmd_hostevent}, - {"hostsleepstate", cmd_hostsleepstate}, - {"locatechip", cmd_locate_chip}, - {"i2cprotect", cmd_i2c_protect}, - {"i2cread", cmd_i2c_read}, - {"i2cspeed", cmd_i2c_speed}, - {"i2cwrite", cmd_i2c_write}, - {"i2cxfer", cmd_i2c_xfer}, - {"infopddev", cmd_pd_device_info}, - {"inventory", cmd_inventory}, - {"led", cmd_led}, - {"lightbar", cmd_lightbar}, - {"kbfactorytest", cmd_keyboard_factory_test}, - {"kbid", cmd_kbid}, - {"kbinfo", cmd_kbinfo}, - {"kbpress", cmd_kbpress}, - {"keyconfig", cmd_keyconfig}, - {"keyscan", cmd_keyscan}, - {"mkbpget", cmd_mkbp_get}, - {"mkbpwakemask", cmd_mkbp_wake_mask}, - {"motionsense", cmd_motionsense}, - {"nextevent", cmd_next_event}, - {"panicinfo", cmd_panic_info}, - {"pause_in_s5", cmd_s5}, - {"pchg", cmd_pchg}, - {"pdgetmode", cmd_pd_get_amode}, - {"pdsetmode", cmd_pd_set_amode}, - {"port80read", cmd_port80_read}, - {"pdlog", cmd_pd_log}, - {"pdcontrol", cmd_pd_control}, - {"pdchipinfo", cmd_pd_chip_info}, - {"pdwritelog", cmd_pd_write_log}, - {"powerinfo", cmd_power_info}, - {"protoinfo", cmd_proto_info}, - {"pse", cmd_pse}, - {"pstoreinfo", cmd_pstore_info}, - {"pstoreread", cmd_pstore_read}, - {"pstorewrite", cmd_pstore_write}, - {"pwmgetfanrpm", cmd_pwm_get_fan_rpm}, - {"pwmgetkblight", cmd_pwm_get_keyboard_backlight}, - {"pwmgetnumfans", cmd_pwm_get_num_fans}, - {"pwmgetduty", cmd_pwm_get_duty}, - {"pwmsetfanrpm", cmd_pwm_set_fan_rpm}, - {"pwmsetkblight", cmd_pwm_set_keyboard_backlight}, - {"pwmsetduty", cmd_pwm_set_duty}, - {"rand", cmd_rand}, - {"readtest", cmd_read_test}, - {"reboot_ec", cmd_reboot_ec}, - {"rgbkbd", cmd_rgbkbd}, - {"rollbackinfo", cmd_rollback_info}, - {"rtcget", cmd_rtc_get}, - {"rtcgetalarm", cmd_rtc_get_alarm}, - {"rtcset", cmd_rtc_set}, - {"rtcsetalarm", cmd_rtc_set_alarm}, - {"rwhashpd", cmd_rw_hash_pd}, - {"rwsig", cmd_rwsig}, - {"rwsigaction", cmd_rwsig_action_legacy}, - {"rwsigstatus", cmd_rwsig_status}, - {"sertest", cmd_serial_test}, - {"smartdischarge", cmd_smart_discharge}, - {"stress", cmd_stress_test}, - {"sysinfo", cmd_sysinfo}, - {"port80flood", cmd_port_80_flood}, - {"switches", cmd_switches}, - {"temps", cmd_temperature}, - {"tempsinfo", cmd_temp_sensor_info}, - {"test", cmd_test}, - {"thermalget", cmd_thermal_get_threshold}, - {"thermalset", cmd_thermal_set_threshold}, - {"tpselftest", cmd_tp_self_test}, - {"tpframeget", cmd_tp_frame_get}, - {"tmp006cal", cmd_tmp006cal}, - {"tmp006raw", cmd_tmp006raw}, - {"typeccontrol", cmd_typec_control}, - {"typecdiscovery", cmd_typec_discovery}, - {"typecstatus", cmd_typec_status}, - {"uptimeinfo", cmd_uptimeinfo}, - {"usbchargemode", cmd_usb_charge_set_mode}, - {"usbmux", cmd_usb_mux}, - {"usbpd", cmd_usb_pd}, - {"usbpddps", cmd_usb_pd_dps}, - {"usbpdmuxinfo", cmd_usb_pd_mux_info}, - {"usbpdpower", cmd_usb_pd_power}, - {"version", cmd_version}, - {"waitevent", cmd_wait_event}, - {"wireless", cmd_wireless}, - {"reboot_ap_on_g3", cmd_reboot_ap_on_g3}, - {NULL, NULL} + { "adcread", cmd_adc_read }, + { "addentropy", cmd_add_entropy }, + { "apreset", cmd_apreset }, + { "autofanctrl", cmd_thermal_auto_fan_ctrl }, + { "backlight", cmd_lcd_backlight }, + { "basestate", cmd_basestate }, + { "battery", cmd_battery }, + { "batterycutoff", cmd_battery_cut_off }, + { "batteryparam", cmd_battery_vendor_param }, + { "boardversion", cmd_board_version }, + { "button", cmd_button }, + { "cbi", cmd_cbi }, + { "chargecurrentlimit", cmd_charge_current_limit }, + { "chargecontrol", cmd_charge_control }, + { "chargeoverride", cmd_charge_port_override }, + { "chargesplash", cmd_chargesplash }, + { "chargestate", cmd_charge_state }, + { "chipinfo", cmd_chipinfo }, + { "cmdversions", cmd_cmdversions }, + { "console", cmd_console }, + { "cec", cmd_cec }, + { "echash", cmd_ec_hash }, + { "eventclear", cmd_host_event_clear }, + { "eventclearb", cmd_host_event_clear_b }, + { "eventget", cmd_host_event_get_raw }, + { "eventgetb", cmd_host_event_get_b }, + { "eventgetscimask", cmd_host_event_get_sci_mask }, + { "eventgetsmimask", cmd_host_event_get_smi_mask }, + { "eventgetwakemask", cmd_host_event_get_wake_mask }, + { "eventsetscimask", cmd_host_event_set_sci_mask }, + { "eventsetsmimask", cmd_host_event_set_smi_mask }, + { "eventsetwakemask", cmd_host_event_set_wake_mask }, + { "extpwrlimit", cmd_ext_power_limit }, + { "fanduty", cmd_fanduty }, + { "flasherase", cmd_flash_erase }, + { "flasheraseasync", cmd_flash_erase }, + { "flashprotect", cmd_flash_protect }, + { "flashread", cmd_flash_read }, + { "flashwrite", cmd_flash_write }, + { "flashinfo", cmd_flash_info }, + { "flashspiinfo", cmd_flash_spi_info }, + { "flashpd", cmd_flash_pd }, + { "forcelidopen", cmd_force_lid_open }, + { "fpcontext", cmd_fp_context }, + { "fpencstatus", cmd_fp_enc_status }, + { "fpframe", cmd_fp_frame }, + { "fpinfo", cmd_fp_info }, + { "fpmode", cmd_fp_mode }, + { "fpseed", cmd_fp_seed }, + { "fpstats", cmd_fp_stats }, + { "fptemplate", cmd_fp_template }, + { "gpioget", cmd_gpio_get }, + { "gpioset", cmd_gpio_set }, + { "hangdetect", cmd_hang_detect }, + { "hello", cmd_hello }, + { "hibdelay", cmd_hibdelay }, + { "hostevent", cmd_hostevent }, + { "hostsleepstate", cmd_hostsleepstate }, + { "locatechip", cmd_locate_chip }, + { "i2cprotect", cmd_i2c_protect }, + { "i2cread", cmd_i2c_read }, + { "i2cspeed", cmd_i2c_speed }, + { "i2cwrite", cmd_i2c_write }, + { "i2cxfer", cmd_i2c_xfer }, + { "infopddev", cmd_pd_device_info }, + { "inventory", cmd_inventory }, + { "led", cmd_led }, + { "lightbar", cmd_lightbar }, + { "kbfactorytest", cmd_keyboard_factory_test }, + { "kbid", cmd_kbid }, + { "kbinfo", cmd_kbinfo }, + { "kbpress", cmd_kbpress }, + { "keyconfig", cmd_keyconfig }, + { "keyscan", cmd_keyscan }, + { "mkbpget", cmd_mkbp_get }, + { "mkbpwakemask", cmd_mkbp_wake_mask }, + { "motionsense", cmd_motionsense }, + { "nextevent", cmd_next_event }, + { "panicinfo", cmd_panic_info }, + { "pause_in_s5", cmd_s5 }, + { "pchg", cmd_pchg }, + { "pdgetmode", cmd_pd_get_amode }, + { "pdsetmode", cmd_pd_set_amode }, + { "port80read", cmd_port80_read }, + { "pdlog", cmd_pd_log }, + { "pdcontrol", cmd_pd_control }, + { "pdchipinfo", cmd_pd_chip_info }, + { "pdwritelog", cmd_pd_write_log }, + { "powerinfo", cmd_power_info }, + { "protoinfo", cmd_proto_info }, + { "pse", cmd_pse }, + { "pstoreinfo", cmd_pstore_info }, + { "pstoreread", cmd_pstore_read }, + { "pstorewrite", cmd_pstore_write }, + { "pwmgetfanrpm", cmd_pwm_get_fan_rpm }, + { "pwmgetkblight", cmd_pwm_get_keyboard_backlight }, + { "pwmgetnumfans", cmd_pwm_get_num_fans }, + { "pwmgetduty", cmd_pwm_get_duty }, + { "pwmsetfanrpm", cmd_pwm_set_fan_rpm }, + { "pwmsetkblight", cmd_pwm_set_keyboard_backlight }, + { "pwmsetduty", cmd_pwm_set_duty }, + { "rand", cmd_rand }, + { "readtest", cmd_read_test }, + { "reboot_ec", cmd_reboot_ec }, + { "rgbkbd", cmd_rgbkbd }, + { "rollbackinfo", cmd_rollback_info }, + { "rtcget", cmd_rtc_get }, + { "rtcgetalarm", cmd_rtc_get_alarm }, + { "rtcset", cmd_rtc_set }, + { "rtcsetalarm", cmd_rtc_set_alarm }, + { "rwhashpd", cmd_rw_hash_pd }, + { "rwsig", cmd_rwsig }, + { "rwsigaction", cmd_rwsig_action_legacy }, + { "rwsigstatus", cmd_rwsig_status }, + { "sertest", cmd_serial_test }, + { "smartdischarge", cmd_smart_discharge }, + { "stress", cmd_stress_test }, + { "sysinfo", cmd_sysinfo }, + { "port80flood", cmd_port_80_flood }, + { "switches", cmd_switches }, + { "temps", cmd_temperature }, + { "tempsinfo", cmd_temp_sensor_info }, + { "test", cmd_test }, + { "thermalget", cmd_thermal_get_threshold }, + { "thermalset", cmd_thermal_set_threshold }, + { "tpselftest", cmd_tp_self_test }, + { "tpframeget", cmd_tp_frame_get }, + { "tmp006cal", cmd_tmp006cal }, + { "tmp006raw", cmd_tmp006raw }, + { "typeccontrol", cmd_typec_control }, + { "typecdiscovery", cmd_typec_discovery }, + { "typecstatus", cmd_typec_status }, + { "uptimeinfo", cmd_uptimeinfo }, + { "usbchargemode", cmd_usb_charge_set_mode }, + { "usbmux", cmd_usb_mux }, + { "usbpd", cmd_usb_pd }, + { "usbpddps", cmd_usb_pd_dps }, + { "usbpdmuxinfo", cmd_usb_pd_mux_info }, + { "usbpdpower", cmd_usb_pd_power }, + { "version", cmd_version }, + { "waitevent", cmd_wait_event }, + { "wireless", cmd_wireless }, + { "reboot_ap_on_g3", cmd_reboot_ap_on_g3 }, + { NULL, NULL } }; int main(int argc, char *argv[]) @@ -10980,8 +11036,8 @@ int main(int argc, char *argv[]) break; case OPT_I2C_BUS: i2c_bus = strtoull(optarg, &e, 0); - if (*optarg == '\0' || (e && *e != '\0') - || i2c_bus < 0) { + if (*optarg == '\0' || (e && *e != '\0') || + i2c_bus < 0) { fprintf(stderr, "Invalid --i2c_bus\n"); parse_error = 1; } @@ -10992,9 +11048,10 @@ int main(int argc, char *argv[]) } } - if (i2c_bus != -1) { + if (i2c_bus != -1) { if (!(interfaces & COMM_I2C)) { - fprintf(stderr, "--i2c_bus is specified, but --interface is set to something other than I2C\n"); + fprintf(stderr, + "--i2c_bus is specified, but --interface is set to something other than I2C\n"); parse_error = 1; } else { interfaces = COMM_I2C; @@ -11030,7 +11087,10 @@ int main(int argc, char *argv[]) /* Prefer /dev method, which supports built-in mutex */ if (!(interfaces & COMM_DEV) || comm_init_dev(device_name)) { /* If dev is excluded or isn't supported, find alternative */ - if (acquire_gec_lock(GEC_LOCK_TIMEOUT_SECS) < 0) { + + /* Lock is not needed for COMM_USB */ + if (!(interfaces & COMM_USB) && + acquire_gec_lock(GEC_LOCK_TIMEOUT_SECS) < 0) { fprintf(stderr, "Could not acquire GEC lock.\n"); exit(1); } diff --git a/util/ectool.h b/util/ectool.h index c76e1652cc..3b398af273 100644 --- a/util/ectool.h +++ b/util/ectool.h @@ -1,4 +1,4 @@ -/* Copyright 2012 The Chromium OS Authors. All rights reserved. +/* Copyright 2012 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ diff --git a/util/ectool_i2c.c b/util/ectool_i2c.c index 97e47e6e85..efe2b723a2 100644 --- a/util/ectool_i2c.c +++ b/util/ectool_i2c.c @@ -1,4 +1,4 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. +/* Copyright 2021 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -20,8 +20,7 @@ int cmd_i2c_protect(int argc, char *argv[]) int rv; if (argc != 2 && (argc != 3 || strcmp(argv[2], "status"))) { - fprintf(stderr, "Usage: %s <port> [status]\n", - argv[0]); + fprintf(stderr, "Usage: %s <port> [status]\n", argv[0]); return -1; } @@ -56,9 +55,8 @@ int cmd_i2c_protect(int argc, char *argv[]) return 0; } -static int do_i2c_xfer(unsigned int port, unsigned int addr, - uint8_t *write_buf, int write_len, - uint8_t **read_buf, int read_len) +static int do_i2c_xfer(unsigned int port, unsigned int addr, uint8_t *write_buf, + int write_len, uint8_t **read_buf, int read_len) { struct ec_params_i2c_passthru *p = (struct ec_params_i2c_passthru *)ec_outbuf; @@ -96,8 +94,8 @@ static int do_i2c_xfer(unsigned int port, unsigned int addr, msg->len = read_len; } - rv = ec_command(EC_CMD_I2C_PASSTHRU, 0, p, size + write_len, - r, sizeof(*r) + read_len); + rv = ec_command(EC_CMD_I2C_PASSTHRU, 0, p, size + write_len, r, + sizeof(*r) + read_len); if (rv < 0) return rv; @@ -132,9 +130,7 @@ static void cmd_i2c_help(void) " <offset> offset to read from or write to\n" " <data> data to write\n" " <read_count> number of bytes to read\n" - " [bytes ...] data to write\n" - ); - + " [bytes ...] data to write\n"); } int cmd_i2c_read(int argc, char *argv[]) @@ -184,8 +180,8 @@ int cmd_i2c_read(int argc, char *argv[]) if (rv < 0) return rv; - printf("Read from I2C port %d at 0x%x offset 0x%x = 0x%x\n", - port, addr8, write_buf[0], *(uint16_t *)read_buf); + printf("Read from I2C port %d at 0x%x offset 0x%x = 0x%x\n", port, + addr8, write_buf[0], *(uint16_t *)read_buf); return 0; } @@ -324,7 +320,7 @@ int cmd_i2c_xfer(int argc, char *argv[]) static int i2c_get(int port) { - struct ec_params_i2c_control p; + struct ec_params_i2c_control p; struct ec_response_i2c_control r; uint16_t speed_khz; int rv; @@ -348,7 +344,7 @@ static int i2c_get(int port) static int i2c_set(int port, int new_speed_khz) { - struct ec_params_i2c_control p; + struct ec_params_i2c_control p; struct ec_response_i2c_control r; uint16_t old_speed_khz; int rv; @@ -374,8 +370,7 @@ static int i2c_set(int port, int new_speed_khz) printf("Port %d speed set to %d kHz\n", port, new_speed_khz); } else { printf("Port %d speed changed from %u kHz to %d kHz\n", port, - old_speed_khz, - new_speed_khz); + old_speed_khz, new_speed_khz); } return 0; @@ -403,7 +398,7 @@ int cmd_i2c_speed(int argc, char *argv[]) speed = strtol(argv[2], &e, 0); if (e && *e) { fprintf(stderr, "Bad speed. " - "Typical speeds are one of {100,400,1000}.\n"); + "Typical speeds are one of {100,400,1000}.\n"); return -1; } diff --git a/util/ectool_keyscan.c b/util/ectool_keyscan.c index 4f5393157d..796e197a9a 100644 --- a/util/ectool_keyscan.c +++ b/util/ectool_keyscan.c @@ -1,4 +1,4 @@ -/* Copyright 2012 The Chromium OS Authors. All rights reserved. +/* Copyright 2012 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -18,39 +18,39 @@ enum { /* Alloc this many more scans when needed */ - KEYSCAN_ALLOC_STEP = 64, - KEYSCAN_MAX_TESTS = 10, /* Maximum number of tests supported */ - KEYSCAN_MAX_INPUT_LEN = 20, /* Maximum characters we can receive */ + KEYSCAN_ALLOC_STEP = 64, + KEYSCAN_MAX_TESTS = 10, /* Maximum number of tests supported */ + KEYSCAN_MAX_INPUT_LEN = 20, /* Maximum characters we can receive */ }; /* A single entry of the key matrix */ struct matrix_entry { - int row; /* key matrix row */ - int col; /* key matrix column */ - int keycode; /* corresponding linux key code */ + int row; /* key matrix row */ + int col; /* key matrix column */ + int keycode; /* corresponding linux key code */ }; struct keyscan_test_item { - uint32_t beat; /* Beat number */ - uint8_t scan[KEYBOARD_COLS_MAX]; /* Scan data */ + uint32_t beat; /* Beat number */ + uint8_t scan[KEYBOARD_COLS_MAX]; /* Scan data */ }; /* A single test, consisting of a list of key scans and expected ascii input */ struct keyscan_test { - char *name; /* name of test */ - char *expect; /* resulting input we expect to see */ - int item_count; /* number of items in data */ - int item_alloced; /* number of items alloced in data */ - struct keyscan_test_item *items; /* key data for EC */ + char *name; /* name of test */ + char *expect; /* resulting input we expect to see */ + int item_count; /* number of items in data */ + int item_alloced; /* number of items alloced in data */ + struct keyscan_test_item *items; /* key data for EC */ }; /* A list of tests that we can run */ struct keyscan_info { - unsigned int beat_us; /* length of each beat in microseconds */ - struct keyscan_test tests[KEYSCAN_MAX_TESTS]; /* the tests */ - int test_count; /* number of tests */ - struct matrix_entry *matrix; /* the key matrix info */ - int matrix_count; /* number of keys in matrix */ + unsigned int beat_us; /* length of each beat in microseconds */ + struct keyscan_test tests[KEYSCAN_MAX_TESTS]; /* the tests */ + int test_count; /* number of tests */ + struct matrix_entry *matrix; /* the key matrix info */ + int matrix_count; /* number of keys in matrix */ }; /** @@ -125,18 +125,18 @@ static int keyscan_read_fdt_matrix(struct keyscan_info *keyscan, * when we see a space in a key sequence file. */ static const unsigned char kbd_plain_xlate[] = { - 0xff, 0x1b, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '-', '=', '\b', '\t', /* 0x00 - 0x0f */ - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '[', ']', '\r', 0xff, 'a', 's', /* 0x10 - 0x1f */ - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', - '\'', '`', 0xff, '\\', 'z', 'x', 'c', 'v', /* 0x20 - 0x2f */ - 'b', 'n', 'm', ',' , '.', '/', 0xff, 0xff, 0xff, - 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x30 - 0x3f */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '7', - '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */ - '2', '3', '0', '.', 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x50 - 0x5F */ + 0xff, 0x1b, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', '\b', '\t', /* 0x00 - 0x0f */ + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', '\r', 0xff, 'a', 's', /* 0x10 - 0x1f */ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + '\'', '`', 0xff, '\\', 'z', 'x', 'c', 'v', /* 0x20 - 0x2f */ + 'b', 'n', 'm', ',', '.', '/', 0xff, 0xff, + 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x30 - 0x3f */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '7', + '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */ + '2', '3', '0', '.', 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x50 - 0x5F */ '\r', 0xff, 0xff, '\0' }; @@ -216,7 +216,7 @@ static int keyscan_add_to_scan(struct keyscan_info *keyscan, char **keysp, /* Look up keycode in matrix */ for (i = 0, matrix = keyscan->matrix; i < keyscan->matrix_count; - i++, matrix++) { + i++, matrix++) { if (matrix->keycode == keycode) { #ifdef DEBUG printf("%d: %d,%d\n", matrix->keycode, matrix->row, @@ -289,15 +289,15 @@ static int keyscan_process_keys(struct keyscan_info *keyscan, int linenum, keys++; while (*keys) { if (keyscan_add_to_scan(keyscan, &keys, item->scan)) { - fprintf(stderr, "Line %d: Cannot parse" - " key input '%s'\n", linenum, - keys); + fprintf(stderr, + "Line %d: Cannot parse" + " key input '%s'\n", + linenum, keys); return -1; } } } else if (*keys) { - fprintf(stderr, "Line %d: Need space after beat\n", - linenum); + fprintf(stderr, "Line %d: Need space after beat\n", linenum); return -1; } test->item_count++; @@ -307,10 +307,10 @@ static int keyscan_process_keys(struct keyscan_info *keyscan, int linenum, /* These are the commands we understand in a key sequence file */ enum keyscan_cmd { - KEYSCAN_CMD_TEST, /* start a new test */ - KEYSCAN_CMD_ENDTEST, /* end a test */ - KEYSCAN_CMD_SEQ, /* add a keyscan to a test sequence */ - KEYSCAN_CMD_EXPECT, /* indicate what input is expected */ + KEYSCAN_CMD_TEST, /* start a new test */ + KEYSCAN_CMD_ENDTEST, /* end a test */ + KEYSCAN_CMD_SEQ, /* add a keyscan to a test sequence */ + KEYSCAN_CMD_EXPECT, /* indicate what input is expected */ KEYSCAN_CMD_COUNT }; @@ -388,7 +388,7 @@ static int keyscan_process_file(FILE *f, struct keyscan_info *keyscan) /* Start a new test */ if (keyscan->test_count == KEYSCAN_MAX_TESTS) { fprintf(stderr, "KEYSCAN_MAX_TESTS " - "exceeded\n"); + "exceeded\n"); return -1; } cur_test = &keyscan->tests[keyscan->test_count]; @@ -401,8 +401,10 @@ static int keyscan_process_file(FILE *f, struct keyscan_info *keyscan) case KEYSCAN_CMD_EXPECT: /* Get expect string */ if (!cur_test) { - fprintf(stderr, "Line %d: expect should be " - "inside test\n", linenum); + fprintf(stderr, + "Line %d: expect should be " + "inside test\n", + linenum); return -1; } cur_test->expect = strdup(args); @@ -418,9 +420,11 @@ static int keyscan_process_file(FILE *f, struct keyscan_info *keyscan) break; case KEYSCAN_CMD_SEQ: if (keyscan_process_keys(keyscan, linenum, cur_test, - args)) { - fprintf(stderr, "Line %d: Cannot parse key " - "input '%s'\n", linenum, args); + args)) { + fprintf(stderr, + "Line %d: Cannot parse key " + "input '%s'\n", + linenum, args); return -1; } break; @@ -519,8 +523,8 @@ static int keyscan_send_sequence(struct keyscan_info *keyscan, fprintf(stderr, "Out of memory for message\n"); return -1; } - for (upto = rv = 0, item = test->items; rv >= 0 && - upto < test->item_count; upto++, item++) { + for (upto = rv = 0, item = test->items; + rv >= 0 && upto < test->item_count; upto++, item++) { req->cmd = EC_KEYSCAN_SEQ_ADD; req->add.time_us = item->beat * keyscan->beat_us; memcpy(req->add.scan, item->scan, sizeof(item->scan)); @@ -553,8 +557,8 @@ static int run_test(struct keyscan_info *keyscan, struct keyscan_test *test) /* First clear the sequence */ ctrl.cmd = EC_KEYSCAN_SEQ_CLEAR; - rv = ec_command(EC_CMD_KEYSCAN_SEQ_CTRL, 0, &ctrl, sizeof(ctrl), - NULL, 0); + rv = ec_command(EC_CMD_KEYSCAN_SEQ_CTRL, 0, &ctrl, sizeof(ctrl), NULL, + 0); if (rv < 0) return rv; @@ -565,13 +569,13 @@ static int run_test(struct keyscan_info *keyscan, struct keyscan_test *test) /* Start it */ set_to_raw(fd, 1); ctrl.cmd = EC_KEYSCAN_SEQ_START; - rv = ec_command(EC_CMD_KEYSCAN_SEQ_CTRL, 0, &ctrl, sizeof(ctrl), - NULL, 0); + rv = ec_command(EC_CMD_KEYSCAN_SEQ_CTRL, 0, &ctrl, sizeof(ctrl), NULL, + 0); if (rv < 0) return rv; /* Work out how long we need to wait */ - wait_us = 100 * 1000; /* Wait 100ms to at least */ + wait_us = 100 * 1000; /* Wait 100ms to at least */ if (test->item_count) { struct keyscan_test_item *ksi; @@ -593,8 +597,8 @@ static int run_test(struct keyscan_info *keyscan, struct keyscan_test *test) ctrl.cmd = EC_KEYSCAN_SEQ_COLLECT; ctrl.collect.start_item = 0; ctrl.collect.num_items = test->item_count; - rv = ec_command(EC_CMD_KEYSCAN_SEQ_CTRL, 0, &ctrl, sizeof(ctrl), - resp, size); + rv = ec_command(EC_CMD_KEYSCAN_SEQ_CTRL, 0, &ctrl, sizeof(ctrl), resp, + size); if (rv < 0) return rv; diff --git a/util/env_changed.sh b/util/env_changed.sh index 5bab64760d..eadc94ae01 100755 --- a/util/env_changed.sh +++ b/util/env_changed.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2019 The Chromium OS Authors. All rights reserved. +# Copyright 2019 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/util/export_taskinfo.c b/util/export_taskinfo.c index 4c09bafb90..af40ef8de6 100644 --- a/util/export_taskinfo.c +++ b/util/export_taskinfo.c @@ -1,4 +1,4 @@ -/* Copyright 2017 The Chromium OS Authors. All rights reserved. +/* Copyright 2017 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -25,14 +25,13 @@ struct taskinfo { uint32_t stack_size; }; -#define TASK(n, r, d, s, ...) { \ - .name = #n, \ - .routine = #r, \ - .stack_size = s, \ -}, -static const struct taskinfo taskinfos[] = { - CONFIG_TASK_LIST -}; +#define TASK(n, r, d, s, ...) \ + { \ + .name = #n, \ + .routine = #r, \ + .stack_size = s, \ + }, +static const struct taskinfo taskinfos[] = { CONFIG_TASK_LIST }; #undef TASK uint32_t GET_TASKINFOS_FUNC(const struct taskinfo **infos) diff --git a/util/flash_ec b/util/flash_ec index 7cb4ebcda8..8557b637e5 100755 --- a/util/flash_ec +++ b/util/flash_ec @@ -1,11 +1,11 @@ #!/bin/bash -# Copyright 2014 The Chromium OS Authors. All rights reserved. +# Copyright 2014 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. SCRIPT="$(readlink -f "$0")" -SCRIPT_DIR="$(dirname "$SCRIPT")" +SCRIPT_DIR="$(dirname "${SCRIPT}")" EC_DIR="$(readlink -f "${SCRIPT_DIR}/..")" if [[ "$(basename "${EC_DIR}")" != "ec" ]]; then @@ -147,9 +147,9 @@ BITBANG_RATE="57600" # Could be overwritten by a command line option. # Flags DEFINE_integer bitbang_rate "${BITBANG_RATE}" \ - "UART baud rate to use when bit bang programming, "\ + "UART baud rate to use when bit bang programming, " \ "standard UART rates from 9600 to 57600 are supported." -DEFINE_string board "${DEFAULT_BOARD}" \ +DEFINE_string board "" \ "The board to run debugger on." DEFINE_string chip "" \ "The chip to run debugger on." @@ -223,15 +223,15 @@ function print_or_run() { function dut_control() { local DUT_CTRL_CML=( "${DUT_CONTROL_CMD[@]}" ) - for p in $@ ; do + for p in "$@" ; do # Only add the prefix if the arg is a control name. if [[ ${p} != -* ]] ; then p="${DUT_CTRL_PREFIX}${p}" fi - DUT_CTRL_CML+=( "$p" ) + DUT_CTRL_CML+=( "${p}" ) done - if [ "${FLAGS_verbose}" = ${FLAGS_TRUE} ]; then + if [ "${FLAGS_verbose}" = "${FLAGS_TRUE}" ]; then echo "${DUT_CTRL_CML[*]}" 1>&2 fi @@ -244,7 +244,7 @@ function dut_control_or_die { function dut_control_get() { if [ $# -gt 1 ]; then - error "${FUNCNAME[0]} failed: more than one argument: $@" + error "${FUNCNAME[0]} failed: more than one argument: $*" return 1 fi @@ -266,7 +266,11 @@ function dut_control_get_or_die { die "command exited $? (non-zero): dut-control --value_only $*" } -: ${BOARD:=${FLAGS_board}} +: "${BOARD:=${FLAGS_board}}" + +if [ "${BOARD}" == "" ]; then + die "Must specify board." +fi in_array() { local n=$# @@ -282,48 +286,48 @@ in_array() { declare -a SUPPORTED_CHIPS -if $(in_array "${BOARDS_STM32[@]}" "${BOARD}"); then +if in_array "${BOARDS_STM32[@]}" "${BOARD}"; then SUPPORTED_CHIPS+=("stm32") fi -if $(in_array "${BOARDS_STM32_DFU[@]}" "${BOARD}"); then +if in_array "${BOARDS_STM32_DFU[@]}" "${BOARD}"; then SUPPORTED_CHIPS+=("stm32_dfu") fi -if $(in_array "${BOARDS_NPCX_5M5G_JTAG[@]}" "${BOARD}"); then +if in_array "${BOARDS_NPCX_5M5G_JTAG[@]}" "${BOARD}"; then SUPPORTED_CHIPS+=("npcx_5m5g_jtag") fi -if $(in_array "${BOARDS_NPCX_5M6G_JTAG[@]}" "${BOARD}"); then +if in_array "${BOARDS_NPCX_5M6G_JTAG[@]}" "${BOARD}"; then SUPPORTED_CHIPS+=("npcx_5m6g_jtag") fi -if $(in_array "${BOARDS_NPCX_7M6X_JTAG[@]}" "${BOARD}"); then +if in_array "${BOARDS_NPCX_7M6X_JTAG[@]}" "${BOARD}"; then SUPPORTED_CHIPS+=("npcx_7m6x_jtag") fi -if $(in_array "${BOARDS_NPCX_7M7X_JTAG[@]}" "${BOARD}"); then +if in_array "${BOARDS_NPCX_7M7X_JTAG[@]}" "${BOARD}"; then SUPPORTED_CHIPS+=("npcx_7m7x_jtag") fi -if $(in_array "${BOARDS_NPCX_SPI[@]}" "${BOARD}"); then +if in_array "${BOARDS_NPCX_SPI[@]}" "${BOARD}"; then SUPPORTED_CHIPS+=("npcx_spi") fi -if $(in_array "${BOARDS_NPCX_INT_SPI[@]}" "${BOARD}"); then +if in_array "${BOARDS_NPCX_INT_SPI[@]}" "${BOARD}"; then SUPPORTED_CHIPS+=("npcx_int_spi") fi -if $(in_array "${BOARDS_IT83XX[@]}" "${BOARD}"); then +if in_array "${BOARDS_IT83XX[@]}" "${BOARD}"; then SUPPORTED_CHIPS+=("it83xx") fi -if $(in_array "${BOARDS_IT83XX_SPI_PROGRAMMING[@]}" "${BOARD}"); then +if in_array "${BOARDS_IT83XX_SPI_PROGRAMMING[@]}" "${BOARD}"; then SUPPORTED_CHIPS+=("ite_spi") fi if [[ ${#SUPPORTED_CHIPS[@]} -eq 0 && -n "${FLAGS_chip}" ]]; then - SUPPORTED_CHIPS+="${FLAGS_chip}" + SUPPORTED_CHIPS+=("${FLAGS_chip}") fi if [[ ${#SUPPORTED_CHIPS[@]} -eq 0 ]]; then @@ -345,10 +349,10 @@ if [[ ${#SUPPORTED_CHIPS[@]} -eq 0 ]]; then elif [[ ${#SUPPORTED_CHIPS[@]} -eq 1 ]]; then CHIP="${SUPPORTED_CHIPS[0]}" elif [ -n "${FLAGS_chip}" ]; then - if $(in_array "${SUPPORTED_CHIPS[@]}" "${FLAGS_chip}"); then + if in_array "${SUPPORTED_CHIPS[@]}" "${FLAGS_chip}"; then CHIP="${FLAGS_chip}" else - die "board ${BOARD} only supports (${SUPPORTED_CHIPS[@]})," \ + die "board ${BOARD} only supports (${SUPPORTED_CHIPS[*]})," \ "not ${FLAGS_chip}." fi else @@ -356,10 +360,10 @@ else # file, instead of having multiple board-to-chip mapping info in this # script. Please refer to crrev.com/c/1496460 for example. die "board ${BOARD} supports multiple chips" \ - "(${FILTERED_CHIPS[@]}). Use --chip= to choose one." + "(${SUPPORTED_CHIPS[*]}). Use --chip= to choose one." fi -if [ -n "${FLAGS_chip}" -a "${CHIP}" != "${FLAGS_chip}" ]; then +if [ -n "${FLAGS_chip}" ] && [ "${CHIP}" != "${FLAGS_chip}" ]; then die "board ${BOARD} doesn't use chip ${FLAGS_chip}" fi @@ -379,7 +383,7 @@ esac case "${CHIP}" in "stm32"|"npcx_spi"|"npcx_int_spi"|"it83xx"|"npcx_uut"|"ite_spi"| \ - "ite_spi_ccd_i2c") + "ite_spi_ccd_i2c"|"it8xxx2") ;; *) if [[ -n "${FLAGS_read}" ]]; then @@ -388,7 +392,7 @@ case "${CHIP}" in # If verification is not supported, then show a warning message. # Keep it running however. - if [[ "${FLAGS_verify}" == ${FLAGS_TRUE} ]]; then + if [[ "${FLAGS_verify}" == "${FLAGS_TRUE}" ]]; then warn "Ignoring '--verify'" \ "since read is not supported on ${CHIP}." fi @@ -399,6 +403,9 @@ SERVO_TYPE="$(dut_control_get servo_type || :)" if [[ "${SERVO_TYPE}" =~ ^servo_v4(p1)?_with_.*$ ]]; then ACTIVE_DEVICE="$(dut_control_get active_dut_controller)" + if [[ ${ACTIVE_DEVICE} == neither ]]; then + die "Could not determine servo V4 active device" + fi else ACTIVE_DEVICE="${SERVO_TYPE}" fi @@ -464,6 +471,15 @@ servo_usbpd_hard_reset() { servo_fpmcu_hard_reset() { dut_control fpmcu_reset:on sleep:0.5 fpmcu_reset:off + + # b/177331210: Workaround for an outstanding issue that prevents + # flashing dartmonkey with a servo_micro. The exact root cause is still + # unknown, but it's been observed that repeating the FPMCU reset + # sequence twice makes the operation succeed. + if [[ "${BOARD}" =~ "dartmonkey" ]] ; then + warn "Workaround for dartmonkey + servo_micro: repeat FPMCU reset sequence" + dut_control fpmcu_reset:on sleep:0.5 fpmcu_reset:off + fi } servo_sh_hard_reset() { @@ -481,7 +497,7 @@ ec_reset() { fi if [[ -n "${stype}" ]]; then - eval ${stype}_${MCU}_hard_reset + eval "${stype}_${MCU}_hard_reset" fi } @@ -497,7 +513,7 @@ ccd_ec_boot0() { dut_control cold_reset:on fi - dut_control "ccd_ec_boot_mode_${boot_mode}":"${on_value}" + dut_control "ccd_ec_boot_mode_${boot_mode}:${on_value}" } servo_micro_ec_boot0() { @@ -505,7 +521,7 @@ servo_micro_ec_boot0() { # circuit that is controlled by the EC_FLASH_ODL pin. For those boards, # we want to continue to drive the EC_FLASH_ODL if they do not have the # servo micro rework listed below. - if [[ "${FLAGS_servo_micro_uart_rx_rework}" == ${FLAGS_TRUE} ]]; then + if [[ "${FLAGS_servo_micro_uart_rx_rework}" == "${FLAGS_TRUE}" ]]; then info "Servo micro $2 mode: $1 (using rx_rework)" # Setting the test point allows the EC_TX_SERVO_RX line @@ -515,28 +531,28 @@ servo_micro_ec_boot0() { # HW Rework (b/143163043#comment3): # - Disconnect U45.1 from ground # - Connected U45.1 to TP1 pad - dut_control tp1:$1 - dut_control servo_micro_ec_boot_mode_$2:$1 + dut_control "tp1:$1" + dut_control "servo_micro_ec_boot_mode_$2:$1" else info "Servo micro $2 mode: $1 (using FW_UP_L)" - dut_control ec_boot_mode:$1 + dut_control "ec_boot_mode:$1" fi } servo_ec_boot0() { - dut_control ec_boot_mode:$1 + dut_control "ec_boot_mode:$1" } c2d2_ec_boot0() { - dut_control ec_boot_mode_uut:$1 + dut_control "ec_boot_mode_uut:$1" } servo_usbpd_boot0() { - dut_control usbpd_boot_mode:$1 + dut_control "usbpd_boot_mode:$1" } servo_fpmcu_boot0() { - dut_control fpmcu_boot_mode:"$1" + dut_control "fpmcu_boot_mode:$1" } servo_micro_fpmcu_boot0() { @@ -548,13 +564,13 @@ servo_micro_usbpd_boot0() { } servo_sh_boot0() { - dut_control sh_boot_mode:$1 + dut_control "sh_boot_mode:$1" } ec_switch_boot0() { local on_value=$1 # Enable programming GPIOs - if $(in_array "${BOARDS_STM32_PROG_EN[@]}" "${BOARD}"); then + if in_array "${BOARDS_STM32_PROG_EN[@]}" "${BOARD}"; then servo_save_add "prog_en" dut_control prog_en:yes @@ -568,15 +584,15 @@ ec_switch_boot0() { else stype=${SERVO_TYPE} fi - eval ${stype}_${MCU}_boot0 "${on_value}" $2 + eval "${stype}_${MCU}_boot0" "${on_value}" "$2" } ec_enable_boot0() { - ec_switch_boot0 "on" $1 + ec_switch_boot0 "on" "$1" } ec_disable_boot0() { - ec_switch_boot0 "off" $1 + ec_switch_boot0 "off" "$1" } # Returns 0 on success (if on beaglebone) @@ -593,9 +609,9 @@ on_raiden() { return 0 fi if [ -z "${BOARD}" ]; then - [ "${FLAGS_raiden}" = ${FLAGS_TRUE} ] && return 0 || return 1 + [ "${FLAGS_raiden}" = "${FLAGS_TRUE}" ] && return 0 || return 1 fi - if [ "${FLAGS_raiden}" = ${FLAGS_TRUE} ]; then + if [ "${FLAGS_raiden}" = "${FLAGS_TRUE}" ]; then if in_array "${BOARDS_RAIDEN[@]}" "${BOARD}"; then return 0 fi @@ -646,7 +662,7 @@ cleanup() { servo_restore - if [ "${CHIP}" = "stm32" -o "${CHIP}" = "npcx_uut" ]; then + if [ "${CHIP}" = "stm32" ] || [ "${CHIP}" = "npcx_uut" ]; then dut_control "${MCU}"_boot_mode:off fi @@ -665,25 +681,23 @@ trap cleanup EXIT # the RO image includes a header. # NPCX images use "build-ro/zephyr/zephyr.npcx.bin" # ITE images use "build-ro/zephyr/zephyr.bin" -if [ "${FLAGS_ro}" = ${FLAGS_TRUE} ] && [ "${FLAGS_zephyr}" = ${FLAGS_TRUE} ] +if [ "${FLAGS_ro}" = "${FLAGS_TRUE}" ] && [ "${FLAGS_zephyr}" = "${FLAGS_TRUE}" ] then die "The --ro flag is not supported with the --zephyr flag" fi # Possible default EC images -if [ "${FLAGS_ro}" = ${FLAGS_TRUE} ] ; then +if [ "${FLAGS_ro}" = "${FLAGS_TRUE}" ] ; then EC_FILE=ec.RO.flat -elif [ "${FLAGS_zephyr}" = ${FLAGS_TRUE} ] ; then - EC_FILE=zephyr.bin else EC_FILE=ec.bin fi LOCAL_BUILD= if [[ -n "${EC_DIR}" ]]; then - if [ "${FLAGS_ro}" = ${FLAGS_TRUE} ] ; then + if [ "${FLAGS_ro}" = "${FLAGS_TRUE}" ] ; then LOCAL_BUILD="${EC_DIR}/build/${BOARD}/RO/${EC_FILE}" - elif [ "${FLAGS_zephyr}" = ${FLAGS_TRUE} ] ; then + elif [ "${FLAGS_zephyr}" = "${FLAGS_TRUE}" ] ; then LOCAL_BUILD="${EC_DIR}/build/zephyr/${BOARD}/output/${EC_FILE}" else LOCAL_BUILD="${EC_DIR}/build/${BOARD}/${EC_FILE}" @@ -697,14 +711,15 @@ BASEBOARD= # setting BASEBOARD set +e if [[ -n "${EC_DIR}" ]]; then - BASEBOARD=$(make --quiet -C ${EC_DIR} BOARD=${BOARD} print-baseboard \ + BASEBOARD=$(make --quiet -C "${EC_DIR}" BOARD="${BOARD}" print-baseboard \ 2>/dev/null) elif [[ -d "${HOME}/trunk/src/platform/ec" ]]; then - BASEBOARD=$(make --quiet -C ${HOME}/trunk/src/platform/ec \ - BOARD=${BOARD} print-baseboard 2>/dev/null) + BASEBOARD=$(make --quiet -C "${HOME}"/trunk/src/platform/ec \ + BOARD="${BOARD}" print-baseboard 2>/dev/null) else info "Could not find ec build folder to calculate baseboard." fi +# shellcheck disable=SC2181 if [ $? -ne 0 ]; then info "EC build system didn't recognize ${BOARD}. Assuming no baseboard." fi @@ -763,20 +778,9 @@ function servo_ec_uart() { if [[ -z "${PTY}" ]]; then die "${SERVOD_FAIL}" fi - echo $PTY + echo "${PTY}" } -# Not every control is supported on every servo type. Therefore, define which -# controls are supported by each servo type. -servo_v2_VARS=( "cold_reset" ) -servo_micro_VARS=( "cold_reset" ) -servo_v4_with_ccd_cr50_VARS=( "cold_reset" ) -c2d2_VARS=( "cold_reset" ) - -# Some servo boards use the same controls. -servo_v3_VARS=( "${servo_v2_VARS[@]}" ) -servo_v4_with_servo_micro_VARS=( "${servo_micro_VARS[@]}" ) - declare -a save ####################################### @@ -789,12 +793,12 @@ function servo_save_add() { local CTRL_RESULT= case $# in 1) CTRL_RESULT="$( "${DUT_CONTROL_CMD[@]}" \ - "${DUT_CTRL_PREFIX}$@" )" + "${DUT_CTRL_PREFIX}$*" )" if [[ -n "${CTRL_RESULT}" ]]; then # Don't save the control with the prefix, because # dut_control will add the prefix again when we restore # the settings. - save=( "${CTRL_RESULT#$DUT_CTRL_PREFIX}" "${save[@]}" ) + save=( "${CTRL_RESULT#${DUT_CTRL_PREFIX}}" "${save[@]}" ) fi ;; 2) save=( "$1:$2" "${save[@]}" ) @@ -805,10 +809,7 @@ function servo_save_add() { } function servo_save() { - local SERVO_VARS_NAME="${SERVO_TYPE}_VARS[@]" - for ctrl in "${!SERVO_VARS_NAME}"; do - servo_save_add "${ctrl}" - done + servo_save_add "cold_reset" if [[ "${SERVO_TYPE}" == "servo_v2" ]]; then servo_save_add "i2c_mux_en" @@ -844,22 +845,22 @@ function claim_pty() { # interfere with flashing. servo_save_add "${MCU}_ec3po_interp_connect" - dut_control ${MCU}_ec3po_interp_connect:off || \ + dut_control "${MCU}_ec3po_interp_connect:off" || \ warn "hdctools cannot disconnect the EC-3PO interpreter from" \ "the UART." - pids=$(lsof -FR 2>/dev/null -- $1 | grep -v '^f' | tr -d 'pR') + pids=$(lsof -FR 2>/dev/null -- "$1" | grep -v '^f' | tr -d 'pR') FROZEN_PIDS="" # reverse order to SIGSTOP parents before children - for pid in $(echo ${pids} | tac -s " "); do + for pid in $(echo "${pids}" | tac -s " "); do if ps -o cmd= "${pid}" | grep -qE "(servod|/sbin/init)"; then info "Skip stopping servod or init: process ${pid}." else info "Sending SIGSTOP to process ${pid}!" FROZEN_PIDS+=" ${pid}" sleep 0.02 - kill -STOP ${pid} + kill -STOP "${pid}" fi done } @@ -901,7 +902,7 @@ repo sync && sudo emerge hdctools servo-firmware && sudo servo_updater -b c2d2" while [[ "$(dut_control_get h1_vref_present)" = "off" \ && "${LOOP_COUNTER}" -gt 1 ]] ; do sleep 0.1 - let LOOP_COUNTER=LOOP_COUNTER-1 + (( LOOP_COUNTER=LOOP_COUNTER-1 )) done # If we ran out of time, then just die now if [[ "${LOOP_COUNTER}" -eq 1 ]] ; then @@ -944,7 +945,7 @@ function flash_openocd() { # helper function for using servo with flashrom function flash_flashrom() { - TOOL_PATH="${EC_DIR}/build/${BOARD}/util:$PATH:/usr/sbin" + TOOL_PATH="${EC_DIR}/build/${BOARD}/util:${PATH}:/usr/sbin" FLASHROM=$(PATH="${TOOL_PATH}" which flashrom) if on_servov3; then @@ -960,21 +961,24 @@ function flash_flashrom() { FLASHROM_ARGS="-p ft2232_spi:type=google-servo-v2,port=B," fi - if [ ! -x "$FLASHROM" ]; then + if [ ! -x "${FLASHROM}" ]; then die "no flashrom util found." fi if ! on_servov3; then SERIALNAME=$(get_serial) - if [[ "$SERIALNAME" != "" ]] ; then + if [[ "${SERIALNAME}" != "" ]] ; then FLASHROM_ARGS+="serial=${SERIALNAME}" fi fi + # Eventually remove ite_spi_ccd_i2c once all references are removed if ! on_raiden || [[ "${SERVO_TYPE}" =~ "servo_micro" ]] ; then - if $(in_array "${BOARDS_SPI_1800MV[@]}" "${BOARD}"); then + if in_array "${BOARDS_SPI_1800MV[@]}" "${BOARD}"; then SPI_VOLTAGE="pp1800" - elif [[ "${CHIP}" == "ite_spi" || "${CHIP}" == "ite_spi_ccd_i2c" ]]; then + elif [[ "${CHIP}" == "ite_spi" || + "${CHIP}" == "ite_spi_ccd_i2c" || + "${CHIP}" == "it8xxx2" ]]; then SPI_VOLTAGE="pp1800" else SPI_VOLTAGE="pp3300" @@ -993,7 +997,9 @@ function flash_flashrom() { fi # Enable SPI programming mode. - if [[ "${CHIP}" == "ite_spi" || "${CHIP}" == "ite_spi_ccd_i2c" ]]; then + if [[ "${CHIP}" == "ite_spi" || + "${CHIP}" == "ite_spi_ccd_i2c" || + "${CHIP}" == "it8xxx2" ]]; then # Set hardware strap pin (GPG6) of SPI programming as low then start ec dut_control fw_up:on sleep 0.1 @@ -1007,7 +1013,7 @@ function flash_flashrom() { servo_save_add "spi1_buf_en" "off" # Turn on SPI1 interface on servo for SPI Flash Chip - dut_control spi1_vref:${SPI_VOLTAGE} spi1_buf_en:on + dut_control "spi1_vref:${SPI_VOLTAGE}" spi1_buf_en:on if [[ ! "${SERVO_TYPE}" =~ "servo_micro" ]]; then # Servo micro doesn't support this control. servo_save_add "spi1_buf_on_flex_en" "off" @@ -1033,24 +1039,25 @@ function flash_flashrom() { [[ -z "${FLAGS_read}" ]] && dump_fmap -F "${IMG}" > "${L}" - FLASHROM_OPTIONS="-i EC_RW -i WP_RO -l "${L}" --noverify-all" + FLASHROM_OPTIONS=(-i EC_RW -i WP_RO -l "${L}" --noverify-all) fi # Generate the correct flashrom command base. - FLASHROM_CMDLINE="${FLASHROM} ${FLASHROM_ARGS}" + # shellcheck disable=SC2206 + FLASHROM_CMDLINE=("${FLASHROM}" ${FLASHROM_ARGS}) if [[ -z "${FLAGS_read}" ]]; then # Program EC image. # flashrom should report the image size at the end of the output. - local FLASHROM_GETSIZE="sudo ${FLASHROM_CMDLINE} --flash-size" - if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then + local FLASHROM_GETSIZE=(sudo "${FLASHROM_CMDLINE[@]}" --flash-size) + if [[ "${FLAGS_verbose}" == "${FLAGS_TRUE}" ]]; then info "Running flashrom:" 1>&2 - echo " ${FLASHROM_GETSIZE}" 1>&2 + echo " ${FLASHROM_GETSIZE[*]}" 1>&2 fi - SPI_SIZE=$(${FLASHROM_GETSIZE} | grep -oe '[0-9]\+$' | + SPI_SIZE=$("${FLASHROM_GETSIZE[@]}" | grep -oe '[0-9]\+$' | tail -n1) || die "Failed to determine chip size!" [[ ${SPI_SIZE} -eq 0 ]] && die "Chip size is 0!" - PATCH_SIZE=$((${SPI_SIZE} - ${IMG_SIZE})) + PATCH_SIZE=$(( SPI_SIZE - IMG_SIZE )) # Temp image T=/tmp/flash_spi_$$ @@ -1058,66 +1065,67 @@ function flash_flashrom() { if [[ "${CHIP}" =~ ^npcx(|_int)_spi$ ]] || \ [[ "${CHIP}" =~ "ite_spi_ccd_i2c" ]] || + [[ "${CHIP}" =~ "it8xxx2" ]] || [[ "${CHIP}" =~ "ite_spi" ]] ; then { # Patch temp image up to SPI_SIZE - cat "$IMG" + cat "${IMG}" if [[ ${IMG_SIZE} -lt ${SPI_SIZE} ]] ; then - dd if=/dev/zero bs=${PATCH_SIZE} count=1 | \ + dd if=/dev/zero bs="${PATCH_SIZE}" count=1 | \ tr '\0' '\377' fi - } > $T + } > "${T}" else { # Patch temp image up to SPI_SIZE if [[ ${IMG_SIZE} -lt ${SPI_SIZE} ]] ; then - dd if=/dev/zero bs=${PATCH_SIZE} count=1 | \ + dd if=/dev/zero bs="${PATCH_SIZE}" count=1 | \ tr '\0' '\377' fi - cat "$IMG" - } > $T + cat "${IMG}" + } > "${T}" fi info "Programming EC firmware image." - local FLASHROM_WRITE="${FLASHROM_CMDLINE} ${FLASHROM_OPTIONS}" - if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then + local FLASHROM_WRITE=("${FLASHROM_CMDLINE[@]}" "${FLASHROM_OPTIONS[@]}") + if [[ "${FLAGS_verbose}" == "${FLAGS_TRUE}" ]]; then info "Running flashrom:" 1>&2 - echo " ${FLASHROM_WRITE} -w ${T}" 1>&2 + echo " ${FLASHROM_WRITE[*]} -w ${T}" 1>&2 fi print_or_run sudo timeout -k 10 -s 9 "${FLAGS_timeout}" \ - ${FLASHROM_WRITE} -w "${T}" \ + "${FLASHROM_WRITE[@]}" -w "${T}" \ || die "${MSG_PROGRAM_FAIL}" else # Read EC image. info "Reading EC firmware image." - if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then + if [[ "${FLAGS_verbose}" == "${FLAGS_TRUE}" ]]; then info "Running flashrom:" 1>&2 - echo " ${FLASHROM_CMDLINE} -r ${FLAGS_read}" 1>&2 + echo " ${FLASHROM_CMDLINE[*]} -r ${FLAGS_read}" 1>&2 fi print_or_run sudo timeout -k 10 -s 9 "${FLAGS_timeout}" \ - ${FLASHROM_CMDLINE} -r "${FLAGS_read}" \ + "${FLASHROM_CMDLINE[@]}" -r "${FLAGS_read}" \ || die "${MSG_READ_FAIL}" fi } function flash_stm32() { local STM32MON - local STM32MON_OPT + local STM32MON_OPT=() if ! servo_has_cold_reset; then die "Cold reset must be available for STM32 programming" fi - TOOL_PATH="${EC_DIR}/build/${BOARD}/util:$PATH" + TOOL_PATH="${EC_DIR}/build/${BOARD}/util:${PATH}" STM32MON=$(PATH="${TOOL_PATH}" which stm32mon) EC_UART="$(servo_ec_uart)" EC_UART_PREFIX="$(servo_ec_uart_prefix)" - if [ ! -x "$STM32MON" ]; then + if [ ! -x "${STM32MON}" ]; then die "no stm32mon util found." fi info "Using serial flasher : ${STM32MON}" info "${MCU} UART pty : ${EC_UART}" - claim_pty ${EC_UART} - STM32MON_OPT="-d ${EC_UART}" + claim_pty "${EC_UART}" + STM32MON_OPT+=(-d "${EC_UART}") # Make sure EC reboots in serial monitor mode. ec_enable_boot0 "bitbang" @@ -1160,12 +1168,12 @@ function flash_stm32() { # ccdstate once a second, so a 2 second delay should be safe. if servo_is_ccd ; then sleep 2 - STM32MON_OPT+=" -c" + STM32MON_OPT+=(-c) fi if [ -n "${FLAGS_logfile}" ]; then info "Saving log in ${FLAGS_logfile}" - STM32MON_OPT+=" -L ${FLAGS_logfile}" + STM32MON_OPT+=(-L "${FLAGS_logfile}") fi local IMG_READ="${FLAGS_read}" @@ -1173,19 +1181,21 @@ function flash_stm32() { if [[ -z "${IMG_READ}" ]]; then info "Programming EC firmware image." # Unprotect flash, erase, and write - local STM32MON_COMMAND="${STM32MON} ${STM32MON_OPT} -U -u -e -w" - if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then - echo "${STM32MON_COMMAND} ${IMG}" + local STM32MON_COMMAND=("${STM32MON}" "${STM32MON_OPT[@]}" -U -u -e -w) + if [[ "${FLAGS_verbose}" == "${FLAGS_TRUE}" ]]; then + echo "${STM32MON_COMMAND[*]} ${IMG}" fi print_or_run timeout -k 10 -s 9 "${FLAGS_timeout}" \ - ${STM32MON_COMMAND} "${IMG}" \ + "${STM32MON_COMMAND[@]}" "${IMG}" \ || die "${MSG_PROGRAM_FAIL}" # If it is a program-verify request, then make a temporary # directory to store the image - if [[ "${FLAGS_verify}" == ${FLAGS_TRUE} ]]; then - local TEMP_SUFFIX=".$(basename ${SCRIPT}).${CHIP}" - local TEMP_DIR="$(mktemp -d --suffix="${TEMP_SUFFIX}")" + if [[ "${FLAGS_verify}" == "${FLAGS_TRUE}" ]]; then + local TEMP_SUFFIX + local TEMP_DIR + TEMP_SUFFIX=".$(basename "${SCRIPT}").${CHIP}" + TEMP_DIR="$(mktemp -d --suffix="${TEMP_SUFFIX}")" IMG_READ="${TEMP_DIR}/ec.read.bin" DELETE_LIST+=( "${TEMP_DIR}" ) @@ -1195,20 +1205,20 @@ function flash_stm32() { # Read EC image. if [[ -n "${IMG_READ}" ]]; then info "Reading EC firmware image." - local STM32MON_READ_CMD="${STM32MON} ${STM32MON_OPT} -U -r" - if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then - echo "${STM32MON_READ_CMD} ${IMG_READ}" + local STM32MON_READ_CMD=("${STM32MON}" "${STM32MON_OPT[@]}" -U -r) + if [[ "${FLAGS_verbose}" == "${FLAGS_TRUE}" ]]; then + echo "${STM32MON_READ_CMD[*]} ${IMG_READ}" fi print_or_run timeout -k 10 -s 9 "${FLAGS_timeout}" \ - ${STM32MON_READ_CMD} "${IMG_READ}" \ + "${STM32MON_READ_CMD[@]}" "${IMG_READ}" \ || die "${MSG_READ_FAIL}" fi # Verify the flash by comparing the source image to the read image, # only if it was a flash write request. - if [[ -z "${FLAGS_read}" && "${FLAGS_verify}" == ${FLAGS_TRUE} ]]; then + if [[ -z "${FLAGS_read}" && "${FLAGS_verify}" == "${FLAGS_TRUE}" ]]; then info "Verifying EC firmware image." - if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then + if [[ "${FLAGS_verbose}" == "${FLAGS_TRUE}" ]]; then echo "cmp -n ${IMG_SIZE} ${IMG} ${IMG_READ}" fi cmp -s -n "${IMG_SIZE}" "${IMG}" "${IMG_READ}" \ @@ -1226,41 +1236,42 @@ function flash_stm32_dfu() { DFU_DEVICE=0483:df11 ADDR=0x08000000 DFU_UTIL='dfu-util' - which $DFU_UTIL &> /dev/null || die \ + which "${DFU_UTIL}" &> /dev/null || die \ "no dfu-util util found. Did you 'sudo emerge dfu-util'" info "Using dfu flasher : ${DFU_UTIL}" - dev_cnt=$(lsusb -d $DFU_DEVICE | wc -l) - if [ $dev_cnt -eq 0 ] ; then - die "unable to locate dfu device at $DFU_DEVICE" - elif [ $dev_cnt -ne 1 ] ; then + dev_cnt=$(lsusb -d "${DFU_DEVICE}" | wc -l) + if [ "${dev_cnt}" -eq 0 ] ; then + die "unable to locate dfu device at ${DFU_DEVICE}" + elif [ "${dev_cnt}" -ne 1 ] ; then die "too many dfu devices (${dev_cnt}). Disconnect all but one." fi - SIZE=$(wc -c ${IMG} | cut -d' ' -f1) + SIZE=$(wc -c "${IMG}" | cut -d' ' -f1) # Remove read protection - print_or_run sudo timeout -k 10 -s 9 "${FLAGS_timeout}" $DFU_UTIL -a 0 \ - -d "${DFU_DEVICE}" -s ${ADDR}:${SIZE}:force:unprotect -D "${IMG}" + print_or_run sudo timeout -k 10 -s 9 "${FLAGS_timeout}" "${DFU_UTIL}" -a 0 \ + -d "${DFU_DEVICE}" -s "${ADDR}:${SIZE}:force:unprotect" -D "${IMG}" # Wait for mass-erase and reboot after unprotection print_or_run sleep 1 # Actual image flashing - print_or_run sudo timeout -k 10 -s 9 "${FLAGS_timeout}" $DFU_UTIL -a 0 \ - -d "${DFU_DEVICE}" -s ${ADDR}:${SIZE} -D "${IMG}" + print_or_run sudo timeout -k 10 -s 9 "${FLAGS_timeout}" "${DFU_UTIL}" -a 0 \ + -d "${DFU_DEVICE}" -s "${ADDR}:${SIZE}" -D "${IMG}" } function dut_i2c_dev() { - if [ -n "$DUT_I2C_DEV" ]; then - [ -e "$DUT_I2C_DEV" ] || - die "\$DUT_I2C_DEV is a non-existent path: $DUT_I2C_DEV" - echo "$DUT_I2C_DEV" + if [ -n "${DUT_I2C_DEV}" ]; then + [ -e "${DUT_I2C_DEV}" ] || + die "\$DUT_I2C_DEV is a non-existent path: ${DUT_I2C_DEV}" + echo "${DUT_I2C_DEV}" return fi - local has_i2c_pseudo="$(dut_control_get_or_die \ + local has_i2c_pseudo + has_i2c_pseudo="$(dut_control_get_or_die \ "${ACTIVE_DEVICE}_i2c_pseudo_is_running")" if [[ "${has_i2c_pseudo}" == False ]]; then - error "i2c-pseudo module is not running." + error "i2c-pseudo module is not running on ${ACTIVE_DEVICE}." error "Please follow https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/util/iteflash.md#i2c-pseudo" die "to install i2c-pseudo module." fi @@ -1268,14 +1279,15 @@ function dut_i2c_dev() { local adap_num= adap_num="$(dut_control_get_or_die \ "${ACTIVE_DEVICE}_i2c_pseudo_adapter_num")" - echo /dev/i2c-"$adap_num" + echo /dev/i2c-"${adap_num}" } function flash_it83xx() { - local TOOL_PATH="${EC_DIR}/build/${BOARD}/util:$PATH" - local ITEFLASH_BIN=$(PATH="${TOOL_PATH}" which iteflash) + local TOOL_PATH="${EC_DIR}/build/${BOARD}/util:${PATH}" + local ITEFLASH_BIN + ITEFLASH_BIN=$(PATH="${TOOL_PATH}" which iteflash) - if [[ ! -x "$ITEFLASH_BIN" ]]; then + if [[ ! -x "${ITEFLASH_BIN}" ]]; then die "no iteflash util found." fi @@ -1291,7 +1303,10 @@ function flash_it83xx() { dut_control_or_die i2c_ec_bus_speed:400 # We need to swing the DUT-side muxes to I2C instead of UART. - # This is done by convention with EC_FLASH_SELECT pin from H1 + # This is done by convention with EC_FLASH_SELECT pin of the + # GSC. Also make sure that the setting is restored after + # completion. + servo_save_add "ec_flash_select" "off" dut_control_or_die ec_flash_select:on fi @@ -1318,7 +1333,8 @@ function flash_it83xx() { info "Asking servo to send the dbgr special waveform to ${CHIP}" dut_control_or_die enable_ite_dfu elif servo_is_ccd; then - local CCD_I2C_CAP="$(dut_control_get ccd_i2c_en)" + local CCD_I2C_CAP + CCD_I2C_CAP="$(dut_control_get ccd_i2c_en)" if [[ "${CCD_I2C_CAP,,}" != "always" ]]; then die "CCD I2C capability is not set as 'Always'" \ ": ${CCD_I2C_CAP}" @@ -1364,7 +1380,7 @@ function flash_it83xx() { ITEFLASH_ARGS+=( "--noverify" ) fi - if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then + if [[ "${FLAGS_verbose}" == "${FLAGS_TRUE}" ]]; then ITEFLASH_ARGS+=( "--debug" ) echo "${ITEFLASH_ARGS[@]}" fi @@ -1393,10 +1409,14 @@ function flash_ite_spi_ccd_i2c() { fi } +function flash_it8xxx2() { + flash_ite_spi_ccd_i2c +} + function flash_npcx_jtag() { IMG_PATH="${EC_DIR}/build/${BOARD}" OCD_CHIP_CFG="npcx_chip.cfg" - if [ "${FLAGS_ro}" = ${FLAGS_TRUE} ] ; then + if [ "${FLAGS_ro}" = "${FLAGS_TRUE}" ] ; then # Program RO region only OCD_CMDS="init; flash_npcx_ro ${CHIP} ${IMG_PATH} ${FLAGS_offset}; shutdown;" else @@ -1411,23 +1431,25 @@ function flash_npcx_jtag() { } function flash_npcx_uut() { - local TOOL_PATH="${EC_DIR}/build/${BOARD}/util:$PATH" - local NPCX_UUT=$(PATH="${TOOL_PATH}" which uartupdatetool) - local EC_UART="$(servo_ec_uart)" + local NPCX_UUT + local EC_UART + local TOOL_PATH="${EC_DIR}/build/${BOARD}/util:${PATH}" + NPCX_UUT=$(PATH="${TOOL_PATH}" which uartupdatetool) + EC_UART="$(servo_ec_uart)" # Look for npcx_monitor.bin in multiple directories, starting with # the same path as the EC binary. local MON="" for dir in \ - "$(dirname "$IMG")/chip/npcx/spiflashfw" \ - "$(dirname "$IMG")" \ + "$(dirname "${IMG}")/chip/npcx/spiflashfw" \ + "$(dirname "${IMG}")" \ "${EC_DIR}/build/${BOARD}/chip/npcx/spiflashfw" \ "${EC_DIR}/build/zephyr/${BOARD}/output" \ - "$(dirname "$LOCAL_BUILD")" \ - "$(dirname "$EMERGE_BUILD")" ; + "$(dirname "${LOCAL_BUILD}")" \ + "$(dirname "${EMERGE_BUILD}")" ; do - if [ -f "$dir/npcx_monitor.bin" ] ; then - MON="$dir/npcx_monitor.bin" + if [ -f "${dir}/npcx_monitor.bin" ] ; then + MON="${dir}/npcx_monitor.bin" break fi done @@ -1440,13 +1462,13 @@ function flash_npcx_uut() { # The start address to restore monitor firmware binary local MON_ADDR="0x200C3020" - if [ ! -x "$NPCX_UUT" ]; then + if [ ! -x "${NPCX_UUT}" ]; then die "no NPCX UART Update Tool found." fi info "Using: NPCX UART Update Tool" info "${MCU} UART pty : ${EC_UART}" - claim_pty ${EC_UART} + claim_pty "${EC_UART}" if [[ "${SERVO_TYPE}" =~ "ccd_cr50" ]] ; then # Ti50 does not yet support ccd_keepalive option which @@ -1495,7 +1517,7 @@ function flash_npcx_uut() { "--file=${MON}" ) # Load monitor binary to address 0x200C3020 - if [[ "${FLAGS_verbose}" = ${FLAGS_TRUE} ]]; then + if [[ "${FLAGS_verbose}" = "${FLAGS_TRUE}" ]]; then echo "${UUT_MON[*]}" fi @@ -1523,7 +1545,7 @@ function flash_npcx_uut() { local UUT_WR=( "${NPCX_UUT}" "${UUT_ARGS[@]}" \ "--auto" "--offset=${FLAGS_offset}" \ "--file=${IMG}" ) - if [[ "${FLAGS_verbose}" = ${FLAGS_TRUE} ]]; then + if [[ "${FLAGS_verbose}" = "${FLAGS_TRUE}" ]]; then echo "${UUT_WR[*]}" fi print_or_run timeout -k 10 -s 9 "${FLAGS_timeout}" \ @@ -1531,9 +1553,11 @@ function flash_npcx_uut() { # If it is a program-verify request, then make a temporary # directory to store the image. - if [[ "${FLAGS_verify}" == ${FLAGS_TRUE} ]]; then - local TEMP_SUFFIX=".$(basename ${SCRIPT}).${CHIP}.$$" - local TEMP_DIR="$(mktemp -d --suffix="${TEMP_SUFFIX}")" + if [[ "${FLAGS_verify}" == "${FLAGS_TRUE}" ]]; then + local TEMP_SUFFIX + local TEMP_DIR + TEMP_SUFFIX=".$(basename "${SCRIPT}").${CHIP}.$$" + TEMP_DIR="$(mktemp -d --suffix="${TEMP_SUFFIX}")" IMG_READ="${TEMP_DIR}/ec.read.bin" DELETE_LIST+=( "${TEMP_DIR}" ) @@ -1547,7 +1571,7 @@ function flash_npcx_uut() { local UUT_RD=( "${NPCX_UUT}" "${UUT_ARGS[@]}" \ "--read-flash" "--file=${IMG_READ}" ) - if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then + if [[ "${FLAGS_verbose}" == "${FLAGS_TRUE}" ]]; then echo "${UUT_RD[*]}" fi print_or_run timeout -k 10 -s 9 "${FLAGS_timeout}" \ @@ -1556,10 +1580,10 @@ function flash_npcx_uut() { # Verify the flash by comparing the source image to the read image, # only if it was a flash write request. - if [[ -z "${FLAGS_read}" && "${FLAGS_verify}" == ${FLAGS_TRUE} ]]; then + if [[ -z "${FLAGS_read}" && "${FLAGS_verify}" == "${FLAGS_TRUE}" ]]; then info "Verifying EC firmware image." - if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then + if [[ "${FLAGS_verbose}" == "${FLAGS_TRUE}" ]]; then echo "cmp -n ${IMG_SIZE} ${IMG} ${IMG_READ}" fi @@ -1610,5 +1634,5 @@ if [ "${NEED_SERVO}" != "no" ] ; then fi info "Flashing chip ${CHIP}." -flash_${CHIP} +flash_"${CHIP}" info "Flashing done." diff --git a/util/flash_fp_mcu b/util/flash_fp_mcu index 75a989e1f4..a823174c94 100644 --- a/util/flash_fp_mcu +++ b/util/flash_fp_mcu @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2019 The Chromium OS Authors. All rights reserved. +# Copyright 2019 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -430,19 +430,7 @@ flash_fp_mcu_stm32() { fi # Go back to normal mode - gpio out "${gpio_nrst}" - gpio 0 "${gpio_boot0}" "${gpio_nrst}" - gpio 1 "${gpio_nrst}" - - # Give up GPIO control, unless we need to keep these driving as - # outputs because they're not open-drain signals. - # TODO(b/179839337): Make this the default and properly support - # open-drain outputs on other platforms. - if [[ "${PLATFORM_BASE_NAME}" != "strongbad" ]] && - [[ "${PLATFORM_BASE_NAME}" != "herobrine" ]]; then - gpio in "${gpio_boot0}" "${gpio_nrst}" - fi - gpio unexport "${gpio_boot0}" "${gpio_nrst}" + gpio 0 "${gpio_boot0}" # Dartmonkey's RO has a flashprotect logic issue that forces reboot loops # when SW-WP is enabled and HW-WP is disabled. It is avoided if a POR is @@ -458,8 +446,25 @@ flash_fp_mcu_stm32() { gpio 1 "${gpio_pwren}" # Power enable line is externally pulled down, so leave as output-high. gpio unexport "${gpio_pwren}" + else + echo "Reset the FPMCU." + gpio out "${gpio_nrst}" + gpio 0 "${gpio_nrst}" + # Make sure that we keep nRST line low long enough. + sleep 0.01 + gpio 1 "${gpio_nrst}" fi + # Give up GPIO control, unless we need to keep these driving as + # outputs because they're not open-drain signals. + # TODO(b/179839337): Make this the default and properly support + # open-drain outputs on other platforms. + if [[ "${PLATFORM_BASE_NAME}" != "strongbad" ]] && + [[ "${PLATFORM_BASE_NAME}" != "herobrine" ]]; then + gpio in "${gpio_boot0}" "${gpio_nrst}" + fi + gpio unexport "${gpio_boot0}" "${gpio_nrst}" + # Put back cros_fp driver if transport is SPI if [[ "${transport}" != "UART" ]]; then # wait for FP MCU to come back up (including RWSIG delay) @@ -467,6 +472,18 @@ flash_fp_mcu_stm32() { klog "Binding cros-ec driver" echo "" > "/sys/bus/spi/devices/${deviceid}/driver_override" echo "${deviceid}" > /sys/bus/spi/drivers/cros-ec-spi/bind + else + # FPMCU can still have ro_now protection (sector write protection) enabled + # e.g. when flash_fp_mcu was run with --read option. It is disabled when + # FPMCU boots with HW write protect disabled. + # Disabling sector write protection takes some time due to flash internal + # structures update. During that time we can't reset or power cycle FPMCU + # otherwise we will corrupt internal flash state which will brick FPMCU. + # This situation can occur if DUT is rebooted immediately after flash_fp_mcu + # finishes, so give some time to remove sector write protection. No need to + # wait if transport is SPI because later we query for version and reset + # flags. + sleep 3 fi if [[ "${cmd_exit_status}" -ne 0 ]]; then @@ -493,13 +510,25 @@ config_hatch() { # for pin name to number mapping. # Examine `cat /sys/kernel/debug/pinctrl/INT34BB:00/gpio-ranges` on a hatch # device to determine gpio number from pin number. - readonly GPIO_CHIP="gpiochip200" - # FPMCU RST_ODL is on GPP_A12 = 200 + 12 = 212 - readonly GPIO_NRST=212 - # FPMCU BOOT0 is on GPP_A22 = 200 + 22 = 222 - readonly GPIO_BOOT0=222 - # FP_PWR_EN is on GPP_C11 = 456 + (192 - 181) = 456 + 11 = 467 - readonly GPIO_PWREN=467 + + local gpiochip="gpiochip712" + # Support kernel version 4.x, 5.4 and 5.10 during transition to 5.15+ + match_kernel_regex "^((4\..)|(5\.4\.)|(5\.10\.))" && gpiochip="gpiochip200" + readonly GPIO_CHIP="${gpiochip}" + local offset=0 + # Support kernel version 4.x, 5.4 and 5.10 during transition to 5.15+ + # v4.4 has GPIOs that are offset by -512 + match_kernel_regex "^((4\..)|(5\.4\.)|(5\.10\.))" && offset=512 + + # FPMCU RST_ODL is on GPP_A12 = 712 + 12 = 724 + local gpionrst=724 + readonly GPIO_NRST=$(( gpionrst - offset )) + # FPMCU BOOT0 is on GPP_A22 = 712 + 22 = 734 + local gpioboot=734 + readonly GPIO_BOOT0=$(( gpioboot - offset )) + # FP_PWR_EN is on GPP_C11 = 968 + (192 - 181) = 968 + 11 = 979 + local gpiopwren=979 + readonly GPIO_PWREN=$(( gpiopwren - offset )) } config_herobrine() { @@ -542,26 +571,13 @@ config_nami() { readonly GPIO_PWREN=395 } -config_nami-kernelnext() { - config_nami -} - config_nocturne() { - readonly TRANSPORT="SPI" - readonly DEVICE="/dev/spidev32765.0" - - readonly GPIO_CHIP="gpiochip360" - # FPMCU RST_ODL is on GPP_C10 = 360 + 58 = 418 - readonly GPIO_NRST=418 - # FPMCU BOOT0 is on GPP_C8 = 360 + 56 = 416 - readonly GPIO_BOOT0=416 - # FP_PWR_EN is on GPP_A11 = 360 + 11 = 371 - readonly GPIO_PWREN=371 -} + local device="/dev/spidev1.0" + # Support kernel version 4.4 during transition to 5.10 + match_kernel_regex "^4\.4\." && device="/dev/spidev32765.0" -config_nocturne-kernelnext() { readonly TRANSPORT="SPI" - readonly DEVICE="/dev/spidev1.0" + readonly DEVICE="${device}" readonly GPIO_CHIP="gpiochip360" # FPMCU RST_ODL is on GPP_C10 = 360 + 58 = 418 @@ -610,15 +626,26 @@ config_volteer() { # volteer device to determine gpio number from pin number. # For example: GPP_C23 is UART2_CTS which can be queried from EDS # the pin number is 194. From the gpio-ranges, the gpio value is - # 408 + (194-171) = 431 - - readonly GPIO_CHIP="gpiochip152" - # FPMCU RST_ODL is on GPP_C23 = 408 + (194 - 171) = 431 - readonly GPIO_NRST=431 - # FPMCU BOOT0 is on GPP_C22 = 408 + (193 - 171) = 430 - readonly GPIO_BOOT0=430 - # FP_PWR_EN is on GPP_A21 = 216 + (63 - 42) = 237 - readonly GPIO_PWREN=237 + # 920 + (194-171) = 943 + + local gpiochip="gpiochip664" + # Support kernel version 4.x, 5.4, 5.10 during transition to 5.15+ + match_kernel_regex "^((4\..)|(5\.4\.)|(5\.10\..))" && gpiochip="gpiochip152" + readonly GPIO_CHIP="${gpiochip}" + local offset=0 + # Support kernel version 4.x, 5.4, 5.10 during transition to 5.15+ + # v4.4 has GPIOs that are offset by -512 + match_kernel_regex "^((4\..)|(5\.4\.)|(5\.10\.))" && offset=512 + + # FPMCU RST_ODL is on GPP_C23 = 920 + (194 - 171) = 943 + local gpionrst=943 + readonly GPIO_NRST=$(( gpionrst - offset )) + # FPMCU BOOT0 is on GPP_C22 = 920 + (193 - 171) = 942 + local gpioboot=942 + readonly GPIO_BOOT0=$(( gpioboot - offset )) + # FP_PWR_EN is on GPP_A21 = 728 + (63 - 42) = 749 + local gpiopwren=749 + readonly GPIO_PWREN=$(( gpiopwren - offset )) } config_brya() { @@ -631,15 +658,27 @@ config_brya() { # brya device to determine gpio number from pin number. # For example: GPP_D1 is ISH_GP_1 which can be queried from EDS # the pin number is 100 from the pinctrl-tigerlake.c. - # From the gpio-ranges, the gpio value is 312 + (100-99) = 313 - - readonly GPIO_CHIP="gpiochip152" - # FPMCU RST_ODL is on GPP_D1 = 312 + (100 - 99) = 313 - readonly GPIO_NRST=313 - # FPMCU BOOT0 is on GPP_D0 = 312 + (99 - 99) = 312 - readonly GPIO_BOOT0=312 - # FP_PWR_EN is on GPP_D2 = 312 + (101 - 99) = 314 - readonly GPIO_PWREN=314 + # From the gpio-ranges, the gpio value is 824 + (100-99) = 825 + + local gpiochip="gpiochip664" + # Support kernel version 5.10 during transition to 5.15+ + match_kernel_regex "^5\.10\." && gpiochip="gpiochip152" + readonly GPIO_CHIP="${gpiochip}" + + local offset=0 + # Support kernel version 5.10 during transition to 5.15+ + # v5.10 has GPIOs that are offset by -512 + match_kernel_regex "^5\.10\." && offset=512 + + # FPMCU RST_ODL is on GPP_D1 = 824 + (100 - 99) = 825 + local gpionrst=825 + readonly GPIO_NRST=$(( gpionrst - offset )) + # FPMCU BOOT0 is on GPP_D0 = 824 + (99 - 99) = 824 + local gpioboot=824 + readonly GPIO_BOOT0=$(( gpioboot - offset )) + # FP_PWR_EN is on GPP_D2 = 824 + (101 - 99) = 826 + local gpiopwren=826 + readonly GPIO_PWREN=$(( gpiopwren - offset )) } config_brask() { @@ -647,6 +686,11 @@ config_brask() { config_brya } +config_ghost() { + # No changes to brya. + config_brya +} + config_zork() { readonly TRANSPORT="UART" readonly DEVICE="/dev/ttyS1" @@ -674,6 +718,20 @@ config_guybrush() { readonly GPIO_PWREN=259 } +config_skyrim() { + readonly TRANSPORT="UART" + + readonly DEVICE="/dev/ttyS1" + + readonly GPIO_CHIP="gpiochip768" + # FPMCU RST_ODL is on AGPIO 12 = 768 + 12 = 780 + readonly GPIO_NRST=780 + # FPMCU BOOT0 is on AGPIO 130 = 768 + 130 = 898 + readonly GPIO_BOOT0=898 + # FPMCU PWR_EN is on AGPIO 4 = 768 + 4 = 772 + readonly GPIO_PWREN=772 +} + main() { local filename="$1" diff --git a/util/flash_jlink.py b/util/flash_jlink.py index 26c3c2e709..dc462e354b 100755 --- a/util/flash_jlink.py +++ b/util/flash_jlink.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright 2020 The Chromium OS Authors. All rights reserved. +# Copyright 2020 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -25,7 +25,6 @@ import sys import tempfile import time - DEFAULT_SEGGER_REMOTE_PORT = 19020 # Commands are documented here: https://wiki.segger.com/J-Link_Commander @@ -41,27 +40,34 @@ exit class BoardConfig: """Board configuration.""" + def __init__(self, interface, device, flash_address): self.interface = interface self.device = device self.flash_address = flash_address -SWD_INTERFACE = 'SWD' -STM32_DEFAULT_FLASH_ADDRESS = '0x8000000' -DRAGONCLAW_CONFIG = BoardConfig(interface=SWD_INTERFACE, device='STM32F412CG', - flash_address=STM32_DEFAULT_FLASH_ADDRESS) -ICETOWER_CONFIG = BoardConfig(interface=SWD_INTERFACE, device='STM32H743ZI', - flash_address=STM32_DEFAULT_FLASH_ADDRESS) +SWD_INTERFACE = "SWD" +STM32_DEFAULT_FLASH_ADDRESS = "0x8000000" +DRAGONCLAW_CONFIG = BoardConfig( + interface=SWD_INTERFACE, + device="STM32F412CG", + flash_address=STM32_DEFAULT_FLASH_ADDRESS, +) +ICETOWER_CONFIG = BoardConfig( + interface=SWD_INTERFACE, + device="STM32H743ZI", + flash_address=STM32_DEFAULT_FLASH_ADDRESS, +) BOARD_CONFIGS = { - 'dragonclaw': DRAGONCLAW_CONFIG, - 'bloonchipper': DRAGONCLAW_CONFIG, - 'nucleo-f412zg': DRAGONCLAW_CONFIG, - 'dartmonkey': ICETOWER_CONFIG, - 'icetower': ICETOWER_CONFIG, - 'nucleo-dartmonkey': ICETOWER_CONFIG, - 'nucleo-h743zi': ICETOWER_CONFIG, + "dragonclaw": DRAGONCLAW_CONFIG, + "bloonchipper": DRAGONCLAW_CONFIG, + "nucleo-f412zg": DRAGONCLAW_CONFIG, + "dartmonkey": ICETOWER_CONFIG, + "icetower": ICETOWER_CONFIG, + "nucleo-dartmonkey": ICETOWER_CONFIG, + "nucleo-h743zi": ICETOWER_CONFIG, } @@ -93,9 +99,11 @@ def is_tcp_port_open(host: str, tcp_port: int) -> bool: def create_jlink_command_file(firmware_file, config): tmp = tempfile.NamedTemporaryFile() - tmp.write(JLINK_COMMANDS.format(FIRMWARE=firmware_file, - FLASH_ADDRESS=config.flash_address).encode( - 'utf-8')) + tmp.write( + JLINK_COMMANDS.format( + FIRMWARE=firmware_file, FLASH_ADDRESS=config.flash_address + ).encode("utf-8") + ) tmp.flush() return tmp @@ -106,8 +114,8 @@ def flash(jlink_exe, remote, device, interface, cmd_file): ] if remote: - logging.debug(f'Connecting to J-Link over TCP/IP {remote}.') - remote_components = remote.split(':') + logging.debug(f"Connecting to J-Link over TCP/IP {remote}.") + remote_components = remote.split(":") if len(remote_components) not in [1, 2]: logging.debug(f'Given remote "{remote}" is malformed.') return 1 @@ -118,7 +126,7 @@ def flash(jlink_exe, remote, device, interface, cmd_file): except socket.gaierror as e: logging.error(f'Failed to resolve host "{host}": {e}.') return 1 - logging.debug(f'Resolved {host} as {ip}.') + logging.debug(f"Resolved {host} as {ip}.") port = DEFAULT_SEGGER_REMOTE_PORT if len(remote_components) == 2: @@ -126,29 +134,40 @@ def flash(jlink_exe, remote, device, interface, cmd_file): port = int(remote_components[1]) except ValueError: logging.error( - f'Given remote port "{remote_components[1]}" is malformed.') + f'Given remote port "{remote_components[1]}" is malformed.' + ) return 1 - remote = f'{ip}:{port}' + remote = f"{ip}:{port}" - logging.debug(f'Checking connection to {remote}.') + logging.debug(f"Checking connection to {remote}.") if not is_tcp_port_open(ip, port): logging.error( - f"JLink server doesn't seem to be listening on {remote}.") - logging.error('Ensure that JLinkRemoteServerCLExe is running.') + f"JLink server doesn't seem to be listening on {remote}." + ) + logging.error("Ensure that JLinkRemoteServerCLExe is running.") return 1 - cmd.extend(['-ip', remote]) - - cmd.extend([ - '-device', device, - '-if', interface, - '-speed', 'auto', - '-autoconnect', '1', - '-CommandFile', cmd_file, - ]) - logging.debug('Running command: "%s"', ' '.join(cmd)) - completed_process = subprocess.run(cmd) # pylint: disable=subprocess-run-check - logging.debug('JLink return code: %d', completed_process.returncode) + cmd.extend(["-ip", remote]) + + cmd.extend( + [ + "-device", + device, + "-if", + interface, + "-speed", + "auto", + "-autoconnect", + "1", + "-CommandFile", + cmd_file, + ] + ) + logging.debug('Running command: "%s"', " ".join(cmd)) + completed_process = subprocess.run( + cmd + ) # pylint: disable=subprocess-run-check + logging.debug("JLink return code: %d", completed_process.returncode) return completed_process.returncode @@ -156,36 +175,42 @@ def main(argv: list): parser = argparse.ArgumentParser() - default_jlink = './JLink_Linux_V684a_x86_64/JLinkExe' + default_jlink = "./JLink_Linux_V684a_x86_64/JLinkExe" if shutil.which(default_jlink) is None: - default_jlink = 'JLinkExe' + default_jlink = "JLinkExe" parser.add_argument( - '--jlink', '-j', - help='JLinkExe path (default: ' + default_jlink + ')', - default=default_jlink) + "--jlink", + "-j", + help="JLinkExe path (default: " + default_jlink + ")", + default=default_jlink, + ) parser.add_argument( - '--remote', '-n', - help='Use TCP/IP host[:port] to connect to a J-Link or ' - 'JLinkRemoteServerCLExe. If unspecified, connect over USB.') + "--remote", + "-n", + help="Use TCP/IP host[:port] to connect to a J-Link or " + "JLinkRemoteServerCLExe. If unspecified, connect over USB.", + ) - default_board = 'bloonchipper' + default_board = "bloonchipper" parser.add_argument( - '--board', '-b', - help='Board (default: ' + default_board + ')', - default=default_board) + "--board", + "-b", + help="Board (default: " + default_board + ")", + default=default_board, + ) - default_firmware = os.path.join('./build', default_board, 'ec.bin') + default_firmware = os.path.join("./build", default_board, "ec.bin") parser.add_argument( - '--image', '-i', - help='Firmware binary (default: ' + default_firmware + ')', - default=default_firmware) + "--image", + "-i", + help="Firmware binary (default: " + default_firmware + ")", + default=default_firmware, + ) - log_level_choices = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'] + log_level_choices = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] parser.add_argument( - '--log_level', '-l', - choices=log_level_choices, - default='DEBUG' + "--log_level", "-l", choices=log_level_choices, default="DEBUG" ) args = parser.parse_args(argv) @@ -201,11 +226,12 @@ def main(argv: list): args.jlink = args.jlink cmd_file = create_jlink_command_file(args.image, config) - ret_code = flash(args.jlink, args.remote, config.device, config.interface, - cmd_file.name) + ret_code = flash( + args.jlink, args.remote, config.device, config.interface, cmd_file.name + ) cmd_file.close() return ret_code -if __name__ == '__main__': +if __name__ == "__main__": sys.exit(main(sys.argv[1:])) diff --git a/util/fptool.py b/util/fptool.py index 5d73302bbc..ba00c0020a 100755 --- a/util/fptool.py +++ b/util/fptool.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Copyright 2021 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -19,14 +19,14 @@ def cmd_flash(args: argparse.Namespace) -> int: disabled. """ - if not shutil.which('flash_fp_mcu'): - print('Error - The flash_fp_mcu utility does not exist.') + if not shutil.which("flash_fp_mcu"): + print("Error - The flash_fp_mcu utility does not exist.") return 1 - cmd = ['flash_fp_mcu'] + cmd = ["flash_fp_mcu"] if args.image: if not os.path.isfile(args.image): - print(f'Error - image {args.image} is not a file.') + print(f"Error - image {args.image} is not a file.") return 1 cmd.append(args.image) @@ -38,18 +38,19 @@ def cmd_flash(args: argparse.Namespace) -> int: def main(argv: list) -> int: parser = argparse.ArgumentParser(description=__doc__) - subparsers = parser.add_subparsers(dest='subcommand', title='subcommands') + subparsers = parser.add_subparsers(dest="subcommand", title="subcommands") # This method of setting required is more compatible with older python. subparsers.required = True # Parser for "flash" subcommand. - parser_decrypt = subparsers.add_parser('flash', help=cmd_flash.__doc__) + parser_decrypt = subparsers.add_parser("flash", help=cmd_flash.__doc__) parser_decrypt.add_argument( - 'image', nargs='?', help='Path to the firmware image') + "image", nargs="?", help="Path to the firmware image" + ) parser_decrypt.set_defaults(func=cmd_flash) opts = parser.parse_args(argv) return opts.func(opts) -if __name__ == '__main__': +if __name__ == "__main__": sys.exit(main(sys.argv[1:])) diff --git a/util/gdbinit b/util/gdbinit index ff71e4c39c..1854b4bdc0 100644 --- a/util/gdbinit +++ b/util/gdbinit @@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium OS Authors. All rights reserved. +# Copyright 2019 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/util/gen_emmc_transfer_data.c b/util/gen_emmc_transfer_data.c index 98417beb9b..3c80724594 100644 --- a/util/gen_emmc_transfer_data.c +++ b/util/gen_emmc_transfer_data.c @@ -1,4 +1,4 @@ -/* Copyright 2018 The Chromium OS Authors. All rights reserved. +/* Copyright 2018 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -16,8 +16,8 @@ #include <compile_time_macros.h> /* eMMC transfer block size */ -#define BLOCK_SIZE 512 -#define BLOCK_RAW_DATA "bootblock_raw_data" +#define BLOCK_SIZE 512 +#define BLOCK_RAW_DATA "bootblock_raw_data" uint16_t crc16_arg(uint8_t data, uint16_t previous_crc) { @@ -42,12 +42,11 @@ void header_format(FILE *fin, FILE *fout) size_t cnt = 0; fprintf(fout, "/* This file is auto-generated. Do not modify. */\n" - "#ifndef __CROS_EC_BOOTBLOCK_DATA_H\n" - "#define __CROS_EC_BOOTBLOCK_DATA_H\n" - "\n" - "#include <stdint.h>\n" - "\n" - ); + "#ifndef __CROS_EC_BOOTBLOCK_DATA_H\n" + "#define __CROS_EC_BOOTBLOCK_DATA_H\n" + "\n" + "#include <stdint.h>\n" + "\n"); fprintf(fout, "static const uint8_t %s[] __attribute__((aligned(4))) =\n" @@ -64,18 +63,19 @@ void header_format(FILE *fin, FILE *fout) if (cnt == 0) break; else if (cnt < BLOCK_SIZE) - memset(&data[cnt], 0xff, BLOCK_SIZE-cnt); + memset(&data[cnt], 0xff, BLOCK_SIZE - cnt); fprintf(fout, "\t/* Block %d (%ld) */\n", blk, cnt); fprintf(fout, "\t0xff, 0xfe, /* idle, start bit. */"); for (j = 0; j < sizeof(data); j++) { - fprintf(fout, "%s0x%02x,", - (j % 8) == 0 ? "\n\t" : " ", data[j]); + fprintf(fout, "%s0x%02x,", (j % 8) == 0 ? "\n\t" : " ", + data[j]); crc16 = crc16_arg(data[j], crc16); } fprintf(fout, "\n"); - fprintf(fout, "\t0x%02x, 0x%02x, 0xff," + fprintf(fout, + "\t0x%02x, 0x%02x, 0xff," " /* CRC, end bit, idle */\n", crc16 >> 8, crc16 & 0xff); } @@ -96,16 +96,14 @@ int main(int argc, char **argv) FILE *fout = NULL; const char short_opts[] = "i:ho:"; - const struct option long_opts[] = { - { "input", 1, NULL, 'i' }, - { "help", 0, NULL, 'h' }, - { "out", 1, NULL, 'o' }, - { NULL } - }; + const struct option long_opts[] = { { "input", 1, NULL, 'i' }, + { "help", 0, NULL, 'h' }, + { "out", 1, NULL, 'o' }, + { NULL } }; const char usage[] = "USAGE: %s [-i <input>] -o <output>\n"; - while ((nopt = getopt_long(argc, argv, short_opts, long_opts, - NULL)) != -1) { + while ((nopt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != + -1) { switch (nopt) { case 'i': /* -i or --input*/ input_name = optarg; diff --git a/util/gen_ipi_table.c b/util/gen_ipi_table.c index 07a3a39be0..6c1407973c 100644 --- a/util/gen_ipi_table.c +++ b/util/gen_ipi_table.c @@ -1,4 +1,4 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. +/* Copyright 2019 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -12,7 +12,7 @@ #include "board.h" -#define FPRINTF(format, args...) fprintf(fout, format, ## args) +#define FPRINTF(format, args...) fprintf(fout, format, ##args) int main(int argc, char **argv) { diff --git a/util/gen_touchpad_hash.c b/util/gen_touchpad_hash.c index e03c4638f3..98370038b7 100644 --- a/util/gen_touchpad_hash.c +++ b/util/gen_touchpad_hash.c @@ -1,4 +1,4 @@ -/* Copyright 2017 The Chromium OS Authors. All rights reserved. +/* Copyright 2017 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -35,7 +35,7 @@ static int hash_fw_blank(FILE *hashes) CONFIG_TOUCHPAD_VIRTUAL_SIZE / CONFIG_UPDATE_PDU_SIZE, SHA256_DIGEST_LENGTH); for (len = 0; len < CONFIG_TOUCHPAD_VIRTUAL_SIZE; - len += CONFIG_UPDATE_PDU_SIZE) { + len += CONFIG_UPDATE_PDU_SIZE) { print_hex(hashes, digest, sizeof(digest), 0); } fputs("};\n", hashes); @@ -93,7 +93,7 @@ static int hash_fw(FILE *tp_fw, FILE *hashes) if (len != CONFIG_TOUCHPAD_VIRTUAL_SIZE) { warnx("Incorrect TP FW size (%d vs %d)", len, - CONFIG_TOUCHPAD_VIRTUAL_SIZE); + CONFIG_TOUCHPAD_VIRTUAL_SIZE); return 1; } @@ -109,16 +109,14 @@ int main(int argc, char **argv) FILE *tp_fw = NULL; FILE *hashes; const char short_opt[] = "f:ho:"; - const struct option long_opts[] = { - { "firmware", 1, NULL, 'f' }, - { "help", 0, NULL, 'h' }, - { "out", 1, NULL, 'o' }, - { NULL } - }; + const struct option long_opts[] = { { "firmware", 1, NULL, 'f' }, + { "help", 0, NULL, 'h' }, + { "out", 1, NULL, 'o' }, + { NULL } }; const char usage[] = "USAGE: %s -f <touchpad FW> -o <output file>\n"; - while ((nopt = getopt_long(argc, argv, short_opt, - long_opts, NULL)) != -1) { + while ((nopt = getopt_long(argc, argv, short_opt, long_opts, NULL)) != + -1) { switch (nopt) { case 'f': /* -f or --firmware */ tp_fw_name = optarg; diff --git a/util/genvif.c b/util/genvif.c index 2b1ba8c494..543577cb11 100644 --- a/util/genvif.c +++ b/util/genvif.c @@ -1,4 +1,4 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. +/* Copyright 2020 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -25,14 +25,14 @@ #include "genvif.h" -#define VIF_APP_VENDOR_VALUE "Google" -#define VIF_APP_NAME_VALUE "EC GENVIF" -#define VIF_APP_VERSION_VALUE "3.2.3.0" -#define VENDOR_NAME_VALUE "Google" +#define VIF_APP_VENDOR_VALUE "Google" +#define VIF_APP_NAME_VALUE "EC GENVIF" +#define VIF_APP_VERSION_VALUE "3.2.3.0" +#define VENDOR_NAME_VALUE "Google" -#define DEFAULT_MISSING_TID 0xFFFF -#define DEFAULT_MISSING_PID 0xFFFF -#define DEFAULT_MISSING_BCD_DEV 0x0000 +#define DEFAULT_MISSING_TID 0xFFFF +#define DEFAULT_MISSING_PID 0xFFFF +#define DEFAULT_MISSING_BCD_DEV 0x0000 /* * XML namespace for VIF as of VifEditorRelease 3.2.3.0 @@ -47,11 +47,7 @@ struct vif_t vif; /* * local type to make decisions on the output for Source, Sink and DRP */ -enum dtype { - SRC = 0, - SNK, - DRP -}; +enum dtype { SRC = 0, SNK, DRP }; enum ptype { PORT_CONSUMER_ONLY = 0, @@ -309,14 +305,10 @@ const char *vif_component_name[] = { BUILD_ASSERT(ARRAY_SIZE(vif_component_name) == Component_Indexes); const char *vif_component_snk_pdo_name[] = { - NAME_INIT(Snk_PDO_Supply_Type), - NAME_INIT(Snk_PDO_APDO_Type), - NAME_INIT(Snk_PDO_Voltage), - NAME_INIT(Snk_PDO_PDP_Rating), - NAME_INIT(Snk_PDO_Op_Power), - NAME_INIT(Snk_PDO_Min_Voltage), - NAME_INIT(Snk_PDO_Max_Voltage), - NAME_INIT(Snk_PDO_Op_Current), + NAME_INIT(Snk_PDO_Supply_Type), NAME_INIT(Snk_PDO_APDO_Type), + NAME_INIT(Snk_PDO_Voltage), NAME_INIT(Snk_PDO_PDP_Rating), + NAME_INIT(Snk_PDO_Op_Power), NAME_INIT(Snk_PDO_Min_Voltage), + NAME_INIT(Snk_PDO_Max_Voltage), NAME_INIT(Snk_PDO_Op_Current), }; BUILD_ASSERT(ARRAY_SIZE(vif_component_snk_pdo_name) == Snk_PDO_Indexes); @@ -343,7 +335,7 @@ const char *vif_component_sop_svid_mode_name[] = { NAME_INIT(SVID_Mode_Recog_Value_SOP), }; BUILD_ASSERT(ARRAY_SIZE(vif_component_sop_svid_mode_name) == - SopSVID_Mode_Indexes); + SopSVID_Mode_Indexes); const char *vif_component_sop_svid_name[] = { NAME_INIT(SVID_SOP), @@ -393,7 +385,7 @@ const char *vif_product_pcie_endpoint_name[] = { NAME_INIT(USB4_PCIe_Endpoint_Class_Code), }; BUILD_ASSERT(ARRAY_SIZE(vif_product_pcie_endpoint_name) == - PCIe_Endpoint_Indexes); + PCIe_Endpoint_Indexes); const char *vif_product_usb4_router_name[] = { NAME_INIT(USB4_Router_ID), @@ -414,7 +406,6 @@ const char *vif_product_usb4_router_name[] = { }; BUILD_ASSERT(ARRAY_SIZE(vif_product_usb4_router_name) == USB4_Router_Indexes); - static bool streq(const char *str1, const char *str2) { if (str1 == NULL && str2 == NULL) @@ -479,8 +470,8 @@ static bool get_vif_field_number(struct vif_field_t *vif_field, int *value) return rv; } -__maybe_unused -static int get_vif_number(struct vif_field_t *vif_field, int default_value) +__maybe_unused static int get_vif_number(struct vif_field_t *vif_field, + int default_value) { int ret_value; @@ -528,8 +519,8 @@ static bool get_vif_bool(struct vif_field_t *vif_field, bool default_value) } /** String **/ -__maybe_unused -static bool get_vif_field_tag_str(struct vif_field_t *vif_field, char **value) +__maybe_unused static bool get_vif_field_tag_str(struct vif_field_t *vif_field, + char **value) { if (vif_field->tag_value == NULL) return false; @@ -537,8 +528,8 @@ static bool get_vif_field_tag_str(struct vif_field_t *vif_field, char **value) *value = vif_field->tag_value; return true; } -__maybe_unused -static bool get_vif_field_str_str(struct vif_field_t *vif_field, char **value) +__maybe_unused static bool get_vif_field_str_str(struct vif_field_t *vif_field, + char **value) { if (vif_field->str_value == NULL) return false; @@ -550,7 +541,6 @@ static bool get_vif_field_str_str(struct vif_field_t *vif_field, char **value) * VIF Structure Override Value Retrieve Functions *****************************************************************************/ - /***************************************************************************** * Generic Helper Functions */ @@ -561,9 +551,8 @@ static bool is_src(void) /* Determine if we are DRP, SRC or SNK */ was_overridden = get_vif_field_tag_number( - &vif.Component[component_index] - .vif_field[Type_C_State_Machine], - &override_value); + &vif.Component[component_index].vif_field[Type_C_State_Machine], + &override_value); if (was_overridden) { switch (override_value) { case SRC: @@ -578,15 +567,14 @@ static bool is_src(void) } if (!was_overridden) { was_overridden = get_vif_field_tag_number( - &vif.Component[component_index] - .vif_field[PD_Port_Type], - &override_value); + &vif.Component[component_index].vif_field[PD_Port_Type], + &override_value); if (was_overridden) { switch (override_value) { - case PORT_PROVIDER_ONLY: /* SRC */ - case PORT_DRP: /* DRP */ + case PORT_PROVIDER_ONLY: /* SRC */ + case PORT_DRP: /* DRP */ return true; - case PORT_CONSUMER_ONLY: /* SNK */ + case PORT_CONSUMER_ONLY: /* SNK */ return false; default: was_overridden = false; @@ -602,9 +590,8 @@ static bool is_snk(void) /* Determine if we are DRP, SRC or SNK */ was_overridden = get_vif_field_tag_number( - &vif.Component[component_index] - .vif_field[Type_C_State_Machine], - &override_value); + &vif.Component[component_index].vif_field[Type_C_State_Machine], + &override_value); if (was_overridden) { switch (override_value) { case SNK: @@ -619,15 +606,14 @@ static bool is_snk(void) } if (!was_overridden) { was_overridden = get_vif_field_tag_number( - &vif.Component[component_index] - .vif_field[PD_Port_Type], - &override_value); + &vif.Component[component_index].vif_field[PD_Port_Type], + &override_value); if (was_overridden) { switch (override_value) { - case PORT_CONSUMER_ONLY: /* SNK */ - case PORT_DRP: /* DRP */ + case PORT_CONSUMER_ONLY: /* SNK */ + case PORT_DRP: /* DRP */ return true; - case PORT_PROVIDER_ONLY: /* SRC */ + case PORT_PROVIDER_ONLY: /* SRC */ return false; default: was_overridden = false; @@ -643,9 +629,8 @@ static bool is_drp(void) /* Determine if we are DRP, SRC or SNK */ was_overridden = get_vif_field_tag_number( - &vif.Component[component_index] - .vif_field[Type_C_State_Machine], - &override_value); + &vif.Component[component_index].vif_field[Type_C_State_Machine], + &override_value); if (was_overridden) { switch (override_value) { case DRP: @@ -660,16 +645,15 @@ static bool is_drp(void) } if (!was_overridden) { was_overridden = get_vif_field_tag_number( - &vif.Component[component_index] - .vif_field[PD_Port_Type], - &override_value); + &vif.Component[component_index].vif_field[PD_Port_Type], + &override_value); if (was_overridden) { switch (override_value) { - case PORT_DRP: /* DRP */ + case PORT_DRP: /* DRP */ return true; - case PORT_CONSUMER_ONLY: /* SNK */ + case PORT_CONSUMER_ONLY: /* SNK */ return false; - case PORT_PROVIDER_ONLY: /* SRC */ + case PORT_PROVIDER_ONLY: /* SRC */ default: was_overridden = false; } @@ -683,80 +667,79 @@ static bool is_drp(void) static bool can_act_as_device(void) { return get_vif_bool(&vif.Component[component_index] - .vif_field[Type_C_Can_Act_As_Device], + .vif_field[Type_C_Can_Act_As_Device], #if defined(USB_DEV_CLASS) && defined(USB_CLASS_BILLBOARD) USB_DEV_CLASS == USB_CLASS_BILLBOARD #else false #endif - ); + ); } static bool can_act_as_host(void) { return get_vif_bool(&vif.Component[component_index] - .vif_field[Type_C_Can_Act_As_Host], + .vif_field[Type_C_Can_Act_As_Host], (!(IS_ENABLED(CONFIG_USB_CTVPD) || IS_ENABLED(CONFIG_USB_VPD)))); } static bool is_usb4_supported(void) { - return get_vif_bool(&vif.Component[component_index] - .vif_field[USB4_Supported], - IS_ENABLED(CONFIG_USB_PD_USB4)); + return get_vif_bool( + &vif.Component[component_index].vif_field[USB4_Supported], + IS_ENABLED(CONFIG_USB_PD_USB4)); } static bool is_usb4_tbt3_compatible(void) { - return get_vif_bool(&vif.Component[component_index] - .vif_field[USB4_TBT3_Compatibility_Supported], - IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE)); + return get_vif_bool( + &vif.Component[component_index] + .vif_field[USB4_TBT3_Compatibility_Supported], + IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE)); } static bool is_usb4_pcie_tunneling_supported(void) { return get_vif_bool(&vif.Component[component_index] - .vif_field[USB4_PCIe_Tunneling_Supported], + .vif_field[USB4_PCIe_Tunneling_Supported], IS_ENABLED(CONFIG_USB_PD_PCIE_TUNNELING)); } static bool is_usb_pd_supported(void) { - return get_vif_bool(&vif.Component[component_index] - .vif_field[USB_PD_Support], - (is_usb4_supported() || - IS_ENABLED(CONFIG_USB_PRL_SM) || - IS_ENABLED(CONFIG_USB_POWER_DELIVERY))); + return get_vif_bool( + &vif.Component[component_index].vif_field[USB_PD_Support], + (is_usb4_supported() || IS_ENABLED(CONFIG_USB_PRL_SM) || + IS_ENABLED(CONFIG_USB_POWER_DELIVERY))); } static bool is_usb_comms_capable(void) { - return get_vif_bool(&vif.Component[component_index] - .vif_field[USB_Comms_Capable], - is_usb4_supported() || - (!(IS_ENABLED(CONFIG_USB_VPD) || - IS_ENABLED(CONFIG_USB_CTVPD)))); + return get_vif_bool( + &vif.Component[component_index].vif_field[USB_Comms_Capable], + is_usb4_supported() || (!(IS_ENABLED(CONFIG_USB_VPD) || + IS_ENABLED(CONFIG_USB_CTVPD)))); } static bool is_alt_mode_controller(void) { return get_vif_bool(&vif.Component[component_index] - .vif_field[Type_C_Is_Alt_Mode_Controller], + .vif_field[Type_C_Is_Alt_Mode_Controller], IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)); } static bool is_alt_mode_adapter(void) { return get_vif_bool(&vif.Component[component_index] - .vif_field[Type_C_Is_Alt_Mode_Adapter], + .vif_field[Type_C_Is_Alt_Mode_Adapter], IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)); } static bool does_respond_to_discov_sop_ufp(void) { return get_vif_bool(&vif.Component[component_index] - .vif_field[Responds_To_Discov_SOP_UFP], + .vif_field[Responds_To_Discov_SOP_UFP], (is_usb4_supported() || IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE))); } @@ -764,7 +747,7 @@ static bool does_respond_to_discov_sop_ufp(void) static bool does_respond_to_discov_sop_dfp(void) { return get_vif_bool(&vif.Component[component_index] - .vif_field[Responds_To_Discov_SOP_DFP], + .vif_field[Responds_To_Discov_SOP_DFP], (is_usb4_supported() || IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE))); } @@ -772,23 +755,21 @@ static bool does_respond_to_discov_sop_dfp(void) static bool does_support_device_usb_data(void) { return get_vif_bool(&vif.Component[component_index] - .vif_field[Device_Supports_USB_Data], - (is_usb4_supported() || - can_act_as_device())); + .vif_field[Device_Supports_USB_Data], + (is_usb4_supported() || can_act_as_device())); } static bool does_support_host_usb_data(void) { int type_c_state_machine; - if (!get_vif_field_tag_number( - &vif.Component[component_index] - .vif_field[Type_C_State_Machine], - &type_c_state_machine)) + if (!get_vif_field_tag_number(&vif.Component[component_index] + .vif_field[Type_C_State_Machine], + &type_c_state_machine)) return false; return get_vif_bool(&vif.Component[component_index] - .vif_field[Host_Supports_USB_Data], + .vif_field[Host_Supports_USB_Data], can_act_as_host()); } @@ -831,7 +812,6 @@ static bool vif_fields_present(const struct vif_field_t *vif_fields, int count) * Generic Helper Functions *****************************************************************************/ - /***************************************************************************** * VIF XML Output Functions */ @@ -874,9 +854,8 @@ static void vif_out_comment(FILE *vif_file, int level, const char *fmt, ...) fprintf(vif_file, "-->\r\n"); } -static const char vif_separator[] = - ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;" - ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"; +static const char vif_separator[] = ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;" + ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"; static void vif_out_field(FILE *vif_file, int level, const struct vif_field_t *vif_field) @@ -901,8 +880,7 @@ static void vif_out_field(FILE *vif_file, int level, fprintf(vif_file, " value=\"%s\"", vif_field->tag_value); if (vif_field->str_value) - fprintf(vif_file, ">%s</%s>\r\n", - vif_field->str_value, + fprintf(vif_file, ">%s</%s>\r\n", vif_field->str_value, vif_field->name); else fprintf(vif_file, " />\r\n"); @@ -910,8 +888,8 @@ static void vif_out_field(FILE *vif_file, int level, } static void vif_out_fields_range(FILE *vif_file, int level, - const struct vif_field_t *vif_fields, - int start, int count) + const struct vif_field_t *vif_fields, + int start, int count) { int index; @@ -925,10 +903,8 @@ static void vif_out_fields(FILE *vif_file, int level, vif_out_fields_range(vif_file, level, vif_fields, 0, count); } - - -static void vif_output_vif_component_cable_svid_mode_list(FILE *vif_file, - const struct vif_cableSVIDList_t *svid_list, int level) +static void vif_output_vif_component_cable_svid_mode_list( + FILE *vif_file, const struct vif_cableSVIDList_t *svid_list, int level) { int index; @@ -939,22 +915,22 @@ static void vif_output_vif_component_cable_svid_mode_list(FILE *vif_file, vif_out_start(vif_file, level++, "CableSVIDModeList"); for (index = 0; index < MAX_NUM_CABLE_SVID_MODES; ++index) { const struct vif_cableSVIDModeList_t *mode_list = - &svid_list->CableSVIDModeList[index]; + &svid_list->CableSVIDModeList[index]; if (!vif_fields_present(mode_list->vif_field, CableSVID_Mode_Indexes)) break; vif_out_start(vif_file, level++, "SOPSVIDMode"); - vif_out_fields(vif_file, level, - mode_list->vif_field, CableSVID_Mode_Indexes); + vif_out_fields(vif_file, level, mode_list->vif_field, + CableSVID_Mode_Indexes); vif_out_end(vif_file, --level, "SOPSVIDMode"); } vif_out_end(vif_file, --level, "CableSVIDModeList"); } -static void vif_output_vif_component_cable_svid_list(FILE *vif_file, - const struct vif_Component_t *component, int level) +static void vif_output_vif_component_cable_svid_list( + FILE *vif_file, const struct vif_Component_t *component, int level) { int index; @@ -965,24 +941,24 @@ static void vif_output_vif_component_cable_svid_list(FILE *vif_file, vif_out_start(vif_file, level++, "CableSVIDList"); for (index = 0; index < MAX_NUM_CABLE_SVIDS; ++index) { const struct vif_cableSVIDList_t *svid_list = - &component->CableSVIDList[index]; + &component->CableSVIDList[index]; if (!vif_fields_present(svid_list->vif_field, CableSVID_Indexes)) break; vif_out_start(vif_file, level++, "CableSVID"); - vif_out_fields(vif_file, level, - svid_list->vif_field, CableSVID_Indexes); + vif_out_fields(vif_file, level, svid_list->vif_field, + CableSVID_Indexes); vif_output_vif_component_cable_svid_mode_list(vif_file, - svid_list, level); + svid_list, level); vif_out_end(vif_file, --level, "CableSVID"); } vif_out_end(vif_file, --level, "CableSVIDList"); } -static void vif_output_vif_component_sop_svid_mode_list(FILE *vif_file, - const struct vif_sopSVIDList_t *svid_list, int level) +static void vif_output_vif_component_sop_svid_mode_list( + FILE *vif_file, const struct vif_sopSVIDList_t *svid_list, int level) { int index; @@ -993,22 +969,22 @@ static void vif_output_vif_component_sop_svid_mode_list(FILE *vif_file, vif_out_start(vif_file, level++, "SOPSVIDModeList"); for (index = 0; index < MAX_NUM_SOP_SVID_MODES; ++index) { const struct vif_sopSVIDModeList_t *mode_list = - &svid_list->SOPSVIDModeList[index]; + &svid_list->SOPSVIDModeList[index]; if (!vif_fields_present(mode_list->vif_field, SopSVID_Mode_Indexes)) break; vif_out_start(vif_file, level++, "SOPSVIDMode"); - vif_out_fields(vif_file, level, - mode_list->vif_field, SopSVID_Mode_Indexes); + vif_out_fields(vif_file, level, mode_list->vif_field, + SopSVID_Mode_Indexes); vif_out_end(vif_file, --level, "SOPSVIDMode"); } vif_out_end(vif_file, --level, "SOPSVIDModeList"); } -static void vif_output_vif_component_sop_svid_list(FILE *vif_file, - const struct vif_Component_t *component, int level) +static void vif_output_vif_component_sop_svid_list( + FILE *vif_file, const struct vif_Component_t *component, int level) { int index; @@ -1019,24 +995,23 @@ static void vif_output_vif_component_sop_svid_list(FILE *vif_file, vif_out_start(vif_file, level++, "SOPSVIDList"); for (index = 0; index < MAX_NUM_SOP_SVIDS; ++index) { const struct vif_sopSVIDList_t *svid_list = - &component->SOPSVIDList[index]; + &component->SOPSVIDList[index]; - if (!vif_fields_present(svid_list->vif_field, - SopSVID_Indexes)) + if (!vif_fields_present(svid_list->vif_field, SopSVID_Indexes)) break; vif_out_start(vif_file, level++, "SOPSVID"); - vif_out_fields(vif_file, level, - svid_list->vif_field, SopSVID_Indexes); - vif_output_vif_component_sop_svid_mode_list(vif_file, - svid_list, level); + vif_out_fields(vif_file, level, svid_list->vif_field, + SopSVID_Indexes); + vif_output_vif_component_sop_svid_mode_list(vif_file, svid_list, + level); vif_out_end(vif_file, --level, "SOPSVID"); } vif_out_end(vif_file, --level, "SOPSVIDList"); } -static void vif_output_vif_component_snk_pdo_list(FILE *vif_file, - const struct vif_Component_t *component, int level) +static void vif_output_vif_component_snk_pdo_list( + FILE *vif_file, const struct vif_Component_t *component, int level) { int index; @@ -1048,23 +1023,22 @@ static void vif_output_vif_component_snk_pdo_list(FILE *vif_file, vif_out_start(vif_file, level++, "SnkPdoList"); for (index = 0; index < MAX_NUM_SNK_PDOS; ++index) { const struct vif_snkPdoList_t *pdo_list = - &component->SnkPdoList[index]; + &component->SnkPdoList[index]; - if (!vif_fields_present(pdo_list->vif_field, - Snk_PDO_Indexes)) + if (!vif_fields_present(pdo_list->vif_field, Snk_PDO_Indexes)) break; vif_out_start(vif_file, level++, "SnkPDO"); vif_out_comment(vif_file, level, "Sink PDO %d", index + 1); - vif_out_fields(vif_file, level, - pdo_list->vif_field, Snk_PDO_Indexes); + vif_out_fields(vif_file, level, pdo_list->vif_field, + Snk_PDO_Indexes); vif_out_end(vif_file, --level, "SnkPDO"); } vif_out_end(vif_file, --level, "SnkPdoList"); } -static void vif_output_vif_component_src_pdo_list(FILE *vif_file, - const struct vif_Component_t *component, int level) +static void vif_output_vif_component_src_pdo_list( + FILE *vif_file, const struct vif_Component_t *component, int level) { int index; @@ -1076,23 +1050,22 @@ static void vif_output_vif_component_src_pdo_list(FILE *vif_file, vif_out_start(vif_file, level++, "SrcPdoList"); for (index = 0; index < MAX_NUM_SRC_PDOS; ++index) { const struct vif_srcPdoList_t *pdo_list = - &component->SrcPdoList[index]; + &component->SrcPdoList[index]; - if (!vif_fields_present(pdo_list->vif_field, - Src_PDO_Indexes)) + if (!vif_fields_present(pdo_list->vif_field, Src_PDO_Indexes)) break; vif_out_start(vif_file, level++, "SrcPDO"); vif_out_comment(vif_file, level, "Source PDO %d", index + 1); - vif_out_fields(vif_file, level, - pdo_list->vif_field, Src_PDO_Indexes); + vif_out_fields(vif_file, level, pdo_list->vif_field, + Src_PDO_Indexes); vif_out_end(vif_file, --level, "SrcPDO"); } vif_out_end(vif_file, --level, "SrcPdoList"); } -static void vif_output_vif_component(FILE *vif_file, - const struct vif_t *vif, int level) +static void vif_output_vif_component(FILE *vif_file, const struct vif_t *vif, + int level) { int index; @@ -1106,26 +1079,23 @@ static void vif_output_vif_component(FILE *vif_file, vif_out_start(vif_file, level++, "Component"); vif_out_comment(vif_file, level, "Component %d", index); - vif_out_fields(vif_file, level, - component->vif_field, Component_Indexes); - vif_output_vif_component_snk_pdo_list(vif_file, - component, - level); - vif_output_vif_component_src_pdo_list(vif_file, - component, - level); - vif_output_vif_component_sop_svid_list(vif_file, - component, - level); - vif_output_vif_component_cable_svid_list(vif_file, - component, - level); + vif_out_fields(vif_file, level, component->vif_field, + Component_Indexes); + vif_output_vif_component_snk_pdo_list(vif_file, component, + level); + vif_output_vif_component_src_pdo_list(vif_file, component, + level); + vif_output_vif_component_sop_svid_list(vif_file, component, + level); + vif_output_vif_component_cable_svid_list(vif_file, component, + level); vif_out_end(vif_file, --level, "Component"); } } -static void vif_output_vif_product_usb4router_endpoint(FILE *vif_file, - const struct vif_Usb4RouterListType_t *router, int level) +static void vif_output_vif_product_usb4router_endpoint( + FILE *vif_file, const struct vif_Usb4RouterListType_t *router, + int level) { int index; @@ -1136,22 +1106,23 @@ static void vif_output_vif_product_usb4router_endpoint(FILE *vif_file, vif_out_start(vif_file, level++, "PCIeEndpointList"); for (index = 0; index < MAX_NUM_PCIE_ENDPOINTS; ++index) { const struct vif_PCIeEndpointListType_t *endpont = - &router->PCIeEndpointList[index]; + &router->PCIeEndpointList[index]; if (!vif_fields_present(endpont->vif_field, PCIe_Endpoint_Indexes)) break; vif_out_start(vif_file, level++, "PCIeEndpoint"); - vif_out_fields(vif_file, level, - endpont->vif_field, PCIe_Endpoint_Indexes); + vif_out_fields(vif_file, level, endpont->vif_field, + PCIe_Endpoint_Indexes); vif_out_end(vif_file, --level, "PCIeEndpoint"); } vif_out_end(vif_file, --level, "PCIeEndpointList"); } static void vif_output_vif_product_usb4router(FILE *vif_file, - const struct vif_t *vif, int level) + const struct vif_t *vif, + int level) { int index; @@ -1163,34 +1134,32 @@ static void vif_output_vif_product_usb4router(FILE *vif_file, vif_out_start(vif_file, level++, "USB4RouterList"); for (index = 0; index < MAX_NUM_USB4_ROUTERS; ++index) { const struct vif_Usb4RouterListType_t *router = - &vif->Product.USB4RouterList[index]; + &vif->Product.USB4RouterList[index]; - if (!vif_fields_present(router->vif_field, - USB4_Router_Indexes)) + if (!vif_fields_present(router->vif_field, USB4_Router_Indexes)) break; vif_out_start(vif_file, level++, "Usb4Router"); vif_out_comment(vif_file, level, "USB4 Router %d", index); - vif_out_fields(vif_file, level, - router->vif_field, USB4_Router_Indexes); - vif_output_vif_product_usb4router_endpoint(vif_file, - router, + vif_out_fields(vif_file, level, router->vif_field, + USB4_Router_Indexes); + vif_output_vif_product_usb4router_endpoint(vif_file, router, level); vif_out_end(vif_file, --level, "Usb4Router"); } vif_out_end(vif_file, --level, "USB4RouterList"); } -static void vif_output_vif_product(FILE *vif_file, - const struct vif_t *vif, int level) +static void vif_output_vif_product(FILE *vif_file, const struct vif_t *vif, + int level) { if (!vif_fields_present(vif->Product.vif_field, Product_Indexes)) return; vif_out_start(vif_file, level++, "Product"); vif_out_comment(vif_file, level, "Product Level Content:"); - vif_out_fields(vif_file, level, - vif->Product.vif_field, Product_Indexes); + vif_out_fields(vif_file, level, vif->Product.vif_field, + Product_Indexes); vif_output_vif_product_usb4router(vif_file, vif, level); vif_out_end(vif_file, --level, "Product"); } @@ -1203,8 +1172,8 @@ static void vif_output_vif_xml(FILE *vif_file, struct vif_t *vif, int level) vif_out_fields(vif_file, level, vif->vif_app_field, VIF_App_Indexes); vif_out_end(vif_file, --level, "VIF_App"); - vif_out_fields_range(vif_file, level, - vif->vif_field, Vendor_Name, VIF_Indexes); + vif_out_fields_range(vif_file, level, vif->vif_field, Vendor_Name, + VIF_Indexes); } static int vif_output_xml(const char *name, struct vif_t *vif) @@ -1220,12 +1189,13 @@ static int vif_output_xml(const char *name, struct vif_t *vif) } vif_out_str(vif_file, level, - "<?xml version=\"1.0\" encoding=\"utf-8\"?>"); - vif_out_start(vif_file, level++, + "<?xml version=\"1.0\" encoding=\"utf-8\"?>"); + vif_out_start( + vif_file, level++, "VIF " - "xmlns:opt=\"http://usb.org/VendorInfoFileOptionalContent.xsd\" " - "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " - "xmlns:vif=\"http://usb.org/VendorInfoFile.xsd\""); + "xmlns:opt=\"http://usb.org/VendorInfoFileOptionalContent.xsd\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + "xmlns:vif=\"http://usb.org/VendorInfoFile.xsd\""); vif_output_vif_xml(vif_file, vif, level); vif_output_vif_product(vif_file, vif, level); @@ -1240,7 +1210,6 @@ static int vif_output_xml(const char *name, struct vif_t *vif) * VIF XML Output Functions *****************************************************************************/ - /***************************************************************************** * VIF Structure Override from XML file functions */ @@ -1298,11 +1267,9 @@ static void ov_close(void) override_file = NULL; } - static void set_override_vif_field(struct vif_field_t *vif_field, - const char *name, - const char *tag_value, - const char *str_value) + const char *name, const char *tag_value, + const char *str_value) { char *ptr; @@ -1317,12 +1284,12 @@ static void set_override_vif_field(struct vif_field_t *vif_field, vif_field->name = name; if (tag_value && tag_value[0]) { - ptr = malloc(strlen(tag_value)+1); + ptr = malloc(strlen(tag_value) + 1); strcpy(ptr, tag_value); vif_field->tag_value = ptr; } if (str_value && str_value[0]) { - ptr = malloc(strlen(str_value)+1); + ptr = malloc(strlen(str_value) + 1); strcpy(ptr, str_value); vif_field->str_value = ptr; } @@ -1346,10 +1313,9 @@ static void ignore_comment_tag(void) int ch; while ((ch = ov_getc()) != EOF) { - if (ch == '-') { + if (ch == '-') { ovpre_getc(2); - if (ovpre_peek(0) == '-' && - ovpre_peek(1) == '>') { + if (ovpre_peek(0) == '-' && ovpre_peek(1) == '>') { /* --> */ ovpre_drop(2); break; @@ -1388,9 +1354,7 @@ static void ignore_to_end_tag(void) * * <tag><nested value=x /></tag> next call returns <nested> */ -static bool get_next_tag(char *name, - char *tag_value, - char *str_value) +static bool get_next_tag(char *name, char *tag_value, char *str_value) { int ch; int name_index = 0; @@ -1422,8 +1386,7 @@ static bool get_next_tag(char *name, * Ignore XML comment <!-- ... --> */ ovpre_getc(3); - if (ovpre_peek(0) == '!' && - ovpre_peek(1) == '-' && + if (ovpre_peek(0) == '!' && ovpre_peek(1) == '-' && ovpre_peek(2) == '-') { ovpre_drop(3); ignore_comment_tag(); @@ -1444,8 +1407,8 @@ static bool get_next_tag(char *name, /* Looking for a tag name */ while ((ch = ov_getc()) != EOF) { - if (ch == '_' || ch == ':' || - isalpha(ch) || isdigit(ch)) { + if (ch == '_' || ch == ':' || isalpha(ch) || + isdigit(ch)) { name[name_index++] = ch; } else { ov_pushback(ch); @@ -1459,12 +1422,9 @@ static bool get_next_tag(char *name, /* See if there is a tag_string value */ ovpre_getc(7); - if (ovpre_peek(0) == 'v' && - ovpre_peek(1) == 'a' && - ovpre_peek(2) == 'l' && - ovpre_peek(3) == 'u' && - ovpre_peek(4) == 'e' && - ovpre_peek(5) == '=' && + if (ovpre_peek(0) == 'v' && ovpre_peek(1) == 'a' && + ovpre_peek(2) == 'l' && ovpre_peek(3) == 'u' && + ovpre_peek(4) == 'e' && ovpre_peek(5) == '=' && ovpre_peek(6) == '"') { ovpre_drop(7); while ((ch = ov_getc()) != EOF) { @@ -1480,8 +1440,7 @@ static bool get_next_tag(char *name, /* /> ending the tag will conclude this tag */ ovpre_getc(2); - if (ovpre_peek(0) == '/' && - ovpre_peek(1) == '>') { + if (ovpre_peek(0) == '/' && ovpre_peek(1) == '>') { ovpre_drop(2); return true; } @@ -1510,7 +1469,7 @@ static bool get_next_tag(char *name, } static void override_vif_product_pcie_endpoint_field( - struct vif_PCIeEndpointListType_t *endpoint) + struct vif_PCIeEndpointListType_t *endpoint) { char name[80]; char tag_value[80]; @@ -1528,17 +1487,17 @@ static void override_vif_product_pcie_endpoint_field( if (i != PCIe_Endpoint_Indexes) set_override_vif_field( &endpoint->vif_field[i], - vif_product_pcie_endpoint_name[i], - tag_value, + vif_product_pcie_endpoint_name[i], tag_value, str_value); else fprintf(stderr, "VIF/Component/Usb4Router/PCIeEndpoint:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } static void override_vif_product_pcie_endpoint_list_field( - struct vif_PCIeEndpointListType_t *endpoint_list) + struct vif_PCIeEndpointListType_t *endpoint_list) { char name[80]; char tag_value[80]; @@ -1551,16 +1510,17 @@ static void override_vif_product_pcie_endpoint_list_field( if (is_start_tag(name, "PCIeEndpoint")) override_vif_product_pcie_endpoint_field( - &endpoint_list[endpoint_index++]); + &endpoint_list[endpoint_index++]); else fprintf(stderr, "VIF/Product/Usb4Router/PCIeEndpointList:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } -static void override_vif_product_usb4router_fields( - struct vif_Usb4RouterListType_t *router) +static void +override_vif_product_usb4router_fields(struct vif_Usb4RouterListType_t *router) { char name[80]; char tag_value[80]; @@ -1585,17 +1545,17 @@ static void override_vif_product_usb4router_fields( set_override_vif_field( &router->vif_field[i], vif_product_usb4_router_name[i], - tag_value, - str_value); + tag_value, str_value); else fprintf(stderr, "VIF/Component/Usb4Router:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } } static void override_vif_product_usb4routerlist_fields( - struct vif_Usb4RouterListType_t *router_list) + struct vif_Usb4RouterListType_t *router_list) { char name[80]; char tag_value[80]; @@ -1612,7 +1572,8 @@ static void override_vif_product_usb4routerlist_fields( else fprintf(stderr, "VIF/Product/USB4RouterList:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } @@ -1641,19 +1602,19 @@ static void override_vif_product_fields(struct vif_Product_t *vif_product) if (i != Product_Indexes) set_override_vif_field( &vif_product->vif_field[i], - vif_product_name[i], - tag_value, + vif_product_name[i], tag_value, str_value); else fprintf(stderr, "VIF/Product:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } } -static void override_vif_component_src_pdo_fields( - struct vif_srcPdoList_t *vif_src_pdo) +static void +override_vif_component_src_pdo_fields(struct vif_srcPdoList_t *vif_src_pdo) { char name[80]; char tag_value[80]; @@ -1669,19 +1630,18 @@ static void override_vif_component_src_pdo_fields( if (streq(name, vif_component_src_pdo_name[i])) break; if (i != Src_PDO_Indexes) - set_override_vif_field( - &vif_src_pdo->vif_field[i], - vif_component_src_pdo_name[i], - tag_value, - str_value); + set_override_vif_field(&vif_src_pdo->vif_field[i], + vif_component_src_pdo_name[i], + tag_value, str_value); else fprintf(stderr, "VIF/Component/SrcPdo:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } static void override_vif_component_src_pdo_list_fields( - struct vif_srcPdoList_t *vif_src_pdo_list) + struct vif_srcPdoList_t *vif_src_pdo_list) { char name[80]; char tag_value[80]; @@ -1698,12 +1658,13 @@ static void override_vif_component_src_pdo_list_fields( else fprintf(stderr, "VIF/Component/SrcPdoList:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } -static void override_vif_component_snk_pdo_fields( - struct vif_snkPdoList_t *vif_snk_pdo) +static void +override_vif_component_snk_pdo_fields(struct vif_snkPdoList_t *vif_snk_pdo) { char name[80]; char tag_value[80]; @@ -1719,19 +1680,18 @@ static void override_vif_component_snk_pdo_fields( if (streq(name, vif_component_snk_pdo_name[i])) break; if (i != Snk_PDO_Indexes) - set_override_vif_field( - &vif_snk_pdo->vif_field[i], - vif_component_snk_pdo_name[i], - tag_value, - str_value); + set_override_vif_field(&vif_snk_pdo->vif_field[i], + vif_component_snk_pdo_name[i], + tag_value, str_value); else fprintf(stderr, "VIF/Component/SnkPdo:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } static void override_vif_component_snk_pdo_list_fields( - struct vif_snkPdoList_t *vif_snk_pdo_list) + struct vif_snkPdoList_t *vif_snk_pdo_list) { char name[80]; char tag_value[80]; @@ -1748,12 +1708,13 @@ static void override_vif_component_snk_pdo_list_fields( else fprintf(stderr, "VIF/Component/SnkPdoList:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } static void override_vif_component_sop_svid_mode_fields( - struct vif_sopSVIDModeList_t *svid_mode) + struct vif_sopSVIDModeList_t *svid_mode) { char name[80]; char tag_value[80]; @@ -1771,17 +1732,17 @@ static void override_vif_component_sop_svid_mode_fields( if (i != SopSVID_Indexes) set_override_vif_field( &svid_mode->vif_field[i], - vif_component_sop_svid_mode_name[i], - tag_value, + vif_component_sop_svid_mode_name[i], tag_value, str_value); else fprintf(stderr, "VIF/Component/SOPSVIDMode:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } static void override_vif_component_sop_svid_mode_list_fields( - struct vif_sopSVIDModeList_t *svid_mode_list) + struct vif_sopSVIDModeList_t *svid_mode_list) { char name[80]; char tag_value[80]; @@ -1798,12 +1759,13 @@ static void override_vif_component_sop_svid_mode_list_fields( else fprintf(stderr, "VIF/Component/SOPSVIDModeList:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } -static void override_vif_component_sop_svid_fields( - struct vif_sopSVIDList_t *vif_sop_svid) +static void +override_vif_component_sop_svid_fields(struct vif_sopSVIDList_t *vif_sop_svid) { char name[80]; char tag_value[80]; @@ -1820,24 +1782,23 @@ static void override_vif_component_sop_svid_fields( int i; for (i = 0; i < SopSVID_Indexes; i++) - if (streq(name, - vif_component_sop_svid_name[i])) + if (streq(name, vif_component_sop_svid_name[i])) break; if (i != SopSVID_Indexes) set_override_vif_field( &vif_sop_svid->vif_field[i], vif_component_sop_svid_name[i], - tag_value, - str_value); + tag_value, str_value); else fprintf(stderr, "VIF/Component/SOPSVID:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } } static void override_vif_component_sop_svid_list_fields( - struct vif_sopSVIDList_t *vif_sop_svid_list) + struct vif_sopSVIDList_t *vif_sop_svid_list) { char name[80]; char tag_value[80]; @@ -1854,12 +1815,13 @@ static void override_vif_component_sop_svid_list_fields( else fprintf(stderr, "VIF/Component/SOPSVIDList:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } static void override_vif_component_cable_svid_mode_fields( - struct vif_cableSVIDModeList_t *vif_cable_mode) + struct vif_cableSVIDModeList_t *vif_cable_mode) { char name[80]; char tag_value[80]; @@ -1875,19 +1837,18 @@ static void override_vif_component_cable_svid_mode_fields( if (streq(name, vif_cable_mode_name[i])) break; if (i != CableSVID_Mode_Indexes) - set_override_vif_field( - &vif_cable_mode->vif_field[i], - vif_cable_mode_name[i], - tag_value, - str_value); + set_override_vif_field(&vif_cable_mode->vif_field[i], + vif_cable_mode_name[i], + tag_value, str_value); else fprintf(stderr, "VIF/Component/CableSVIDMode:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } static void override_vif_component_cable_svid_mode_list_fields( - struct vif_cableSVIDModeList_t *vif_cable_mode_list) + struct vif_cableSVIDModeList_t *vif_cable_mode_list) { char name[80]; char tag_value[80]; @@ -1904,12 +1865,13 @@ static void override_vif_component_cable_svid_mode_list_fields( else fprintf(stderr, "VIF/Component/CableSVIDModeList:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } static void override_vif_component_cable_svid_fields( - struct vif_cableSVIDList_t *vif_cable_svid) + struct vif_cableSVIDList_t *vif_cable_svid) { char name[80]; char tag_value[80]; @@ -1922,8 +1884,8 @@ static void override_vif_component_cable_svid_fields( if (is_start_tag(name, "CableSVIDModeList")) override_vif_component_cable_svid_mode_list_fields( - &vif_cable_svid->CableSVIDModeList[ - mode_index++]); + &vif_cable_svid + ->CableSVIDModeList[mode_index++]); else { int i; @@ -1933,18 +1895,18 @@ static void override_vif_component_cable_svid_fields( if (i != CableSVID_Indexes) set_override_vif_field( &vif_cable_svid->vif_field[i], - vif_cable_svid_name[i], - tag_value, + vif_cable_svid_name[i], tag_value, str_value); else fprintf(stderr, "VIF/Component/CableSVID:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } } static void override_vif_component_cable_svid_list_fields( - struct vif_cableSVIDList_t *vif_cable_svid_list) + struct vif_cableSVIDList_t *vif_cable_svid_list) { char name[80]; char tag_value[80]; @@ -1961,12 +1923,12 @@ static void override_vif_component_cable_svid_list_fields( else fprintf(stderr, "VIF/Component/CableSVIDList:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } -static void override_vif_component_fields( - struct vif_Component_t *vif_component) +static void override_vif_component_fields(struct vif_Component_t *vif_component) { char name[80]; char tag_value[80]; @@ -1978,16 +1940,16 @@ static void override_vif_component_fields( if (is_start_tag(name, "SrcPdoList")) override_vif_component_src_pdo_list_fields( - vif_component->SrcPdoList); + vif_component->SrcPdoList); else if (is_start_tag(name, "SnkPdoList")) override_vif_component_snk_pdo_list_fields( - vif_component->SnkPdoList); + vif_component->SnkPdoList); else if (is_start_tag(name, "SOPSVIDList")) override_vif_component_sop_svid_list_fields( - vif_component->SOPSVIDList); + vif_component->SOPSVIDList); else if (is_start_tag(name, "CableSVIDList")) override_vif_component_cable_svid_list_fields( - vif_component->CableSVIDList); + vif_component->CableSVIDList); else { int i; @@ -1996,14 +1958,14 @@ static void override_vif_component_fields( break; if (i != Component_Indexes) set_override_vif_field( - &vif_component->vif_field[i], - vif_component_name[i], - tag_value, - str_value); + &vif_component->vif_field[i], + vif_component_name[i], tag_value, + str_value); else fprintf(stderr, "VIF/Component:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } } @@ -2026,7 +1988,8 @@ static void override_vif_app_fields(struct vif_t *vif) if (i == VIF_App_Indexes) fprintf(stderr, "VIF/VIF_App:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } @@ -2055,15 +2018,14 @@ static void override_vif_fields(struct vif_t *vif) if (streq(name, vif_name[i])) break; if (i != VIF_Indexes) - set_override_vif_field( - &vif->vif_field[i], - vif_name[i], - tag_value, - str_value); + set_override_vif_field(&vif->vif_field[i], + vif_name[i], tag_value, + str_value); else fprintf(stderr, "VIF:" - " Unknown tag '%s'\n", name); + " Unknown tag '%s'\n", + name); } } @@ -2072,19 +2034,15 @@ static void override_vif_fields(struct vif_t *vif) * means VIF/VIF_App is to be set by me. */ set_override_vif_field(&vif->vif_app_field[Vendor], - vif_app_name[Vendor], - NULL, - VIF_APP_VENDOR_VALUE); + vif_app_name[Vendor], NULL, + VIF_APP_VENDOR_VALUE); - set_override_vif_field(&vif->vif_app_field[Name], - vif_app_name[Name], - NULL, - VIF_APP_NAME_VALUE); + set_override_vif_field(&vif->vif_app_field[Name], vif_app_name[Name], + NULL, VIF_APP_NAME_VALUE); set_override_vif_field(&vif->vif_app_field[Version], - vif_app_name[Version], - NULL, - VIF_APP_VERSION_VALUE); + vif_app_name[Version], NULL, + VIF_APP_VERSION_VALUE); } static int override_gen_vif(char *over_name, struct vif_t *vif) @@ -2103,8 +2061,7 @@ static int override_gen_vif(char *over_name, struct vif_t *vif) if (is_start_tag(name, "VIF")) override_vif_fields(vif); else - fprintf(stderr, - "Unknown tag '%s'\n", name); + fprintf(stderr, "Unknown tag '%s'\n", name); } ov_close(); @@ -2114,14 +2071,11 @@ static int override_gen_vif(char *over_name, struct vif_t *vif) * VIF Structure Override from XML file functions *****************************************************************************/ - /***************************************************************************** * VIF Structure Initialization Helper Functions */ -static void set_vif_field(struct vif_field_t *vif_field, - const char *name, - const char *tag_value, - const char *str_value) +static void set_vif_field(struct vif_field_t *vif_field, const char *name, + const char *tag_value, const char *str_value) { char *ptr; @@ -2135,19 +2089,18 @@ static void set_vif_field(struct vif_field_t *vif_field, vif_field->name = name; if (tag_value) { - ptr = malloc(strlen(tag_value)+1); + ptr = malloc(strlen(tag_value) + 1); strcpy(ptr, tag_value); vif_field->tag_value = ptr; } if (str_value) { - ptr = malloc(strlen(str_value)+1); + ptr = malloc(strlen(str_value) + 1); strcpy(ptr, str_value); vif_field->str_value = ptr; } } __maybe_unused static void set_vif_field_b(struct vif_field_t *vif_field, - const char *name, - const bool val) + const char *name, const bool val) { if (val) set_vif_field(vif_field, name, "true", NULL); @@ -2155,9 +2108,9 @@ __maybe_unused static void set_vif_field_b(struct vif_field_t *vif_field, set_vif_field(vif_field, name, "false", NULL); } __maybe_unused static void set_vif_field_stis(struct vif_field_t *vif_field, - const char *name, - const char *tag_value, - const int str_value) + const char *name, + const char *tag_value, + const int str_value) { char str_str[20]; @@ -2165,9 +2118,9 @@ __maybe_unused static void set_vif_field_stis(struct vif_field_t *vif_field, set_vif_field(vif_field, name, tag_value, str_str); } __maybe_unused static void set_vif_field_itss(struct vif_field_t *vif_field, - const char *name, - const int tag_value, - const char *str_value) + const char *name, + const int tag_value, + const char *str_value) { char str_tag[20]; @@ -2175,9 +2128,9 @@ __maybe_unused static void set_vif_field_itss(struct vif_field_t *vif_field, set_vif_field(vif_field, name, str_tag, str_value); } __maybe_unused static void set_vif_field_itis(struct vif_field_t *vif_field, - const char *name, - const int tag_value, - const int str_value) + const char *name, + const int tag_value, + const int str_value) { char str_tag[20]; char str_str[20]; @@ -2369,16 +2322,17 @@ __maybe_unused static int32_t init_vif_snk_pdo(struct vif_snkPdoList_t *snkPdo, power_mw = (current_ma * voltage_mv) / 1000; set_vif_field(&snkPdo->vif_field[Snk_PDO_Supply_Type], - vif_component_snk_pdo_name[Snk_PDO_Supply_Type], - "0", "Fixed"); + vif_component_snk_pdo_name[Snk_PDO_Supply_Type], + "0", "Fixed"); sprintf(str, "%d mV", voltage_mv); set_vif_field_itss(&snkPdo->vif_field[Snk_PDO_Voltage], - vif_component_snk_pdo_name[Snk_PDO_Voltage], - voltage, str); + vif_component_snk_pdo_name[Snk_PDO_Voltage], + voltage, str); sprintf(str, "%d mA", current_ma); - set_vif_field_itss(&snkPdo->vif_field[Snk_PDO_Op_Current], - vif_component_snk_pdo_name[Snk_PDO_Op_Current], - current, str); + set_vif_field_itss( + &snkPdo->vif_field[Snk_PDO_Op_Current], + vif_component_snk_pdo_name[Snk_PDO_Op_Current], current, + str); } else if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) { uint32_t max_voltage = (pdo >> 20) & 0x3ff; @@ -2391,20 +2345,22 @@ __maybe_unused static int32_t init_vif_snk_pdo(struct vif_snkPdoList_t *snkPdo, power_mw = power * 250; set_vif_field(&snkPdo->vif_field[Snk_PDO_Supply_Type], - vif_component_snk_pdo_name[Snk_PDO_Supply_Type], - "1", "Battery"); + vif_component_snk_pdo_name[Snk_PDO_Supply_Type], + "1", "Battery"); sprintf(str, "%d mV", min_voltage_mv); - set_vif_field_itss(&snkPdo->vif_field[Snk_PDO_Min_Voltage], + set_vif_field_itss( + &snkPdo->vif_field[Snk_PDO_Min_Voltage], vif_component_snk_pdo_name[Snk_PDO_Min_Voltage], min_voltage, str); sprintf(str, "%d mV", max_voltage_mv); - set_vif_field_itss(&snkPdo->vif_field[Snk_PDO_Max_Voltage], + set_vif_field_itss( + &snkPdo->vif_field[Snk_PDO_Max_Voltage], vif_component_snk_pdo_name[Snk_PDO_Max_Voltage], max_voltage, str); sprintf(str, "%d mW", power_mw); set_vif_field_itss(&snkPdo->vif_field[Snk_PDO_Op_Power], - vif_component_snk_pdo_name[Snk_PDO_Op_Power], - power, str); + vif_component_snk_pdo_name[Snk_PDO_Op_Power], + power, str); } else if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_VARIABLE) { uint32_t max_voltage = (pdo >> 20) & 0x3ff; @@ -2417,20 +2373,23 @@ __maybe_unused static int32_t init_vif_snk_pdo(struct vif_snkPdoList_t *snkPdo, power_mw = (current_ma * max_voltage_mv) / 1000; set_vif_field(&snkPdo->vif_field[Snk_PDO_Supply_Type], - vif_component_snk_pdo_name[Snk_PDO_Supply_Type], - "2", "Variable"); + vif_component_snk_pdo_name[Snk_PDO_Supply_Type], + "2", "Variable"); sprintf(str, "%d mV", min_voltage_mv); - set_vif_field_itss(&snkPdo->vif_field[Snk_PDO_Min_Voltage], + set_vif_field_itss( + &snkPdo->vif_field[Snk_PDO_Min_Voltage], vif_component_snk_pdo_name[Snk_PDO_Min_Voltage], min_voltage, str); sprintf(str, "%d mV", max_voltage_mv); - set_vif_field_itss(&snkPdo->vif_field[Snk_PDO_Max_Voltage], + set_vif_field_itss( + &snkPdo->vif_field[Snk_PDO_Max_Voltage], vif_component_snk_pdo_name[Snk_PDO_Max_Voltage], max_voltage, str); sprintf(str, "%d mA", current_ma); - set_vif_field_itss(&snkPdo->vif_field[Snk_PDO_Op_Current], - vif_component_snk_pdo_name[Snk_PDO_Op_Current], - current, str); + set_vif_field_itss( + &snkPdo->vif_field[Snk_PDO_Op_Current], + vif_component_snk_pdo_name[Snk_PDO_Op_Current], current, + str); } else if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_AUGMENTED) { uint32_t pps = (pdo >> 28) & 3; @@ -2449,18 +2408,21 @@ __maybe_unused static int32_t init_vif_snk_pdo(struct vif_snkPdoList_t *snkPdo, power_mw = (pps_current_ma * pps_max_voltage_mv) / 1000; set_vif_field(&snkPdo->vif_field[Snk_PDO_Supply_Type], - vif_component_snk_pdo_name[Snk_PDO_Supply_Type], - "3", "PPS"); + vif_component_snk_pdo_name[Snk_PDO_Supply_Type], + "3", "PPS"); sprintf(str, "%d mA", pps_current_ma); - set_vif_field_itss(&snkPdo->vif_field[Snk_PDO_Op_Current], + set_vif_field_itss( + &snkPdo->vif_field[Snk_PDO_Op_Current], vif_component_snk_pdo_name[Snk_PDO_Op_Current], pps_current, str); sprintf(str, "%d mV", pps_min_voltage_mv); - set_vif_field_itss(&snkPdo->vif_field[Snk_PDO_Min_Voltage], + set_vif_field_itss( + &snkPdo->vif_field[Snk_PDO_Min_Voltage], vif_component_snk_pdo_name[Snk_PDO_Min_Voltage], pps_min_voltage, str); sprintf(str, "%d mV", pps_max_voltage_mv); - set_vif_field_itss(&snkPdo->vif_field[Snk_PDO_Max_Voltage], + set_vif_field_itss( + &snkPdo->vif_field[Snk_PDO_Max_Voltage], vif_component_snk_pdo_name[Snk_PDO_Max_Voltage], pps_max_voltage, str); } else { @@ -2501,17 +2463,18 @@ __maybe_unused static int32_t init_vif_src_pdo(struct vif_srcPdoList_t *srcPdo, power_mw = (current_ma * voltage_mv) / 1000; set_vif_field(&srcPdo->vif_field[Src_PDO_Supply_Type], - vif_component_src_pdo_name[Src_PDO_Supply_Type], - "0", "Fixed"); + vif_component_src_pdo_name[Src_PDO_Supply_Type], + "0", "Fixed"); set_vif_field(&srcPdo->vif_field[Src_PDO_Peak_Current], - vif_component_src_pdo_name[Src_PDO_Peak_Current], - "0", "100% IOC"); + vif_component_src_pdo_name[Src_PDO_Peak_Current], + "0", "100% IOC"); sprintf(str, "%d mV", voltage_mv); set_vif_field_itss(&srcPdo->vif_field[Src_PDO_Voltage], - vif_component_src_pdo_name[Src_PDO_Voltage], - voltage, str); + vif_component_src_pdo_name[Src_PDO_Voltage], + voltage, str); sprintf(str, "%d mA", current_ma); - set_vif_field_itss(&srcPdo->vif_field[Src_PDO_Max_Current], + set_vif_field_itss( + &srcPdo->vif_field[Src_PDO_Max_Current], vif_component_src_pdo_name[Src_PDO_Max_Current], current, str); @@ -2526,20 +2489,23 @@ __maybe_unused static int32_t init_vif_src_pdo(struct vif_srcPdoList_t *srcPdo, power_mw = power * 250; set_vif_field(&srcPdo->vif_field[Src_PDO_Supply_Type], - vif_component_src_pdo_name[Src_PDO_Supply_Type], - "1", "Battery"); + vif_component_src_pdo_name[Src_PDO_Supply_Type], + "1", "Battery"); sprintf(str, "%d mV", min_voltage_mv); - set_vif_field_itss(&srcPdo->vif_field[Src_PDO_Min_Voltage], + set_vif_field_itss( + &srcPdo->vif_field[Src_PDO_Min_Voltage], vif_component_src_pdo_name[Src_PDO_Min_Voltage], min_voltage, str); sprintf(str, "%d mV", max_voltage_mv); - set_vif_field_itss(&srcPdo->vif_field[Src_PDO_Max_Voltage], + set_vif_field_itss( + &srcPdo->vif_field[Src_PDO_Max_Voltage], vif_component_src_pdo_name[Src_PDO_Max_Voltage], max_voltage, str); sprintf(str, "%d mW", power_mw); - set_vif_field_itss(&srcPdo->vif_field[Src_PDO_Max_Power], - vif_component_src_pdo_name[Src_PDO_Max_Power], - power, str); + set_vif_field_itss( + &srcPdo->vif_field[Src_PDO_Max_Power], + vif_component_src_pdo_name[Src_PDO_Max_Power], power, + str); } else if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_VARIABLE) { uint32_t max_voltage = (pdo >> 20) & 0x3ff; @@ -2552,21 +2518,24 @@ __maybe_unused static int32_t init_vif_src_pdo(struct vif_srcPdoList_t *srcPdo, power_mw = (current_ma * max_voltage_mv) / 1000; set_vif_field(&srcPdo->vif_field[Src_PDO_Supply_Type], - vif_component_src_pdo_name[Src_PDO_Supply_Type], - "2", "Variable"); + vif_component_src_pdo_name[Src_PDO_Supply_Type], + "2", "Variable"); set_vif_field(&srcPdo->vif_field[Src_PDO_Peak_Current], - vif_component_src_pdo_name[Src_PDO_Peak_Current], - "0", "100% IOC"); + vif_component_src_pdo_name[Src_PDO_Peak_Current], + "0", "100% IOC"); sprintf(str, "%d mV", min_voltage_mv); - set_vif_field_itss(&srcPdo->vif_field[Src_PDO_Min_Voltage], + set_vif_field_itss( + &srcPdo->vif_field[Src_PDO_Min_Voltage], vif_component_src_pdo_name[Src_PDO_Min_Voltage], min_voltage, str); sprintf(str, "%d mV", max_voltage_mv); - set_vif_field_itss(&srcPdo->vif_field[Src_PDO_Max_Voltage], + set_vif_field_itss( + &srcPdo->vif_field[Src_PDO_Max_Voltage], vif_component_src_pdo_name[Src_PDO_Max_Voltage], max_voltage, str); sprintf(str, "%d mA", current_ma); - set_vif_field_itss(&srcPdo->vif_field[Src_PDO_Max_Current], + set_vif_field_itss( + &srcPdo->vif_field[Src_PDO_Max_Current], vif_component_src_pdo_name[Src_PDO_Max_Current], current, str); @@ -2587,18 +2556,21 @@ __maybe_unused static int32_t init_vif_src_pdo(struct vif_srcPdoList_t *srcPdo, power_mw = (pps_current_ma * pps_max_voltage_mv) / 1000; set_vif_field(&srcPdo->vif_field[Src_PDO_Supply_Type], - vif_component_src_pdo_name[Src_PDO_Supply_Type], - "3", "PPS"); + vif_component_src_pdo_name[Src_PDO_Supply_Type], + "3", "PPS"); sprintf(str, "%d mA", pps_current_ma); - set_vif_field_itss(&srcPdo->vif_field[Src_PDO_Max_Current], + set_vif_field_itss( + &srcPdo->vif_field[Src_PDO_Max_Current], vif_component_src_pdo_name[Src_PDO_Max_Current], pps_current, str); sprintf(str, "%d mV", pps_min_voltage_mv); - set_vif_field_itss(&srcPdo->vif_field[Src_PDO_Min_Voltage], + set_vif_field_itss( + &srcPdo->vif_field[Src_PDO_Min_Voltage], vif_component_src_pdo_name[Src_PDO_Min_Voltage], pps_min_voltage, str); sprintf(str, "%d mV", pps_max_voltage_mv); - set_vif_field_itss(&srcPdo->vif_field[Src_PDO_Max_Voltage], + set_vif_field_itss( + &srcPdo->vif_field[Src_PDO_Max_Voltage], vif_component_src_pdo_name[Src_PDO_Max_Voltage], pps_max_voltage, str); @@ -2614,157 +2586,120 @@ __maybe_unused static int32_t init_vif_src_pdo(struct vif_srcPdoList_t *srcPdo, * Init VIF Fields */ static void init_vif_fields(struct vif_field_t *vif_fields, - struct vif_field_t *vif_app_fields, - const char *board) + struct vif_field_t *vif_app_fields, + const char *board) { set_vif_field(&vif_fields[VIF_Specification], - vif_name[VIF_Specification], - NULL, - "3.18"); - - set_vif_field(&vif_app_fields[Vendor], - vif_app_name[Vendor], - NULL, - VIF_APP_VENDOR_VALUE); - - set_vif_field(&vif_app_fields[Name], - vif_app_name[Name], - NULL, - VIF_APP_NAME_VALUE); - - set_vif_field(&vif_app_fields[Version], - vif_app_name[Version], - NULL, - VIF_APP_VERSION_VALUE); - - set_vif_field(&vif_fields[Vendor_Name], - vif_name[Vendor_Name], - NULL, - VENDOR_NAME_VALUE); - - #if defined(CONFIG_USB_PD_MODEL_PART_NUMBER) + vif_name[VIF_Specification], NULL, "3.18"); + + set_vif_field(&vif_app_fields[Vendor], vif_app_name[Vendor], NULL, + VIF_APP_VENDOR_VALUE); + + set_vif_field(&vif_app_fields[Name], vif_app_name[Name], NULL, + VIF_APP_NAME_VALUE); + + set_vif_field(&vif_app_fields[Version], vif_app_name[Version], NULL, + VIF_APP_VERSION_VALUE); + + set_vif_field(&vif_fields[Vendor_Name], vif_name[Vendor_Name], NULL, + VENDOR_NAME_VALUE); + +#if defined(CONFIG_USB_PD_MODEL_PART_NUMBER) + set_vif_field(&vif_fields[Model_Part_Number], + vif_name[Model_Part_Number], NULL, + CONFIG_USB_PD_MODEL_PART_NUMBER); +#else + if (board && strlen(board) > 0) set_vif_field(&vif_fields[Model_Part_Number], - vif_name[Model_Part_Number], - NULL, - CONFIG_USB_PD_MODEL_PART_NUMBER); - #else - if (board && strlen(board) > 0) - set_vif_field(&vif_fields[Model_Part_Number], - vif_name[Model_Part_Number], - NULL, - board); - else - set_vif_field(&vif_fields[Model_Part_Number], - vif_name[Model_Part_Number], - NULL, - "FIX-ME"); - #endif - - #if defined(CONFIG_USB_PD_PRODUCT_REVISION) - set_vif_field(&vif_fields[Product_Revision], - vif_name[Product_Revision], - NULL, - CONFIG_USB_PD_PRODUCT_REVISION); - #else - set_vif_field(&vif_fields[Product_Revision], - vif_name[Product_Revision], - NULL, - "FIX-ME"); - #endif - - #if defined(CONFIG_USB_PD_TID) - set_vif_field_stis(&vif_fields[TID], - vif_name[TID], - NULL, - CONFIG_USB_PD_TID); - #else - set_vif_field_stis(&vif_fields[TID], - vif_name[TID], - NULL, - DEFAULT_MISSING_TID); - #endif - - set_vif_field(&vif_fields[VIF_Product_Type], - vif_name[VIF_Product_Type], - "0", - "Port Product"); + vif_name[Model_Part_Number], NULL, board); + else + set_vif_field(&vif_fields[Model_Part_Number], + vif_name[Model_Part_Number], NULL, "FIX-ME"); +#endif + +#if defined(CONFIG_USB_PD_PRODUCT_REVISION) + set_vif_field(&vif_fields[Product_Revision], vif_name[Product_Revision], + NULL, CONFIG_USB_PD_PRODUCT_REVISION); +#else + set_vif_field(&vif_fields[Product_Revision], vif_name[Product_Revision], + NULL, "FIX-ME"); +#endif + +#if defined(CONFIG_USB_PD_TID) + set_vif_field_stis(&vif_fields[TID], vif_name[TID], NULL, + CONFIG_USB_PD_TID); +#else + set_vif_field_stis(&vif_fields[TID], vif_name[TID], NULL, + DEFAULT_MISSING_TID); +#endif + + set_vif_field(&vif_fields[VIF_Product_Type], vif_name[VIF_Product_Type], + "0", "Port Product"); set_vif_field(&vif_fields[Certification_Type], - vif_name[Certification_Type], - "0", - "End Product"); + vif_name[Certification_Type], "0", "End Product"); } /********************************************************************* * Init VIF/Component[] Fields */ static void init_vif_component_fields(struct vif_field_t *vif_fields, - enum bc_1_2_support *bc_support, - enum dtype type) -{ - #if defined(CONFIG_USB_PD_PORT_LABEL) - set_vif_field_stis(&vif_fields[Port_Label], - vif_component_name[Port_Label], - NULL, - CONFIG_USB_PD_PORT_LABEL); - #else - set_vif_field_stis(&vif_fields[Port_Label], - vif_component_name[Port_Label], - NULL, - component_index); - #endif + enum bc_1_2_support *bc_support, + enum dtype type) +{ +#if defined(CONFIG_USB_PD_PORT_LABEL) + set_vif_field_stis(&vif_fields[Port_Label], + vif_component_name[Port_Label], NULL, + CONFIG_USB_PD_PORT_LABEL); +#else + set_vif_field_stis(&vif_fields[Port_Label], + vif_component_name[Port_Label], NULL, + component_index); +#endif set_vif_field(&vif_fields[Connector_Type], - vif_component_name[Connector_Type], - "2", - "Type-C®"); + vif_component_name[Connector_Type], "2", "Type-C®"); if (is_usb4_supported()) { int router_index; set_vif_field_b(&vif_fields[USB4_Supported], - vif_component_name[USB4_Supported], - true); + vif_component_name[USB4_Supported], true); if (!get_vif_field_tag_number( - &vif.Product.USB4RouterList[0] - .vif_field[USB4_Router_ID], - &router_index)) { + &vif.Product.USB4RouterList[0] + .vif_field[USB4_Router_ID], + &router_index)) { router_index = 0; } set_vif_field_itss(&vif_fields[USB4_Router_Index], - vif_component_name[USB4_Router_Index], - router_index, - NULL); + vif_component_name[USB4_Router_Index], + router_index, NULL); } else { set_vif_field_b(&vif_fields[USB4_Supported], - vif_component_name[USB4_Supported], - false); + vif_component_name[USB4_Supported], false); } set_vif_field_b(&vif_fields[USB_PD_Support], - vif_component_name[USB_PD_Support], - is_usb_pd_supported()); + vif_component_name[USB_PD_Support], + is_usb_pd_supported()); if (is_usb_pd_supported()) { switch (type) { case SNK: set_vif_field(&vif_fields[PD_Port_Type], - vif_component_name[PD_Port_Type], - "0", - "Consumer Only"); + vif_component_name[PD_Port_Type], "0", + "Consumer Only"); break; case SRC: set_vif_field(&vif_fields[PD_Port_Type], - vif_component_name[PD_Port_Type], - "3", - "Provider Only"); + vif_component_name[PD_Port_Type], "3", + "Provider Only"); break; case DRP: set_vif_field(&vif_fields[PD_Port_Type], - vif_component_name[PD_Port_Type], - "4", - "DRP"); + vif_component_name[PD_Port_Type], "4", + "DRP"); break; } } @@ -2772,31 +2707,27 @@ static void init_vif_component_fields(struct vif_field_t *vif_fields, switch (type) { case SNK: set_vif_field(&vif_fields[Type_C_State_Machine], - vif_component_name[Type_C_State_Machine], - "1", - "SNK"); + vif_component_name[Type_C_State_Machine], "1", + "SNK"); break; case SRC: set_vif_field(&vif_fields[Type_C_State_Machine], - vif_component_name[Type_C_State_Machine], - "0", - "SRC"); + vif_component_name[Type_C_State_Machine], "0", + "SRC"); break; case DRP: set_vif_field(&vif_fields[Type_C_State_Machine], - vif_component_name[Type_C_State_Machine], - "2", - "DRP"); + vif_component_name[Type_C_State_Machine], "2", + "DRP"); break; } set_vif_field_b(&vif_fields[Captive_Cable], - vif_component_name[Captive_Cable], - false); + vif_component_name[Captive_Cable], false); set_vif_field_b(&vif_fields[Port_Battery_Powered], - vif_component_name[Port_Battery_Powered], - IS_ENABLED(CONFIG_BATTERY)); + vif_component_name[Port_Battery_Powered], + IS_ENABLED(CONFIG_BATTERY)); *bc_support = BC_1_2_SUPPORT_NONE; if (IS_ENABLED(CONFIG_BC12_DETECT_MAX14637)) @@ -2811,27 +2742,21 @@ static void init_vif_component_fields(struct vif_field_t *vif_fields, switch (*bc_support) { case BC_1_2_SUPPORT_NONE: set_vif_field(&vif_fields[BC_1_2_Support], - vif_component_name[BC_1_2_Support], - "0", - "None"); + vif_component_name[BC_1_2_Support], "0", "None"); break; case BC_1_2_SUPPORT_PORTABLE_DEVICE: set_vif_field(&vif_fields[BC_1_2_Support], - vif_component_name[BC_1_2_Support], - "1", - "Portable Device"); + vif_component_name[BC_1_2_Support], "1", + "Portable Device"); break; case BC_1_2_SUPPORT_CHARGING_PORT: set_vif_field(&vif_fields[BC_1_2_Support], - vif_component_name[BC_1_2_Support], - "2", - "Charging Port"); + vif_component_name[BC_1_2_Support], "2", + "Charging Port"); break; case BC_1_2_SUPPORT_BOTH: set_vif_field(&vif_fields[BC_1_2_Support], - vif_component_name[BC_1_2_Support], - "3", - "Both"); + vif_component_name[BC_1_2_Support], "3", "Both"); break; } } @@ -2839,54 +2764,43 @@ static void init_vif_component_fields(struct vif_field_t *vif_fields, /********************************************************************* * Init VIF/Component[] General PD Fields */ -static void init_vif_component_general_pd_fields( - struct vif_field_t *vif_fields, - enum dtype type) +static void init_vif_component_general_pd_fields(struct vif_field_t *vif_fields, + enum dtype type) { if (IS_ENABLED(CONFIG_USB_PD_REV30) || IS_ENABLED(CONFIG_USB_PRL_SM)) { set_vif_field(&vif_fields[PD_Spec_Revision_Major], - vif_component_name[PD_Spec_Revision_Major], - "3", - NULL); + vif_component_name[PD_Spec_Revision_Major], "3", + NULL); set_vif_field(&vif_fields[PD_Spec_Revision_Minor], - vif_component_name[PD_Spec_Revision_Minor], - "1", - NULL); + vif_component_name[PD_Spec_Revision_Minor], "1", + NULL); set_vif_field(&vif_fields[PD_Spec_Version_Major], - vif_component_name[PD_Spec_Version_Major], - "1", - NULL); + vif_component_name[PD_Spec_Version_Major], "1", + NULL); set_vif_field(&vif_fields[PD_Spec_Version_Minor], - vif_component_name[PD_Spec_Version_Minor], - "3", - NULL); + vif_component_name[PD_Spec_Version_Minor], "3", + NULL); set_vif_field(&vif_fields[PD_Specification_Revision], - vif_component_name[PD_Specification_Revision], - "2", - "Revision 3"); + vif_component_name[PD_Specification_Revision], + "2", "Revision 3"); } else { set_vif_field(&vif_fields[PD_Spec_Revision_Major], - vif_component_name[PD_Spec_Revision_Major], - "2", - NULL); + vif_component_name[PD_Spec_Revision_Major], "2", + NULL); set_vif_field(&vif_fields[PD_Spec_Revision_Minor], - vif_component_name[PD_Spec_Revision_Minor], - "0", - NULL); + vif_component_name[PD_Spec_Revision_Minor], "0", + NULL); set_vif_field(&vif_fields[PD_Spec_Version_Major], - vif_component_name[PD_Spec_Version_Major], - "1", - NULL); + vif_component_name[PD_Spec_Version_Major], "1", + NULL); set_vif_field(&vif_fields[PD_Spec_Version_Minor], - vif_component_name[PD_Spec_Version_Minor], - "3", - NULL); + vif_component_name[PD_Spec_Version_Minor], "3", + NULL); set_vif_field(&vif_fields[PD_Specification_Revision], - vif_component_name[PD_Specification_Revision], - "1", - "Revision 2"); + vif_component_name[PD_Specification_Revision], + "1", "Revision 2"); } set_vif_field_b(&vif_fields[USB_Comms_Capable], @@ -2926,18 +2840,18 @@ static void init_vif_component_general_pd_fields( supports_to_dfp = can_act_as_device(); break; case SNK: - supports_to_dfp = (can_act_as_host() || - is_alt_mode_controller()); + supports_to_dfp = + (can_act_as_host() || is_alt_mode_controller()); break; case DRP: - supports_to_dfp = (can_act_as_host() && - !can_act_as_device()); + supports_to_dfp = + (can_act_as_host() && !can_act_as_device()); break; } set_vif_field_b(&vif_fields[DR_Swap_To_DFP_Supported], - vif_component_name[DR_Swap_To_DFP_Supported], - supports_to_dfp); + vif_component_name[DR_Swap_To_DFP_Supported], + supports_to_dfp); } /* @@ -2968,18 +2882,18 @@ static void init_vif_component_general_pd_fields( supports_to_ufp = can_act_as_device(); break; case SNK: - supports_to_ufp = (can_act_as_host() || - is_alt_mode_controller()); + supports_to_ufp = + (can_act_as_host() || is_alt_mode_controller()); break; case DRP: - supports_to_ufp = (can_act_as_device() && - !can_act_as_host()); + supports_to_ufp = + (can_act_as_device() && !can_act_as_host()); break; } set_vif_field_b(&vif_fields[DR_Swap_To_UFP_Supported], - vif_component_name[DR_Swap_To_UFP_Supported], - supports_to_ufp); + vif_component_name[DR_Swap_To_UFP_Supported], + supports_to_ufp); } if (is_src()) { @@ -2987,52 +2901,50 @@ static void init_vif_component_general_pd_fields( if (IS_ENABLED(CONFIG_CHARGER)) /* USB-C UP bit set */ set_vif_field_b(&vif_fields[Unconstrained_Power], - vif_component_name[Unconstrained_Power], - (src_pdo[0] & PDO_FIXED_UNCONSTRAINED)); + vif_component_name[Unconstrained_Power], + (src_pdo[0] & PDO_FIXED_UNCONSTRAINED)); else { /* Barrel charger being used */ int32_t dedicated_charge_port_count = 0; - #ifdef CONFIG_DEDICATED_CHARGE_PORT_COUNT - dedicated_charge_port_count = - CONFIG_DEDICATED_CHARGE_PORT_COUNT; - #endif +#ifdef CONFIG_DEDICATED_CHARGE_PORT_COUNT + dedicated_charge_port_count = + CONFIG_DEDICATED_CHARGE_PORT_COUNT; +#endif set_vif_field_b(&vif_fields[Unconstrained_Power], - vif_component_name[Unconstrained_Power], - (dedicated_charge_port_count > 0)); + vif_component_name[Unconstrained_Power], + (dedicated_charge_port_count > 0)); } } else { /* Not SRC capable */ set_vif_field_b(&vif_fields[Unconstrained_Power], - vif_component_name[Unconstrained_Power], - false); + vif_component_name[Unconstrained_Power], false); } set_vif_field_b(&vif_fields[VCONN_Swap_To_On_Supported], - vif_component_name[VCONN_Swap_To_On_Supported], - IS_ENABLED(CONFIG_USBC_VCONN_SWAP)); + vif_component_name[VCONN_Swap_To_On_Supported], + IS_ENABLED(CONFIG_USBC_VCONN_SWAP)); set_vif_field_b(&vif_fields[VCONN_Swap_To_Off_Supported], - vif_component_name[VCONN_Swap_To_Off_Supported], - IS_ENABLED(CONFIG_USBC_VCONN_SWAP)); + vif_component_name[VCONN_Swap_To_Off_Supported], + IS_ENABLED(CONFIG_USBC_VCONN_SWAP)); set_vif_field_b(&vif_fields[Responds_To_Discov_SOP_UFP], - vif_component_name[Responds_To_Discov_SOP_UFP], - does_respond_to_discov_sop_ufp()); + vif_component_name[Responds_To_Discov_SOP_UFP], + does_respond_to_discov_sop_ufp()); set_vif_field_b(&vif_fields[Responds_To_Discov_SOP_DFP], - vif_component_name[Responds_To_Discov_SOP_DFP], - does_respond_to_discov_sop_dfp()); + vif_component_name[Responds_To_Discov_SOP_DFP], + does_respond_to_discov_sop_dfp()); set_vif_field_b(&vif_fields[Attempts_Discov_SOP], - vif_component_name[Attempts_Discov_SOP], - ((!IS_ENABLED(CONFIG_USB_PD_SIMPLE_DFP)) || - (type != SRC))); + vif_component_name[Attempts_Discov_SOP], + ((!IS_ENABLED(CONFIG_USB_PD_SIMPLE_DFP)) || + (type != SRC))); set_vif_field(&vif_fields[Power_Interruption_Available], - vif_component_name[Power_Interruption_Available], - "0", + vif_component_name[Power_Interruption_Available], "0", "No Interruption Possible"); set_vif_field_b(&vif_fields[Data_Reset_Supported], @@ -3044,141 +2956,137 @@ static void init_vif_component_general_pd_fields( IS_ENABLED(CONFIG_USB_PD_USB4)); set_vif_field_b(&vif_fields[Chunking_Implemented_SOP], - vif_component_name[Chunking_Implemented_SOP], - (IS_ENABLED(CONFIG_USB_PD_REV30) && - IS_ENABLED(CONFIG_USB_PRL_SM))); + vif_component_name[Chunking_Implemented_SOP], + (IS_ENABLED(CONFIG_USB_PD_REV30) && + IS_ENABLED(CONFIG_USB_PRL_SM))); - set_vif_field_b(&vif_fields[Unchunked_Extended_Messages_Supported], + set_vif_field_b( + &vif_fields[Unchunked_Extended_Messages_Supported], vif_component_name[Unchunked_Extended_Messages_Supported], false); if (IS_ENABLED(CONFIG_USB_PD_MANUFACTURER_INFO)) { char hex_str[10]; - set_vif_field_b(&vif_fields[Manufacturer_Info_Supported_Port], + set_vif_field_b( + &vif_fields[Manufacturer_Info_Supported_Port], vif_component_name[Manufacturer_Info_Supported_Port], true); sprintf(hex_str, "%04X", USB_VID_GOOGLE); - set_vif_field_itss(&vif_fields[Manufacturer_Info_VID_Port], + set_vif_field_itss( + &vif_fields[Manufacturer_Info_VID_Port], vif_component_name[Manufacturer_Info_VID_Port], USB_VID_GOOGLE, hex_str); - #if defined(CONFIG_USB_PID) - sprintf(hex_str, "%04X", CONFIG_USB_PID); - set_vif_field_itss(&vif_fields[ - Manufacturer_Info_PID_Port], - vif_component_name[Manufacturer_Info_PID_Port], - CONFIG_USB_PID, hex_str); - #else - sprintf(hex_str, "%04X", DEFAULT_MISSING_PID); - set_vif_field_itss(&vif_fields[ - Manufacturer_Info_PID_Port], - vif_component_name[Manufacturer_Info_PID_Port], - DEFAULT_MISSING_PID, hex_str); - #endif +#if defined(CONFIG_USB_PID) + sprintf(hex_str, "%04X", CONFIG_USB_PID); + set_vif_field_itss( + &vif_fields[Manufacturer_Info_PID_Port], + vif_component_name[Manufacturer_Info_PID_Port], + CONFIG_USB_PID, hex_str); +#else + sprintf(hex_str, "%04X", DEFAULT_MISSING_PID); + set_vif_field_itss( + &vif_fields[Manufacturer_Info_PID_Port], + vif_component_name[Manufacturer_Info_PID_Port], + DEFAULT_MISSING_PID, hex_str); +#endif } else { - set_vif_field_b(&vif_fields[Manufacturer_Info_Supported_Port], + set_vif_field_b( + &vif_fields[Manufacturer_Info_Supported_Port], vif_component_name[Manufacturer_Info_Supported_Port], false); } set_vif_field_b(&vif_fields[Security_Msgs_Supported_SOP], - vif_component_name[Security_Msgs_Supported_SOP], - IS_ENABLED(CONFIG_USB_PD_SECURITY_MSGS)); - - #if defined(CONFIG_NUM_FIXED_BATTERIES) - set_vif_field_itss(&vif_fields[Num_Fixed_Batteries], - vif_component_name[Num_Fixed_Batteries], - CONFIG_NUM_FIXED_BATTERIES, NULL); - #elif defined(CONFIG_USB_CTVPD) || defined(CONFIG_USB_VPD) - set_vif_field(&vif_fields[Num_Fixed_Batteries], - vif_component_name[Num_Fixed_Batteries], - "0", NULL); - #else - set_vif_field(&vif_fields[Num_Fixed_Batteries], - vif_component_name[Num_Fixed_Batteries], - "1", NULL); - #endif + vif_component_name[Security_Msgs_Supported_SOP], + IS_ENABLED(CONFIG_USB_PD_SECURITY_MSGS)); + +#if defined(CONFIG_NUM_FIXED_BATTERIES) + set_vif_field_itss(&vif_fields[Num_Fixed_Batteries], + vif_component_name[Num_Fixed_Batteries], + CONFIG_NUM_FIXED_BATTERIES, NULL); +#elif defined(CONFIG_USB_CTVPD) || defined(CONFIG_USB_VPD) + set_vif_field(&vif_fields[Num_Fixed_Batteries], + vif_component_name[Num_Fixed_Batteries], "0", NULL); +#else + set_vif_field(&vif_fields[Num_Fixed_Batteries], + vif_component_name[Num_Fixed_Batteries], "1", NULL); +#endif set_vif_field(&vif_fields[Num_Swappable_Battery_Slots], - vif_component_name[Num_Swappable_Battery_Slots], - "0", NULL); + vif_component_name[Num_Swappable_Battery_Slots], "0", + NULL); set_vif_field(&vif_fields[ID_Header_Connector_Type_SOP], - vif_component_name[ID_Header_Connector_Type_SOP], - "2", "USB Type-C\u00ae Receptacle"); + vif_component_name[ID_Header_Connector_Type_SOP], "2", + "USB Type-C\u00ae Receptacle"); } /********************************************************************* * Init VIF/Component[] SOP* Capabilities Fields */ -static void init_vif_component_sop_capabilities_fields( - struct vif_field_t *vif_fields) +static void +init_vif_component_sop_capabilities_fields(struct vif_field_t *vif_fields) { set_vif_field_b(&vif_fields[SOP_Capable], - vif_component_name[SOP_Capable], - can_act_as_host()); + vif_component_name[SOP_Capable], can_act_as_host()); set_vif_field_b(&vif_fields[SOP_P_Capable], - vif_component_name[SOP_P_Capable], - IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)); + vif_component_name[SOP_P_Capable], + IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)); set_vif_field_b(&vif_fields[SOP_PP_Capable], - vif_component_name[SOP_PP_Capable], - IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)); + vif_component_name[SOP_PP_Capable], + IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)); set_vif_field_b(&vif_fields[SOP_P_Debug_Capable], - vif_component_name[SOP_P_Debug_Capable], - false); + vif_component_name[SOP_P_Debug_Capable], false); set_vif_field_b(&vif_fields[SOP_PP_Debug_Capable], - vif_component_name[SOP_PP_Debug_Capable], - false); + vif_component_name[SOP_PP_Debug_Capable], false); } /********************************************************************* * Init VIF/Component[] USB Type-C Fields */ -static void init_vif_component_usb_type_c_fields( - struct vif_field_t *vif_fields, - enum dtype type) +static void init_vif_component_usb_type_c_fields(struct vif_field_t *vif_fields, + enum dtype type) { set_vif_field_b(&vif_fields[Type_C_Implements_Try_SRC], - vif_component_name[Type_C_Implements_Try_SRC], - IS_ENABLED(CONFIG_USB_PD_TRY_SRC)); + vif_component_name[Type_C_Implements_Try_SRC], + IS_ENABLED(CONFIG_USB_PD_TRY_SRC)); set_vif_field_b(&vif_fields[Type_C_Implements_Try_SNK], - vif_component_name[Type_C_Implements_Try_SNK], - false); + vif_component_name[Type_C_Implements_Try_SNK], false); { int rp = CONFIG_USB_PD_PULLUP; - #if defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) - rp = CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT; - #endif +#if defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) + rp = CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT; +#endif switch (rp) { case 0: set_vif_field(&vif_fields[RP_Value], - vif_component_name[RP_Value], - "0", "Default"); + vif_component_name[RP_Value], "0", + "Default"); break; case 1: set_vif_field(&vif_fields[RP_Value], - vif_component_name[RP_Value], - "1", "1.5A"); + vif_component_name[RP_Value], "1", + "1.5A"); break; case 2: set_vif_field(&vif_fields[RP_Value], - vif_component_name[RP_Value], - "2", "3A"); + vif_component_name[RP_Value], "2", "3A"); break; default: set_vif_field_itss(&vif_fields[RP_Value], - vif_component_name[RP_Value], - rp, NULL); + vif_component_name[RP_Value], rp, + NULL); } } @@ -3190,39 +3098,37 @@ static void init_vif_component_usb_type_c_fields( false); set_vif_field_b(&vif_fields[Type_C_Is_VCONN_Powered_Accessory], - vif_component_name[Type_C_Is_VCONN_Powered_Accessory], - false); + vif_component_name[Type_C_Is_VCONN_Powered_Accessory], + false); set_vif_field_b(&vif_fields[Type_C_Is_Debug_Target_SRC], - vif_component_name[Type_C_Is_Debug_Target_SRC], - true); + vif_component_name[Type_C_Is_Debug_Target_SRC], true); set_vif_field_b(&vif_fields[Type_C_Is_Debug_Target_SNK], - vif_component_name[Type_C_Is_Debug_Target_SNK], - true); + vif_component_name[Type_C_Is_Debug_Target_SNK], true); set_vif_field_b(&vif_fields[Type_C_Can_Act_As_Host], - vif_component_name[Type_C_Can_Act_As_Host], - can_act_as_host()); + vif_component_name[Type_C_Can_Act_As_Host], + can_act_as_host()); set_vif_field_b(&vif_fields[Type_C_Is_Alt_Mode_Controller], - vif_component_name[Type_C_Is_Alt_Mode_Controller], - is_alt_mode_controller()); + vif_component_name[Type_C_Is_Alt_Mode_Controller], + is_alt_mode_controller()); if (can_act_as_device()) { set_vif_field_b(&vif_fields[Type_C_Can_Act_As_Device], - vif_component_name[Type_C_Can_Act_As_Device], - true); + vif_component_name[Type_C_Can_Act_As_Device], + true); - if (is_usb_pd_supported() && - does_respond_to_discov_sop_ufp()) - set_vif_field_b(&vif_fields[Type_C_Is_Alt_Mode_Adapter], + if (is_usb_pd_supported() && does_respond_to_discov_sop_ufp()) + set_vif_field_b( + &vif_fields[Type_C_Is_Alt_Mode_Adapter], vif_component_name[Type_C_Is_Alt_Mode_Adapter], IS_ENABLED(CONFIG_USB_ALT_MODE_ADAPTER)); } else { set_vif_field_b(&vif_fields[Type_C_Can_Act_As_Device], - vif_component_name[Type_C_Can_Act_As_Device], - false); + vif_component_name[Type_C_Can_Act_As_Device], + false); set_vif_field_b(&vif_fields[Type_C_Is_Alt_Mode_Adapter], vif_component_name[Type_C_Is_Alt_Mode_Adapter], false); @@ -3247,37 +3153,37 @@ static void init_vif_component_usb_type_c_fields( switch (ps) { case POWER_EXTERNAL: set_vif_field(&vif_fields[Type_C_Power_Source], - vif_component_name[Type_C_Power_Source], - "0", "Externally Powered"); + vif_component_name[Type_C_Power_Source], + "0", "Externally Powered"); break; case POWER_UFP: set_vif_field(&vif_fields[Type_C_Power_Source], - vif_component_name[Type_C_Power_Source], - "1", "UFP-powered"); + vif_component_name[Type_C_Power_Source], + "1", "UFP-powered"); break; case POWER_BOTH: set_vif_field(&vif_fields[Type_C_Power_Source], - vif_component_name[Type_C_Power_Source], - "2", "Both"); + vif_component_name[Type_C_Power_Source], + "2", "Both"); break; default: - set_vif_field_itss(&vif_fields[Type_C_Power_Source], - vif_component_name[Type_C_Power_Source], - ps, NULL); + set_vif_field_itss( + &vif_fields[Type_C_Power_Source], + vif_component_name[Type_C_Power_Source], ps, + NULL); } } set_vif_field_b(&vif_fields[Type_C_Port_On_Hub], - vif_component_name[Type_C_Port_On_Hub], - false); + vif_component_name[Type_C_Port_On_Hub], false); set_vif_field_b(&vif_fields[Type_C_Supports_Audio_Accessory], - vif_component_name[Type_C_Supports_Audio_Accessory], - false); + vif_component_name[Type_C_Supports_Audio_Accessory], + false); set_vif_field_b(&vif_fields[Type_C_Sources_VCONN], - vif_component_name[Type_C_Sources_VCONN], - IS_ENABLED(CONFIG_USBC_VCONN)); + vif_component_name[Type_C_Sources_VCONN], + IS_ENABLED(CONFIG_USBC_VCONN)); } static void init_vif_component_usb4_port_fields(struct vif_field_t *vif_fields) @@ -3288,8 +3194,7 @@ static void init_vif_component_usb4_port_fields(struct vif_field_t *vif_fields) if (!is_usb4_supported()) return; - set_vif_field_c(&vif_fields[USB4_Port_Header], - "USB4\u2122 Port"); + set_vif_field_c(&vif_fields[USB4_Port_Header], "USB4\u2122 Port"); vi = vif_get_max_tbt_speed(); switch (vi) { @@ -3304,8 +3209,7 @@ static void init_vif_component_usb4_port_fields(struct vif_field_t *vif_fields) } set_vif_field_itss(&vif_fields[USB4_Max_Speed], - vif_component_name[USB4_Max_Speed], - vi, vs); + vif_component_name[USB4_Max_Speed], vi, vs); set_vif_field_b(&vif_fields[USB4_TBT3_Compatibility_Supported], vif_component_name[USB4_TBT3_Compatibility_Supported], @@ -3330,8 +3234,8 @@ static void init_vif_component_usb4_port_fields(struct vif_field_t *vif_fields) * Device_Gen1x1_tLinkTurnaround numericFieldType * Device_Gen2x1_tLinkTurnaround numericFieldType */ -static void init_vif_component_usb_data_ufp_fields( - struct vif_field_t *vif_fields) +static void +init_vif_component_usb_data_ufp_fields(struct vif_field_t *vif_fields) { /* * TOTO(b:172441959) Adjust the speed based on CONFIG_ @@ -3351,37 +3255,36 @@ static void init_vif_component_usb_data_ufp_fields( return; supports_usb_data = does_support_device_usb_data(); - set_vif_field_b( - &vif_fields[Device_Supports_USB_Data], - vif_component_name[Device_Supports_USB_Data], - supports_usb_data); + set_vif_field_b(&vif_fields[Device_Supports_USB_Data], + vif_component_name[Device_Supports_USB_Data], + supports_usb_data); if (supports_usb_data) { switch (ds) { case USB_2: set_vif_field_itss(&vif_fields[Device_Speed], - vif_component_name[Device_Speed], - USB_2, "USB 2"); + vif_component_name[Device_Speed], + USB_2, "USB 2"); break; case USB_GEN11: set_vif_field_itss(&vif_fields[Device_Speed], - vif_component_name[Device_Speed], - USB_GEN11, "USB 3.2 Gen 1x1"); + vif_component_name[Device_Speed], + USB_GEN11, "USB 3.2 Gen 1x1"); break; case USB_GEN21: set_vif_field_itss(&vif_fields[Device_Speed], - vif_component_name[Device_Speed], - USB_GEN21, "USB 3.2 Gen 2x1"); + vif_component_name[Device_Speed], + USB_GEN21, "USB 3.2 Gen 2x1"); break; case USB_GEN12: set_vif_field_itss(&vif_fields[Device_Speed], - vif_component_name[Device_Speed], - USB_GEN12, "USB 3.2 Gen 1x2"); + vif_component_name[Device_Speed], + USB_GEN12, "USB 3.2 Gen 1x2"); break; case USB_GEN22: set_vif_field_itss(&vif_fields[Device_Speed], - vif_component_name[Device_Speed], - USB_GEN22, "USB 3.2 Gen 2x2"); + vif_component_name[Device_Speed], + USB_GEN22, "USB 3.2 Gen 2x2"); break; } } @@ -3402,8 +3305,8 @@ static void init_vif_component_usb_data_ufp_fields( * Host_Gen2x1_tLinkTurnaround numericFieldType * Host_Suspend_Supported booleanFieldType */ -static void init_vif_component_usb_data_dfp_fields( - struct vif_field_t *vif_fields) +static void +init_vif_component_usb_data_dfp_fields(struct vif_field_t *vif_fields) { /* * TOTO(b:172438944) Adjust the speed based on CONFIG_ @@ -3426,65 +3329,63 @@ static void init_vif_component_usb_data_dfp_fields( supports_usb_data = does_support_host_usb_data(); set_vif_field_b(&vif_fields[Host_Supports_USB_Data], - vif_component_name[Host_Supports_USB_Data], - supports_usb_data); + vif_component_name[Host_Supports_USB_Data], + supports_usb_data); if (supports_usb_data) { switch (ds) { case USB_2: set_vif_field_itss(&vif_fields[Host_Speed], - vif_component_name[Host_Speed], - USB_2, "USB 2"); + vif_component_name[Host_Speed], + USB_2, "USB 2"); break; case USB_GEN11: set_vif_field_itss(&vif_fields[Host_Speed], - vif_component_name[Host_Speed], - USB_GEN11, "USB 3.2 Gen 1x1"); + vif_component_name[Host_Speed], + USB_GEN11, "USB 3.2 Gen 1x1"); break; case USB_GEN21: set_vif_field_itss(&vif_fields[Host_Speed], - vif_component_name[Host_Speed], - USB_GEN21, "USB 3.2 Gen 2x1"); + vif_component_name[Host_Speed], + USB_GEN21, "USB 3.2 Gen 2x1"); break; case USB_GEN12: set_vif_field_itss(&vif_fields[Host_Speed], - vif_component_name[Host_Speed], - USB_GEN12, "USB 3.2 Gen 1x2"); + vif_component_name[Host_Speed], + USB_GEN12, "USB 3.2 Gen 1x2"); break; case USB_GEN22: set_vif_field_itss(&vif_fields[Host_Speed], - vif_component_name[Host_Speed], - USB_GEN22, "USB 3.2 Gen 2x2"); + vif_component_name[Host_Speed], + USB_GEN22, "USB 3.2 Gen 2x2"); break; } - if (!get_vif_field_tag_bool( - &vif_fields[Type_C_Port_On_Hub], - &is_dfp_on_hub)) + if (!get_vif_field_tag_bool(&vif_fields[Type_C_Port_On_Hub], + &is_dfp_on_hub)) is_dfp_on_hub = false; set_vif_field_b(&vif_fields[Is_DFP_On_Hub], - vif_component_name[Is_DFP_On_Hub], - is_dfp_on_hub); + vif_component_name[Is_DFP_On_Hub], + is_dfp_on_hub); - set_vif_field_b(&vif_fields[Host_Contains_Captive_Retimer], + set_vif_field_b( + &vif_fields[Host_Contains_Captive_Retimer], vif_component_name[Host_Contains_Captive_Retimer], false); set_vif_field_b(&vif_fields[Host_Is_Embedded], - vif_component_name[Host_Is_Embedded], - false); + vif_component_name[Host_Is_Embedded], false); } } /********************************************************************* * Init VIF/Component[] PD Source Fields */ -static int init_vif_component_pd_source_fields( - struct vif_field_t *vif_fields, - struct vif_srcPdoList_t *comp_src_pdo_list, - int32_t *src_max_power, - enum dtype type) +static int +init_vif_component_pd_source_fields(struct vif_field_t *vif_fields, + struct vif_srcPdoList_t *comp_src_pdo_list, + int32_t *src_max_power, enum dtype type) { if (type == DRP || type == SRC) { int i; @@ -3511,78 +3412,78 @@ static int init_vif_component_pd_source_fields( sprintf(str, "%d mW", *src_max_power); set_vif_field_itss(&vif_fields[PD_Power_As_Source], - vif_component_name[PD_Power_As_Source], - *src_max_power, str); + vif_component_name[PD_Power_As_Source], + *src_max_power, str); } if (type == DRP || type == SRC) set_vif_field_b(&vif_fields[USB_Suspend_May_Be_Cleared], - vif_component_name[USB_Suspend_May_Be_Cleared], - false); + vif_component_name[USB_Suspend_May_Be_Cleared], + false); if (type == DRP || type == SRC) set_vif_field_b(&vif_fields[Sends_Pings], - vif_component_name[Sends_Pings], - false); + vif_component_name[Sends_Pings], false); - if (IS_ENABLED(CONFIG_USB_PD_DUAL_ROLE) && - type == DRP && + if (IS_ENABLED(CONFIG_USB_PD_DUAL_ROLE) && type == DRP && IS_ENABLED(CONFIG_USB_PD_FRS)) - set_vif_field(&vif_fields[ - FR_Swap_Type_C_Current_Capability_As_Initial_Sink], + set_vif_field( + &vif_fields + [FR_Swap_Type_C_Current_Capability_As_Initial_Sink], vif_component_name - [FR_Swap_Type_C_Current_Capability_As_Initial_Sink], + [FR_Swap_Type_C_Current_Capability_As_Initial_Sink], "3", "3A @ 5V"); else - set_vif_field(&vif_fields[ - FR_Swap_Type_C_Current_Capability_As_Initial_Sink], + set_vif_field( + &vif_fields + [FR_Swap_Type_C_Current_Capability_As_Initial_Sink], vif_component_name - [FR_Swap_Type_C_Current_Capability_As_Initial_Sink], + [FR_Swap_Type_C_Current_Capability_As_Initial_Sink], "0", "FR_Swap not supported"); if (IS_ENABLED(CONFIG_USB_PD_REV30) || IS_ENABLED(CONFIG_USB_PRL_SM)) set_vif_field_b(&vif_fields[Master_Port], - vif_component_name[Master_Port], - false); + vif_component_name[Master_Port], false); if (type == DRP || type == SRC) set_vif_field_itss(&vif_fields[Num_Src_PDOs], - vif_component_name[Num_Src_PDOs], - src_pdo_cnt, NULL); + vif_component_name[Num_Src_PDOs], + src_pdo_cnt, NULL); if (type == DRP || type == SRC) { if (IS_ENABLED(CONFIG_USBC_OCP)) { int resp = 0; set_vif_field_b(&vif_fields[PD_OC_Protection], - vif_component_name[PD_OC_Protection], - true); + vif_component_name[PD_OC_Protection], + true); switch (resp) { case 0: set_vif_field(&vif_fields[PD_OCP_Method], - vif_component_name[PD_OCP_Method], - "0", "Over-Current Response"); + vif_component_name[PD_OCP_Method], + "0", "Over-Current Response"); break; case 1: set_vif_field(&vif_fields[PD_OCP_Method], - vif_component_name[PD_OCP_Method], - "1", "Under-Voltage Response"); + vif_component_name[PD_OCP_Method], + "1", "Under-Voltage Response"); break; case 2: set_vif_field(&vif_fields[PD_OCP_Method], - vif_component_name[PD_OCP_Method], - "2", "Both"); + vif_component_name[PD_OCP_Method], + "2", "Both"); break; default: - set_vif_field_itss(&vif_fields[PD_OCP_Method], - vif_component_name[PD_OCP_Method], - resp, NULL); + set_vif_field_itss( + &vif_fields[PD_OCP_Method], + vif_component_name[PD_OCP_Method], resp, + NULL); } } else { set_vif_field_b(&vif_fields[PD_OC_Protection], - vif_component_name[PD_OC_Protection], - false); + vif_component_name[PD_OC_Protection], + false); } } @@ -3592,10 +3493,10 @@ static int init_vif_component_pd_source_fields( /********************************************************************* * Init VIF/Component[] PD Sink Fields */ -static int init_vif_component_pd_sink_fields( - struct vif_field_t *vif_fields, - struct vif_snkPdoList_t *comp_snk_pdo_list, - enum dtype type) +static int +init_vif_component_pd_sink_fields(struct vif_field_t *vif_fields, + struct vif_snkPdoList_t *comp_snk_pdo_list, + enum dtype type) { int i; int32_t snk_max_power = 0; @@ -3607,15 +3508,13 @@ static int init_vif_component_pd_sink_fields( set_vif_field_c(&vif_fields[PD_Sink_Header], "PD Sink"); set_vif_field_b(&vif_fields[EPR_Supported_As_Snk], - vif_component_name[EPR_Supported_As_Snk], - false); + vif_component_name[EPR_Supported_As_Snk], false); /* Sink PDOs */ for (i = 0; i < pd_snk_pdo_cnt; i++) { int32_t pwr; - pwr = init_vif_snk_pdo(&comp_snk_pdo_list[i], - pd_snk_pdo[i]); + pwr = init_vif_snk_pdo(&comp_snk_pdo_list[i], pd_snk_pdo[i]); if (pwr < 0) { fprintf(stderr, "ERROR: Setting SNK PDO.\n"); return 1; @@ -3627,30 +3526,27 @@ static int init_vif_component_pd_sink_fields( sprintf(str, "%d mW", snk_max_power); set_vif_field_itss(&vif_fields[PD_Power_As_Sink], - vif_component_name[PD_Power_As_Sink], - snk_max_power, str); + vif_component_name[PD_Power_As_Sink], snk_max_power, + str); set_vif_field_b(&vif_fields[No_USB_Suspend_May_Be_Set], - vif_component_name[No_USB_Suspend_May_Be_Set], - true); + vif_component_name[No_USB_Suspend_May_Be_Set], true); set_vif_field_b(&vif_fields[GiveBack_May_Be_Set], - vif_component_name[GiveBack_May_Be_Set], - IS_ENABLED(CONFIG_USB_PD_GIVE_BACK)); + vif_component_name[GiveBack_May_Be_Set], + IS_ENABLED(CONFIG_USB_PD_GIVE_BACK)); set_vif_field_b(&vif_fields[Higher_Capability_Set], - vif_component_name[Higher_Capability_Set], - false); + vif_component_name[Higher_Capability_Set], false); - set_vif_field(&vif_fields[ - FR_Swap_Reqd_Type_C_Current_As_Initial_Source], - vif_component_name - [FR_Swap_Reqd_Type_C_Current_As_Initial_Source], + set_vif_field( + &vif_fields[FR_Swap_Reqd_Type_C_Current_As_Initial_Source], + vif_component_name[FR_Swap_Reqd_Type_C_Current_As_Initial_Source], "0", "FR_Swap not supported"); set_vif_field_itss(&vif_fields[Num_Snk_PDOs], - vif_component_name[Num_Snk_PDOs], - pd_snk_pdo_cnt, NULL); + vif_component_name[Num_Snk_PDOs], pd_snk_pdo_cnt, + NULL); return 0; } @@ -3658,32 +3554,28 @@ static int init_vif_component_pd_sink_fields( /********************************************************************* * Init VIF/Component[] PD Dual Role Fields */ -static void init_vif_component_pd_dual_role_fields( - struct vif_field_t *vif_fields, - enum dtype type) +static void +init_vif_component_pd_dual_role_fields(struct vif_field_t *vif_fields, + enum dtype type) { if (!IS_ENABLED(CONFIG_USB_PD_DUAL_ROLE) || type != DRP) return; set_vif_field_b(&vif_fields[Accepts_PR_Swap_As_Src], - vif_component_name[Accepts_PR_Swap_As_Src], - true); + vif_component_name[Accepts_PR_Swap_As_Src], true); set_vif_field_b(&vif_fields[Accepts_PR_Swap_As_Snk], - vif_component_name[Accepts_PR_Swap_As_Snk], - true); + vif_component_name[Accepts_PR_Swap_As_Snk], true); set_vif_field_b(&vif_fields[Requests_PR_Swap_As_Src], - vif_component_name[Requests_PR_Swap_As_Src], - true); + vif_component_name[Requests_PR_Swap_As_Src], true); set_vif_field_b(&vif_fields[Requests_PR_Swap_As_Snk], - vif_component_name[Requests_PR_Swap_As_Snk], - true); + vif_component_name[Requests_PR_Swap_As_Snk], true); set_vif_field_b(&vif_fields[FR_Swap_Supported_As_Initial_Sink], - vif_component_name[FR_Swap_Supported_As_Initial_Sink], - IS_ENABLED(CONFIG_USB_PD_FRS)); + vif_component_name[FR_Swap_Supported_As_Initial_Sink], + IS_ENABLED(CONFIG_USB_PD_FRS)); } /********************************************************************* @@ -3702,8 +3594,8 @@ static void init_vif_component_pd_dual_role_fields( * Num_SVIDs_Max_SOP numericFieldType * SVID_Fixed_SOP booleanFieldType */ -static void init_vif_component_sop_discovery_fields( - struct vif_field_t *vif_fields) +static void +init_vif_component_sop_discovery_fields(struct vif_field_t *vif_fields) { char hex_str[10]; @@ -3716,77 +3608,69 @@ static void init_vif_component_sop_discovery_fields( !does_respond_to_discov_sop_dfp()) return; - set_vif_field(&vif_fields[XID_SOP], - vif_component_name[XID_SOP], - "0", - NULL); + set_vif_field(&vif_fields[XID_SOP], vif_component_name[XID_SOP], "0", + NULL); set_vif_field_b(&vif_fields[Data_Capable_As_USB_Host_SOP], - vif_component_name[Data_Capable_As_USB_Host_SOP], - can_act_as_host()); + vif_component_name[Data_Capable_As_USB_Host_SOP], + can_act_as_host()); set_vif_field_b(&vif_fields[Data_Capable_As_USB_Device_SOP], - vif_component_name[Data_Capable_As_USB_Device_SOP], - can_act_as_device()); + vif_component_name[Data_Capable_As_USB_Device_SOP], + can_act_as_device()); if (does_respond_to_discov_sop_dfp() && IS_ENABLED(CONFIG_USB_PD_REV30)) { #if defined(CONFIG_USB_PD_PORT_LABEL) set_vif_field_stis(&vif_fields[DFP_VDO_Port_Number], - vif_component_name[DFP_VDO_Port_Number], - NULL, - CONFIG_USB_PD_PORT_LABEL); + vif_component_name[DFP_VDO_Port_Number], + NULL, CONFIG_USB_PD_PORT_LABEL); #else set_vif_field_itss(&vif_fields[DFP_VDO_Port_Number], - vif_component_name[DFP_VDO_Port_Number], - component_index, - NULL); + vif_component_name[DFP_VDO_Port_Number], + component_index, NULL); #endif } sprintf(hex_str, "%04X", USB_VID_GOOGLE); set_vif_field_itss(&vif_fields[USB_VID_SOP], - vif_component_name[USB_VID_SOP], - USB_VID_GOOGLE, hex_str); + vif_component_name[USB_VID_SOP], USB_VID_GOOGLE, + hex_str); - #if defined(CONFIG_USB_PID) - sprintf(hex_str, "%04X", CONFIG_USB_PID); - set_vif_field_itss(&vif_fields[PID_SOP], - vif_component_name[PID_SOP], - CONFIG_USB_PID, hex_str); - #else - sprintf(hex_str, "%04X", DEFAULT_MISSING_PID); - set_vif_field_itss(&vif_fields[PID_SOP], - vif_component_name[PID_SOP], - DEFAULT_MISSING_PID, hex_str); - #endif +#if defined(CONFIG_USB_PID) + sprintf(hex_str, "%04X", CONFIG_USB_PID); + set_vif_field_itss(&vif_fields[PID_SOP], vif_component_name[PID_SOP], + CONFIG_USB_PID, hex_str); +#else + sprintf(hex_str, "%04X", DEFAULT_MISSING_PID); + set_vif_field_itss(&vif_fields[PID_SOP], vif_component_name[PID_SOP], + DEFAULT_MISSING_PID, hex_str); +#endif - #if defined(CONFIG_USB_BCD_DEV) - sprintf(hex_str, "%04X", CONFIG_USB_BCD_DEV); - set_vif_field_itss(&vif_fields[bcdDevice_SOP], - vif_component_name[bcdDevice_SOP], - CONFIG_USB_BCD_DEV, hex_str); - #else - sprintf(hex_str, "%04X", DEFAULT_MISSING_BCD_DEV); - set_vif_field_itss(&vif_fields[bcdDevice_SOP], - vif_component_name[bcdDevice_SOP], - DEFAULT_MISSING_BCD_DEV, hex_str); - #endif +#if defined(CONFIG_USB_BCD_DEV) + sprintf(hex_str, "%04X", CONFIG_USB_BCD_DEV); + set_vif_field_itss(&vif_fields[bcdDevice_SOP], + vif_component_name[bcdDevice_SOP], + CONFIG_USB_BCD_DEV, hex_str); +#else + sprintf(hex_str, "%04X", DEFAULT_MISSING_BCD_DEV); + set_vif_field_itss(&vif_fields[bcdDevice_SOP], + vif_component_name[bcdDevice_SOP], + DEFAULT_MISSING_BCD_DEV, hex_str); +#endif } /********************************************************************* * Init VIF/Component[] Battery Charging 1.2 Fields */ -static void init_vif_component_bc_1_2_fields( - struct vif_field_t *vif_fields, - enum bc_1_2_support bc_support) +static void init_vif_component_bc_1_2_fields(struct vif_field_t *vif_fields, + enum bc_1_2_support bc_support) { if (bc_support == BC_1_2_SUPPORT_CHARGING_PORT || bc_support == BC_1_2_SUPPORT_BOTH) set_vif_field(&vif_fields[BC_1_2_Charging_Port_Type], - vif_component_name[BC_1_2_Charging_Port_Type], - "1", - "CDP"); + vif_component_name[BC_1_2_Charging_Port_Type], + "1", "CDP"); } /********************************************************************* @@ -3801,24 +3685,24 @@ static void init_vif_component_bc_1_2_fields( * Port_Source_Power_Gang nonEmptyString * Port_Source_Power_Gang_Max_Power numericFieldType */ -static void init_vif_component_product_power_fields( - struct vif_field_t *vif_fields, - int32_t src_max_power, - enum dtype type) +static void +init_vif_component_product_power_fields(struct vif_field_t *vif_fields, + int32_t src_max_power, enum dtype type) { if (type == DRP || type == SRC) { char str[14]; sprintf(str, "%d mW", src_max_power); - set_vif_field_itss(&vif_fields[Product_Total_Source_Power_mW], + set_vif_field_itss( + &vif_fields[Product_Total_Source_Power_mW], vif_component_name[Product_Total_Source_Power_mW], src_max_power, str); } if (type == DRP || type == SRC) set_vif_field(&vif_fields[Port_Source_Power_Type], - vif_component_name[Port_Source_Power_Type], - "0", "Assured"); + vif_component_name[Port_Source_Power_Type], "0", + "Assured"); } static void init_remarks(struct vif_t *vif) @@ -3852,24 +3736,18 @@ static void init_remarks(struct vif_t *vif) set_vif_field_c(&vif_fields[SOP_Discover_ID_Header], "SOP Discover ID"); } - } -static int gen_vif(const char *board, - struct vif_t *vif) +static int gen_vif(const char *board, struct vif_t *vif) { int max_component_index = board_get_usb_pd_port_count(); /********************************************************************* * Initialize the vif structure */ - init_vif_fields( - vif->vif_field, - vif->vif_app_field, - board); + init_vif_fields(vif->vif_field, vif->vif_app_field, board); - for (component_index = 0; - component_index < max_component_index; + for (component_index = 0; component_index < max_component_index; component_index++) { int override_value; bool was_overridden; @@ -3878,11 +3756,10 @@ static int gen_vif(const char *board, enum bc_1_2_support bc_support = BC_1_2_SUPPORT_NONE; /* Determine if we are DRP, SRC or SNK */ - was_overridden = - get_vif_field_tag_number( - &vif->Component[component_index] - .vif_field[Type_C_State_Machine], - &override_value); + was_overridden = get_vif_field_tag_number( + &vif->Component[component_index] + .vif_field[Type_C_State_Machine], + &override_value); if (was_overridden) { switch (override_value) { case SRC: @@ -3895,20 +3772,19 @@ static int gen_vif(const char *board, } } if (!was_overridden) { - was_overridden = - get_vif_field_tag_number( - &vif->Component[component_index] - .vif_field[PD_Port_Type], - &override_value); + was_overridden = get_vif_field_tag_number( + &vif->Component[component_index] + .vif_field[PD_Port_Type], + &override_value); if (was_overridden) { switch (override_value) { - case PORT_CONSUMER_ONLY: /* SNK */ + case PORT_CONSUMER_ONLY: /* SNK */ type = SNK; break; - case PORT_PROVIDER_ONLY: /* SRC */ + case PORT_PROVIDER_ONLY: /* SRC */ type = SRC; break; - case PORT_DRP: /* DRP */ + case PORT_DRP: /* DRP */ type = DRP; break; default: @@ -3933,60 +3809,51 @@ static int gen_vif(const char *board, return 1; } - init_vif_component_fields( - vif->Component[component_index].vif_field, - &bc_support, - type); + vif->Component[component_index].vif_field, &bc_support, + type); init_vif_component_general_pd_fields( - vif->Component[component_index].vif_field, - type); + vif->Component[component_index].vif_field, type); init_vif_component_sop_capabilities_fields( - vif->Component[component_index].vif_field); + vif->Component[component_index].vif_field); init_vif_component_usb_type_c_fields( - vif->Component[component_index].vif_field, - type); + vif->Component[component_index].vif_field, type); init_vif_component_usb4_port_fields( vif->Component[component_index].vif_field); init_vif_component_usb_data_ufp_fields( - vif->Component[component_index].vif_field); + vif->Component[component_index].vif_field); init_vif_component_usb_data_dfp_fields( - vif->Component[component_index].vif_field); + vif->Component[component_index].vif_field); if (init_vif_component_pd_source_fields( - vif->Component[component_index].vif_field, - vif->Component[component_index].SrcPdoList, - &src_max_power, - type)) + vif->Component[component_index].vif_field, + vif->Component[component_index].SrcPdoList, + &src_max_power, type)) return 1; if (init_vif_component_pd_sink_fields( - vif->Component[component_index].vif_field, - vif->Component[component_index].SnkPdoList, - type)) + vif->Component[component_index].vif_field, + vif->Component[component_index].SnkPdoList, type)) return 1; init_vif_component_pd_dual_role_fields( - vif->Component[component_index].vif_field, - type); + vif->Component[component_index].vif_field, type); init_vif_component_sop_discovery_fields( - vif->Component[component_index].vif_field); + vif->Component[component_index].vif_field); init_vif_component_bc_1_2_fields( - vif->Component[component_index].vif_field, - bc_support); + vif->Component[component_index].vif_field, bc_support); init_vif_component_product_power_fields( - vif->Component[component_index].vif_field, - src_max_power, - type); + vif->Component[component_index].vif_field, + src_max_power, type); } return 0; @@ -4005,14 +3872,11 @@ int main(int argc, char **argv) DIR *vifdir; char *name; int name_size; - const char * const short_opt = "hb:o:nv:"; + const char *const short_opt = "hb:o:nv:"; const struct option long_opts[] = { - { "help", 0, NULL, 'h' }, - { "board", 1, NULL, 'b' }, - { "out", 1, NULL, 'o' }, - { "no-config", 0, NULL, 'n' }, - { "over", 1, NULL, 'v' }, - { NULL } + { "help", 0, NULL, 'h' }, { "board", 1, NULL, 'b' }, + { "out", 1, NULL, 'o' }, { "no-config", 0, NULL, 'n' }, + { "over", 1, NULL, 'v' }, { NULL } }; /* Clear the VIF structure */ diff --git a/util/genvif.h b/util/genvif.h index b9b5ed77bd..448d8bfb43 100644 --- a/util/genvif.h +++ b/util/genvif.h @@ -1,4 +1,4 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. +/* Copyright 2020 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -24,399 +24,399 @@ struct vif_field_t { /* 3.2.15.2 Cable SVID Modes */ enum vif_cableSVIDModeList_indexes { - SVID_Mode_Enter, /* booleanFieldType */ - SVID_Mode_Recog_Mask, /* numericFieldType */ - SVID_Mode_Recog_Value, /* numericFieldType */ + SVID_Mode_Enter, /* booleanFieldType */ + SVID_Mode_Recog_Mask, /* numericFieldType */ + SVID_Mode_Recog_Value, /* numericFieldType */ CableSVID_Mode_Indexes }; struct vif_cableSVIDModeList_t { - struct vif_field_t vif_field[CableSVID_Mode_Indexes]; + struct vif_field_t vif_field[CableSVID_Mode_Indexes]; }; /* 3.2.15.1 Cable SVIDs */ enum vif_cableSVIDList_indexes { - SVID, /* numericFieldType */ - SVID_Num_Modes_Min, /* numericFieldType */ - SVID_Num_Modes_Max, /* numericFieldType */ - SVID_Modes_Fixed, /* booleanFieldType */ + SVID, /* numericFieldType */ + SVID_Num_Modes_Min, /* numericFieldType */ + SVID_Num_Modes_Max, /* numericFieldType */ + SVID_Modes_Fixed, /* booleanFieldType */ CableSVID_Indexes }; struct vif_cableSVIDList_t { - struct vif_field_t vif_field[CableSVID_Indexes]; + struct vif_field_t vif_field[CableSVID_Indexes]; struct vif_cableSVIDModeList_t - CableSVIDModeList[MAX_NUM_CABLE_SVID_MODES]; + CableSVIDModeList[MAX_NUM_CABLE_SVID_MODES]; }; /* 3.2.12.2 SOP SVID Modes */ enum vif_sopSVIDModeList_indexes { - SVID_Mode_Enter_SOP, /* booleanFieldType */ - SVID_Mode_Recog_Mask_SOP, /* numericFieldType */ - SVID_Mode_Recog_Value_SOP, /* numericFieldType */ + SVID_Mode_Enter_SOP, /* booleanFieldType */ + SVID_Mode_Recog_Mask_SOP, /* numericFieldType */ + SVID_Mode_Recog_Value_SOP, /* numericFieldType */ SopSVID_Mode_Indexes }; struct vif_sopSVIDModeList_t { - struct vif_field_t vif_field[SopSVID_Mode_Indexes]; + struct vif_field_t vif_field[SopSVID_Mode_Indexes]; }; /* 3.2.12.1 SOP SVIDs */ enum vif_sopSVIDList_indexes { - SVID_SOP, /* numericFieldType */ - SVID_Num_Modes_Min_SOP, /* numericFieldType */ - SVID_Num_Modes_Max_SOP, /* numericFieldType */ - SVID_Modes_Fixed_SOP, /* booleanFieldType */ + SVID_SOP, /* numericFieldType */ + SVID_Num_Modes_Min_SOP, /* numericFieldType */ + SVID_Num_Modes_Max_SOP, /* numericFieldType */ + SVID_Modes_Fixed_SOP, /* booleanFieldType */ SopSVID_Indexes }; struct vif_sopSVIDList_t { - struct vif_field_t vif_field[SopSVID_Indexes]; + struct vif_field_t vif_field[SopSVID_Indexes]; - struct vif_sopSVIDModeList_t - SOPSVIDModeList[MAX_NUM_SOP_SVID_MODES]; + struct vif_sopSVIDModeList_t SOPSVIDModeList[MAX_NUM_SOP_SVID_MODES]; }; /* 3.2.10.1 Sink PDOs */ enum vif_snkPdoList_indexes { - Snk_PDO_Supply_Type, /* numericFieldType */ - Snk_PDO_APDO_Type, /* numericFieldType */ - Snk_PDO_Voltage, /* numericFieldType */ - Snk_PDO_PDP_Rating, /* numericFieldType */ - Snk_PDO_Op_Power, /* numericFieldType */ - Snk_PDO_Min_Voltage, /* numericFieldType */ - Snk_PDO_Max_Voltage, /* numericFieldType */ - Snk_PDO_Op_Current, /* numericFieldType */ + Snk_PDO_Supply_Type, /* numericFieldType */ + Snk_PDO_APDO_Type, /* numericFieldType */ + Snk_PDO_Voltage, /* numericFieldType */ + Snk_PDO_PDP_Rating, /* numericFieldType */ + Snk_PDO_Op_Power, /* numericFieldType */ + Snk_PDO_Min_Voltage, /* numericFieldType */ + Snk_PDO_Max_Voltage, /* numericFieldType */ + Snk_PDO_Op_Current, /* numericFieldType */ Snk_PDO_Indexes }; struct vif_snkPdoList_t { - struct vif_field_t vif_field[Snk_PDO_Indexes]; + struct vif_field_t vif_field[Snk_PDO_Indexes]; }; /* 3.2.9.1 Source PDOs */ enum vif_srcPdoList_indexes { - Src_PDO_Supply_Type, /* numericFieldType */ - Src_PDO_APDO_Type, /* numericFieldType */ - Src_PDO_Peak_Current, /* numericFieldType */ - Src_PDO_Voltage, /* numericFieldType */ - Src_PDO_Max_Current, /* numericFieldType */ - Src_PDO_Min_Voltage, /* numericFieldType */ - Src_PDO_Max_Voltage, /* numericFieldType */ - Src_PDO_Max_Power, /* numericFieldType */ - Src_PD_OCP_OC_Debounce, /* numericFieldType */ - Src_PD_OCP_OC_Threshold, /* numericFieldType */ - Src_PD_OCP_UV_Debounce, /* numericFieldType */ - Src_PD_OCP_UV_Threshold_Type, /* numericFieldType */ - Src_PD_OCP_UV_Threshold, /* numericFieldType */ + Src_PDO_Supply_Type, /* numericFieldType */ + Src_PDO_APDO_Type, /* numericFieldType */ + Src_PDO_Peak_Current, /* numericFieldType */ + Src_PDO_Voltage, /* numericFieldType */ + Src_PDO_Max_Current, /* numericFieldType */ + Src_PDO_Min_Voltage, /* numericFieldType */ + Src_PDO_Max_Voltage, /* numericFieldType */ + Src_PDO_Max_Power, /* numericFieldType */ + Src_PD_OCP_OC_Debounce, /* numericFieldType */ + Src_PD_OCP_OC_Threshold, /* numericFieldType */ + Src_PD_OCP_UV_Debounce, /* numericFieldType */ + Src_PD_OCP_UV_Threshold_Type, /* numericFieldType */ + Src_PD_OCP_UV_Threshold, /* numericFieldType */ Src_PDO_Indexes }; struct vif_srcPdoList_t { - struct vif_field_t vif_field[Src_PDO_Indexes]; + struct vif_field_t vif_field[Src_PDO_Indexes]; }; /* 3.2.2.1.3 PCIe Endpoint Fields */ enum vif_PCIeEndpointListType_indexes { - USB4_PCIe_Endpoint_Vendor_ID, /* numericFieldType */ - USB4_PCIe_Endpoint_Device_ID, /* numericFieldType */ - USB4_PCIe_Endpoint_Class_Code, /* numericFieldType */ + USB4_PCIe_Endpoint_Vendor_ID, /* numericFieldType */ + USB4_PCIe_Endpoint_Device_ID, /* numericFieldType */ + USB4_PCIe_Endpoint_Class_Code, /* numericFieldType */ PCIe_Endpoint_Indexes }; struct vif_PCIeEndpointListType_t { - struct vif_field_t vif_field[PCIe_Endpoint_Indexes]; + struct vif_field_t vif_field[PCIe_Endpoint_Indexes]; }; /* 3.2.2.1.2 USB4 Router Fields */ enum vif_Usb4RouterListType_indexes { - USB4_Router_ID, /* numericFieldType */ - USB4_Silicon_VID, /* numericFieldType */ - USB4_Num_Lane_Adapters, /* numericFieldType */ - USB4_Num_USB3_DN_Adapters, /* numericFieldType */ - USB4_Num_DP_IN_Adapters, /* numericFieldType */ - USB4_Num_DP_OUT_Adapters, /* numericFieldType */ - USB4_Num_PCIe_DN_Adapters, /* numericFieldType */ - USB4_TBT3_Not_Supported, /* numericFieldType */ - USB4_PCIe_Wake_Supported, /* booleanFieldType */ - USB4_USB3_Wake_Supported, /* booleanFieldType */ - USB4_Num_Unused_Adapters, /* numericFieldType */ - USB4_TBT3_VID, /* numericFieldType */ - USB4_PCIe_Switch_Vendor_ID, /* numericFieldType */ - USB4_PCIe_Switch_Device_ID, /* numericFieldType */ - USB4_Num_PCIe_Endpoints, /* numericFieldType */ + USB4_Router_ID, /* numericFieldType */ + USB4_Silicon_VID, /* numericFieldType */ + USB4_Num_Lane_Adapters, /* numericFieldType */ + USB4_Num_USB3_DN_Adapters, /* numericFieldType */ + USB4_Num_DP_IN_Adapters, /* numericFieldType */ + USB4_Num_DP_OUT_Adapters, /* numericFieldType */ + USB4_Num_PCIe_DN_Adapters, /* numericFieldType */ + USB4_TBT3_Not_Supported, /* numericFieldType */ + USB4_PCIe_Wake_Supported, /* booleanFieldType */ + USB4_USB3_Wake_Supported, /* booleanFieldType */ + USB4_Num_Unused_Adapters, /* numericFieldType */ + USB4_TBT3_VID, /* numericFieldType */ + USB4_PCIe_Switch_Vendor_ID, /* numericFieldType */ + USB4_PCIe_Switch_Device_ID, /* numericFieldType */ + USB4_Num_PCIe_Endpoints, /* numericFieldType */ USB4_Router_Indexes }; struct vif_Usb4RouterListType_t { - struct vif_field_t vif_field[USB4_Router_Indexes]; + struct vif_field_t vif_field[USB4_Router_Indexes]; struct vif_PCIeEndpointListType_t - PCIeEndpointList[MAX_NUM_PCIE_ENDPOINTS]; + PCIeEndpointList[MAX_NUM_PCIE_ENDPOINTS]; }; /* 3.2.3 Component Fields */ enum vif_Component_indexes { - Component_Header, /* comment */ - Port_Label, /* nonEmptyString */ - Connector_Type, /* numericFieldType */ - USB4_Supported, /* booleanFieldType */ - USB4_Router_Index, /* numericFieldType */ - USB_PD_Support, /* booleanFieldType */ - PD_Port_Type, /* numericFieldType */ - Type_C_State_Machine, /* numericFieldType */ - Port_Battery_Powered, /* booleanFieldType */ - BC_1_2_Support, /* numericFieldType */ - Captive_Cable, /* booleanFieldType */ - Captive_Cable_Is_eMarked, /* booleanFieldType */ + Component_Header, /* comment */ + Port_Label, /* nonEmptyString */ + Connector_Type, /* numericFieldType */ + USB4_Supported, /* booleanFieldType */ + USB4_Router_Index, /* numericFieldType */ + USB_PD_Support, /* booleanFieldType */ + PD_Port_Type, /* numericFieldType */ + Type_C_State_Machine, /* numericFieldType */ + Port_Battery_Powered, /* booleanFieldType */ + BC_1_2_Support, /* numericFieldType */ + Captive_Cable, /* booleanFieldType */ + Captive_Cable_Is_eMarked, /* booleanFieldType */ /* 3.2.4 General PD Fields */ - General_PD_Header, /* comment */ - PD_Spec_Revision_Major, /* numericFieldType */ - PD_Spec_Revision_Minor, /* numericFieldType */ - PD_Spec_Version_Major, /* numericFieldType */ - PD_Spec_Version_Minor, /* numericFieldType */ - PD_Specification_Revision, /* numericFieldType */ + General_PD_Header, /* comment */ + PD_Spec_Revision_Major, /* numericFieldType */ + PD_Spec_Revision_Minor, /* numericFieldType */ + PD_Spec_Version_Major, /* numericFieldType */ + PD_Spec_Version_Minor, /* numericFieldType */ + PD_Specification_Revision, /* numericFieldType */ /* 3.2.4.1 SOP* Capabilities */ - SOP_Capable, /* booleanFieldType */ - SOP_P_Capable, /* booleanFieldType */ - SOP_PP_Capable, /* booleanFieldType */ - SOP_P_Debug_Capable, /* booleanFieldType */ - SOP_PP_Debug_Capable, /* booleanFieldType */ - - Manufacturer_Info_Supported_Port, /* booleanFieldType */ - Manufacturer_Info_VID_Port, /* numericFieldType */ - Manufacturer_Info_PID_Port, /* numericFieldType */ - Chunking_Implemented_SOP, /* booleanFieldType */ - Unchunked_Extended_Messages_Supported, /* booleanFieldType */ - Security_Msgs_Supported_SOP, /* booleanFieldType */ - Unconstrained_Power, /* booleanFieldType */ - Num_Fixed_Batteries, /* numericFieldType */ - Num_Swappable_Battery_Slots, /* numericFieldType */ - ID_Header_Connector_Type_SOP, /* numericFieldType */ + SOP_Capable, /* booleanFieldType */ + SOP_P_Capable, /* booleanFieldType */ + SOP_PP_Capable, /* booleanFieldType */ + SOP_P_Debug_Capable, /* booleanFieldType */ + SOP_PP_Debug_Capable, /* booleanFieldType */ + + Manufacturer_Info_Supported_Port, /* booleanFieldType */ + Manufacturer_Info_VID_Port, /* numericFieldType */ + Manufacturer_Info_PID_Port, /* numericFieldType */ + Chunking_Implemented_SOP, /* booleanFieldType */ + Unchunked_Extended_Messages_Supported, /* booleanFieldType */ + Security_Msgs_Supported_SOP, /* booleanFieldType */ + Unconstrained_Power, /* booleanFieldType */ + Num_Fixed_Batteries, /* numericFieldType */ + Num_Swappable_Battery_Slots, /* numericFieldType */ + ID_Header_Connector_Type_SOP, /* numericFieldType */ /* 3.2.4 General PD Fields */ - PD_Capabilities_Header, /* comment */ - USB_Comms_Capable, /* booleanFieldType */ - DR_Swap_To_DFP_Supported, /* booleanFieldType */ - DR_Swap_To_UFP_Supported, /* booleanFieldType */ - VCONN_Swap_To_On_Supported, /* booleanFieldType */ - VCONN_Swap_To_Off_Supported, /* booleanFieldType */ - Responds_To_Discov_SOP_UFP, /* booleanFieldType */ - Responds_To_Discov_SOP_DFP, /* booleanFieldType */ - Attempts_Discov_SOP, /* booleanFieldType */ - Power_Interruption_Available, /* numericFieldType */ - Data_Reset_Supported, /* booleanFieldType */ - Enter_USB_Supported, /* booleanFieldType */ + PD_Capabilities_Header, /* comment */ + USB_Comms_Capable, /* booleanFieldType */ + DR_Swap_To_DFP_Supported, /* booleanFieldType */ + DR_Swap_To_UFP_Supported, /* booleanFieldType */ + VCONN_Swap_To_On_Supported, /* booleanFieldType */ + VCONN_Swap_To_Off_Supported, /* booleanFieldType */ + Responds_To_Discov_SOP_UFP, /* booleanFieldType */ + Responds_To_Discov_SOP_DFP, /* booleanFieldType */ + Attempts_Discov_SOP, /* booleanFieldType */ + Power_Interruption_Available, /* numericFieldType */ + Data_Reset_Supported, /* booleanFieldType */ + Enter_USB_Supported, /* booleanFieldType */ /* 3.2.5 USB Type-C Fields */ - USB_Type_C_Header, /* comment */ - Type_C_Can_Act_As_Host, /* booleanFieldType */ - Type_C_Can_Act_As_Device, /* booleanFieldType */ + USB_Type_C_Header, /* comment */ + Type_C_Can_Act_As_Host, /* booleanFieldType */ + Type_C_Can_Act_As_Device, /* booleanFieldType */ /* 3.2.5 USB Type-C Fields */ - Type_C_Implements_Try_SRC, /* booleanFieldType */ - Type_C_Implements_Try_SNK, /* booleanFieldType */ - Type_C_Supports_Audio_Accessory, /* booleanFieldType */ - Type_C_Is_VCONN_Powered_Accessory, /* booleanFieldType */ - Type_C_Is_Debug_Target_SRC, /* booleanFieldType */ - Type_C_Is_Debug_Target_SNK, /* booleanFieldType */ - RP_Value, /* numericFieldType */ - Type_C_Supports_VCONN_Powered_Accessory,/* booleanFieldType */ - Type_C_Port_On_Hub, /* booleanFieldType */ - Type_C_Power_Source, /* numericFieldType */ - Type_C_Sources_VCONN, /* booleanFieldType */ - Type_C_Is_Alt_Mode_Controller, /* booleanFieldType */ - Type_C_Is_Alt_Mode_Adapter, /* booleanFieldType */ + Type_C_Implements_Try_SRC, /* booleanFieldType */ + Type_C_Implements_Try_SNK, /* booleanFieldType */ + Type_C_Supports_Audio_Accessory, /* booleanFieldType */ + Type_C_Is_VCONN_Powered_Accessory, /* booleanFieldType */ + Type_C_Is_Debug_Target_SRC, /* booleanFieldType */ + Type_C_Is_Debug_Target_SNK, /* booleanFieldType */ + RP_Value, /* numericFieldType */ + Type_C_Supports_VCONN_Powered_Accessory, /* booleanFieldType */ + Type_C_Port_On_Hub, /* booleanFieldType */ + Type_C_Power_Source, /* numericFieldType */ + Type_C_Sources_VCONN, /* booleanFieldType */ + Type_C_Is_Alt_Mode_Controller, /* booleanFieldType */ + Type_C_Is_Alt_Mode_Adapter, /* booleanFieldType */ /* 3.2.6 USB4 Port Fields (missing from output) */ - USB4_Port_Header, /* comment */ - USB4_Lane_0_Adapter, /* numericFieldType */ - USB4_Max_Speed, /* numericFieldType */ - USB4_DFP_Supported, /* booleanFieldType */ - USB4_UFP_Supported, /* booleanFieldType */ - USB4_USB3_Tunneling_Supported, /* booleanFieldType */ - USB4_DP_Tunneling_Supported, /* booleanFieldType */ - USB4_PCIe_Tunneling_Supported, /* booleanFieldType */ - USB4_TBT3_Compatibility_Supported, /* booleanFieldType */ - USB4_CL1_State_Supported, /* booleanFieldType */ - USB4_CL2_State_Supported, /* booleanFieldType */ - USB4_Num_Retimers, /* numericFieldType */ - USB4_DP_Bit_Rate, /* numericFieldType */ - USB4_Num_DP_Lanes, /* numericFieldType */ + USB4_Port_Header, /* comment */ + USB4_Lane_0_Adapter, /* numericFieldType */ + USB4_Max_Speed, /* numericFieldType */ + USB4_DFP_Supported, /* booleanFieldType */ + USB4_UFP_Supported, /* booleanFieldType */ + USB4_USB3_Tunneling_Supported, /* booleanFieldType */ + USB4_DP_Tunneling_Supported, /* booleanFieldType */ + USB4_PCIe_Tunneling_Supported, /* booleanFieldType */ + USB4_TBT3_Compatibility_Supported, /* booleanFieldType */ + USB4_CL1_State_Supported, /* booleanFieldType */ + USB4_CL2_State_Supported, /* booleanFieldType */ + USB4_Num_Retimers, /* numericFieldType */ + USB4_DP_Bit_Rate, /* numericFieldType */ + USB4_Num_DP_Lanes, /* numericFieldType */ /* 3.2.7 USB Data - Upstream Facing Port Fields */ - Device_Supports_USB_Data, /* booleanFieldType */ - Device_Speed, /* numericFieldType */ - Device_Contains_Captive_Retimer, /* booleanFieldType */ - Device_Truncates_DP_For_tDHPResponse, /* booleanFieldType */ - Device_Gen1x1_tLinkTurnaround, /* numericFieldType */ - Device_Gen2x1_tLinkTurnaround, /* numericFieldType */ + Device_Supports_USB_Data, /* booleanFieldType */ + Device_Speed, /* numericFieldType */ + Device_Contains_Captive_Retimer, /* booleanFieldType */ + Device_Truncates_DP_For_tDHPResponse, /* booleanFieldType */ + Device_Gen1x1_tLinkTurnaround, /* numericFieldType */ + Device_Gen2x1_tLinkTurnaround, /* numericFieldType */ /* 3.2.19 Product Power Fields */ - Product_Power_Header, /* comment */ - Product_Total_Source_Power_mW, /* numericFieldType */ - Port_Source_Power_Type, /* numericFieldType */ - Port_Source_Power_Gang, /* nonEmptyString */ - Port_Source_Power_Gang_Max_Power, /* numericFieldType */ + Product_Power_Header, /* comment */ + Product_Total_Source_Power_mW, /* numericFieldType */ + Port_Source_Power_Type, /* numericFieldType */ + Port_Source_Power_Gang, /* nonEmptyString */ + Port_Source_Power_Gang_Max_Power, /* numericFieldType */ /* 3.2.8 USB Data - Downstream Facing Port Fields */ - USB_Host_Header, /* comment */ - Host_Supports_USB_Data, /* booleanFieldType */ - Host_Speed, /* numericFieldType */ - Host_Contains_Captive_Retimer, /* booleanFieldType */ - Host_Truncates_DP_For_tDHPResponse, /* booleanFieldType */ - Host_Gen1x1_tLinkTurnaround, /* numericFieldType */ - Host_Gen2x1_tLinkTurnaround, /* numericFieldType */ - Host_Is_Embedded, /* booleanFieldType */ - Host_Suspend_Supported, /* booleanFieldType */ - Is_DFP_On_Hub, /* booleanFieldType */ - Hub_Port_Number, /* numericFieldType */ + USB_Host_Header, /* comment */ + Host_Supports_USB_Data, /* booleanFieldType */ + Host_Speed, /* numericFieldType */ + Host_Contains_Captive_Retimer, /* booleanFieldType */ + Host_Truncates_DP_For_tDHPResponse, /* booleanFieldType */ + Host_Gen1x1_tLinkTurnaround, /* numericFieldType */ + Host_Gen2x1_tLinkTurnaround, /* numericFieldType */ + Host_Is_Embedded, /* booleanFieldType */ + Host_Suspend_Supported, /* booleanFieldType */ + Is_DFP_On_Hub, /* booleanFieldType */ + Hub_Port_Number, /* numericFieldType */ /* 3.2.14 Battery Charging 1.2 Fields */ - BC_1_2_Header, /* comment */ - BC_1_2_Charging_Port_Type, /* numericFieldType */ + BC_1_2_Header, /* comment */ + BC_1_2_Charging_Port_Type, /* numericFieldType */ /* 3.2.9 PD Source Fields */ - PD_Source_Header, /* comment */ - PD_Power_As_Source, /* numericFieldType */ - EPR_Supported_As_Src, /* booleanFieldType */ - USB_Suspend_May_Be_Cleared, /* booleanFieldType */ - Sends_Pings, /* booleanFieldType */ - FR_Swap_Type_C_Current_Capability_As_Initial_Sink,/* numericFieldType */ - Master_Port, /* booleanFieldType */ - Num_Src_PDOs, /* numericFieldType */ - PD_OC_Protection, /* booleanFieldType */ - PD_OCP_Method, /* numericFieldType */ + PD_Source_Header, /* comment */ + PD_Power_As_Source, /* numericFieldType */ + EPR_Supported_As_Src, /* booleanFieldType */ + USB_Suspend_May_Be_Cleared, /* booleanFieldType */ + Sends_Pings, /* booleanFieldType */ + FR_Swap_Type_C_Current_Capability_As_Initial_Sink, /* numericFieldType + */ + Master_Port, /* booleanFieldType */ + Num_Src_PDOs, /* numericFieldType */ + PD_OC_Protection, /* booleanFieldType */ + PD_OCP_Method, /* numericFieldType */ /* insert: SrcPdoList */ /* 3.2.10 PD Sink Fields */ - PD_Sink_Header, /* comment */ - PD_Power_As_Sink, /* numericFieldType */ - EPR_Supported_As_Snk, /* booleanFieldType */ - No_USB_Suspend_May_Be_Set, /* booleanFieldType */ - GiveBack_May_Be_Set, /* booleanFieldType */ - Higher_Capability_Set, /* booleanFieldType */ - FR_Swap_Reqd_Type_C_Current_As_Initial_Source,/* numericFieldType */ - Num_Snk_PDOs, /* numericFieldType */ + PD_Sink_Header, /* comment */ + PD_Power_As_Sink, /* numericFieldType */ + EPR_Supported_As_Snk, /* booleanFieldType */ + No_USB_Suspend_May_Be_Set, /* booleanFieldType */ + GiveBack_May_Be_Set, /* booleanFieldType */ + Higher_Capability_Set, /* booleanFieldType */ + FR_Swap_Reqd_Type_C_Current_As_Initial_Source, /* numericFieldType */ + Num_Snk_PDOs, /* numericFieldType */ /* insert: SnkPdoList */ /* 3.2.11 PD Dual Role Fields */ - Dual_Role_Header, /* comment */ - Accepts_PR_Swap_As_Src, /* booleanFieldType */ - Accepts_PR_Swap_As_Snk, /* booleanFieldType */ - Requests_PR_Swap_As_Src, /* booleanFieldType */ - Requests_PR_Swap_As_Snk, /* booleanFieldType */ - FR_Swap_Supported_As_Initial_Sink, /* booleanFieldType */ + Dual_Role_Header, /* comment */ + Accepts_PR_Swap_As_Src, /* booleanFieldType */ + Accepts_PR_Swap_As_Snk, /* booleanFieldType */ + Requests_PR_Swap_As_Src, /* booleanFieldType */ + Requests_PR_Swap_As_Snk, /* booleanFieldType */ + FR_Swap_Supported_As_Initial_Sink, /* booleanFieldType */ /* 3.2.12 SOP Discover ID Fields */ - SOP_Discover_ID_Header, /* comment */ - XID_SOP, /* numericFieldType */ - Data_Capable_As_USB_Host_SOP, /* booleanFieldType */ - Data_Capable_As_USB_Device_SOP, /* booleanFieldType */ - Product_Type_UFP_SOP, /* numericFieldType */ - Product_Type_DFP_SOP, /* numericFieldType */ - DFP_VDO_Port_Number, /* numericFieldType */ - Modal_Operation_Supported_SOP, /* booleanFieldType */ - USB_VID_SOP, /* numericFieldType */ - PID_SOP, /* numericFieldType */ - bcdDevice_SOP, /* numericFieldType */ - Num_SVIDs_Min_SOP, /* numericFieldType */ - Num_SVIDs_Max_SOP, /* numericFieldType */ - SVID_Fixed_SOP, /* booleanFieldType */ + SOP_Discover_ID_Header, /* comment */ + XID_SOP, /* numericFieldType */ + Data_Capable_As_USB_Host_SOP, /* booleanFieldType */ + Data_Capable_As_USB_Device_SOP, /* booleanFieldType */ + Product_Type_UFP_SOP, /* numericFieldType */ + Product_Type_DFP_SOP, /* numericFieldType */ + DFP_VDO_Port_Number, /* numericFieldType */ + Modal_Operation_Supported_SOP, /* booleanFieldType */ + USB_VID_SOP, /* numericFieldType */ + PID_SOP, /* numericFieldType */ + bcdDevice_SOP, /* numericFieldType */ + Num_SVIDs_Min_SOP, /* numericFieldType */ + Num_SVIDs_Max_SOP, /* numericFieldType */ + SVID_Fixed_SOP, /* booleanFieldType */ /* 3.2.13 Alternate Mode Adapter (AMA) Fields */ - AMA_HW_Vers, /* numericFieldType */ - AMA_FW_Vers, /* numericFieldType */ - AMA_VCONN_Power, /* booleanFieldType */ - AMA_VCONN_Reqd, /* booleanFieldType */ - AMA_VBUS_Reqd, /* booleanFieldType */ - AMA_Superspeed_Support, /* numericFieldType */ + AMA_HW_Vers, /* numericFieldType */ + AMA_FW_Vers, /* numericFieldType */ + AMA_VCONN_Power, /* booleanFieldType */ + AMA_VCONN_Reqd, /* booleanFieldType */ + AMA_VBUS_Reqd, /* booleanFieldType */ + AMA_Superspeed_Support, /* numericFieldType */ /* 3.2.15 Cable/eMarker Fields */ - XID, /* numericFieldType */ - Data_Capable_As_USB_Host, /* booleanFieldType */ - Data_Capable_As_USB_Device, /* booleanFieldType */ - Product_Type, /* numericFieldType */ - Modal_Operation_Supported, /* booleanFieldType */ - USB_VID, /* numericFieldType */ - PID, /* numericFieldType */ - bcdDevice, /* numericFieldType */ - Cable_HW_Vers, /* numericFieldType */ - Cable_FW_Vers, /* numericFieldType */ - Type_C_To_Type_A_B_C, /* numericFieldType */ - Type_C_To_Type_C_Capt_Vdm_V2, /* numericFieldType */ - EPR_Mode_Capable, /* booleanFieldType */ - Cable_Latency, /* numericFieldType */ - Cable_Termination_Type, /* numericFieldType */ - Cable_VBUS_Current, /* numericFieldType */ - VBUS_Through_Cable, /* booleanFieldType */ - Cable_Superspeed_Support, /* numericFieldType */ - Cable_USB_Highest_Speed, /* numericFieldType */ - Max_VBUS_Voltage_Vdm_V2, /* numericFieldType */ - Manufacturer_Info_Supported, /* booleanFieldType */ - Manufacturer_Info_VID, /* numericFieldType */ - Manufacturer_Info_PID, /* numericFieldType */ - Chunking_Implemented, /* booleanFieldType */ - Security_Msgs_Supported, /* booleanFieldType */ - ID_Header_Connector_Type, /* numericFieldType */ - Cable_Num_SVIDs_Min, /* numericFieldType */ - Cable_Num_SVIDs_Max, /* numericFieldType */ - SVID_Fixed, /* booleanFieldType */ + XID, /* numericFieldType */ + Data_Capable_As_USB_Host, /* booleanFieldType */ + Data_Capable_As_USB_Device, /* booleanFieldType */ + Product_Type, /* numericFieldType */ + Modal_Operation_Supported, /* booleanFieldType */ + USB_VID, /* numericFieldType */ + PID, /* numericFieldType */ + bcdDevice, /* numericFieldType */ + Cable_HW_Vers, /* numericFieldType */ + Cable_FW_Vers, /* numericFieldType */ + Type_C_To_Type_A_B_C, /* numericFieldType */ + Type_C_To_Type_C_Capt_Vdm_V2, /* numericFieldType */ + EPR_Mode_Capable, /* booleanFieldType */ + Cable_Latency, /* numericFieldType */ + Cable_Termination_Type, /* numericFieldType */ + Cable_VBUS_Current, /* numericFieldType */ + VBUS_Through_Cable, /* booleanFieldType */ + Cable_Superspeed_Support, /* numericFieldType */ + Cable_USB_Highest_Speed, /* numericFieldType */ + Max_VBUS_Voltage_Vdm_V2, /* numericFieldType */ + Manufacturer_Info_Supported, /* booleanFieldType */ + Manufacturer_Info_VID, /* numericFieldType */ + Manufacturer_Info_PID, /* numericFieldType */ + Chunking_Implemented, /* booleanFieldType */ + Security_Msgs_Supported, /* booleanFieldType */ + ID_Header_Connector_Type, /* numericFieldType */ + Cable_Num_SVIDs_Min, /* numericFieldType */ + Cable_Num_SVIDs_Max, /* numericFieldType */ + SVID_Fixed, /* booleanFieldType */ /* 3.2.16 Active Cable Fields */ - Cable_SOP_PP_Controller, /* booleanFieldType */ - SBU_Supported, /* booleanFieldType */ - SBU_Type, /* numericFieldType */ - Active_Cable_Max_Operating_Temp, /* numericFieldType */ - Active_Cable_Shutdown_Temp, /* numericFieldType */ - Active_Cable_U3_CLd_Power, /* numericFieldType */ - Active_Cable_U3_U0_Trans_Mode, /* numericFieldType */ - Active_Cable_Physical_Connection, /* numericFieldType */ - Active_Cable_Active_Element, /* numericFieldType */ - Active_Cable_USB4_Support, /* booleanFieldType */ - Active_Cable_USB2_Supported, /* booleanFieldType */ - Active_Cable_USB2_Hub_Hops_Consumed, /* numericFieldType */ - Active_Cable_USB32_Supported, /* booleanFieldType */ - Active_Cable_USB_Lanes, /* numericFieldType */ - Active_Cable_Optically_Isolated, /* booleanFieldType */ - Active_Cable_USB_Gen, /* numericFieldType */ + Cable_SOP_PP_Controller, /* booleanFieldType */ + SBU_Supported, /* booleanFieldType */ + SBU_Type, /* numericFieldType */ + Active_Cable_Max_Operating_Temp, /* numericFieldType */ + Active_Cable_Shutdown_Temp, /* numericFieldType */ + Active_Cable_U3_CLd_Power, /* numericFieldType */ + Active_Cable_U3_U0_Trans_Mode, /* numericFieldType */ + Active_Cable_Physical_Connection, /* numericFieldType */ + Active_Cable_Active_Element, /* numericFieldType */ + Active_Cable_USB4_Support, /* booleanFieldType */ + Active_Cable_USB2_Supported, /* booleanFieldType */ + Active_Cable_USB2_Hub_Hops_Consumed, /* numericFieldType */ + Active_Cable_USB32_Supported, /* booleanFieldType */ + Active_Cable_USB_Lanes, /* numericFieldType */ + Active_Cable_Optically_Isolated, /* booleanFieldType */ + Active_Cable_USB_Gen, /* numericFieldType */ /* 3.2.17 VCONN Powered Devices */ - VPD_HW_Vers, /* numericFieldType */ - VPD_FW_Vers, /* numericFieldType */ - VPD_Max_VBUS_Voltage, /* numericFieldType */ - VPD_Charge_Through_Support, /* booleanFieldType */ - VPD_Charge_Through_Current, /* numericFieldType */ - VPD_VBUS_Impedance, /* numericFieldType */ - VPD_Ground_Impedance, /* numericFieldType */ + VPD_HW_Vers, /* numericFieldType */ + VPD_FW_Vers, /* numericFieldType */ + VPD_Max_VBUS_Voltage, /* numericFieldType */ + VPD_Charge_Through_Support, /* booleanFieldType */ + VPD_Charge_Through_Current, /* numericFieldType */ + VPD_VBUS_Impedance, /* numericFieldType */ + VPD_Ground_Impedance, /* numericFieldType */ /* 3.2.18 Repeater Fields */ - Repeater_One_Type, /* numericFieldType */ - Repeater_Two_Type, /* numericFieldType */ + Repeater_One_Type, /* numericFieldType */ + Repeater_Two_Type, /* numericFieldType */ Component_Indexes }; struct vif_Component_t { - struct vif_field_t vif_field[Component_Indexes]; + struct vif_field_t vif_field[Component_Indexes]; - struct vif_srcPdoList_t SrcPdoList[MAX_NUM_SRC_PDOS]; - struct vif_snkPdoList_t SnkPdoList[MAX_NUM_SNK_PDOS]; - struct vif_sopSVIDList_t SOPSVIDList[MAX_NUM_SOP_SVIDS]; - struct vif_cableSVIDList_t CableSVIDList[MAX_NUM_CABLE_SVIDS]; + struct vif_srcPdoList_t SrcPdoList[MAX_NUM_SRC_PDOS]; + struct vif_snkPdoList_t SnkPdoList[MAX_NUM_SNK_PDOS]; + struct vif_sopSVIDList_t SOPSVIDList[MAX_NUM_SOP_SVIDS]; + struct vif_cableSVIDList_t CableSVIDList[MAX_NUM_CABLE_SVIDS]; /* * The following fields are deprecated. They should not be written @@ -434,55 +434,55 @@ struct vif_Component_t { /* 3.2.2 Product Fields */ enum vif_Product_indexes { - USB4_Product_Header, /* comment */ - USB4_DROM_Vendor_ID, /* numericFieldType */ - USB4_Dock, /* booleanFieldType */ - USB4_Num_Internal_Host_Controllers, /* numericFieldType */ - USB4_Num_PCIe_DN_Bridges, /* numericFieldType */ - USB4_Device_HiFi_Bi_TMU_Mode_Required, /* booleanFieldType */ - USB4_Audio_Supported, /* booleanFieldType */ - USB4_HID_Supported, /* booleanFieldType */ - USB4_Printer_Supported, /* booleanFieldType */ - USB4_Mass_Storage_Supported, /* booleanFieldType */ - USB4_Video_Supported, /* booleanFieldType */ - USB4_Comms_Networking_Supported, /* booleanFieldType */ - USB4_Media_Transfer_Protocol_Supported, /* booleanFieldType */ - USB4_Smart_Card_Supported, /* booleanFieldType */ - USB4_Still_Image_Capture_Supported, /* booleanFieldType */ - USB4_Monitor_Device_Supported, /* booleanFieldType */ + USB4_Product_Header, /* comment */ + USB4_DROM_Vendor_ID, /* numericFieldType */ + USB4_Dock, /* booleanFieldType */ + USB4_Num_Internal_Host_Controllers, /* numericFieldType */ + USB4_Num_PCIe_DN_Bridges, /* numericFieldType */ + USB4_Device_HiFi_Bi_TMU_Mode_Required, /* booleanFieldType */ + USB4_Audio_Supported, /* booleanFieldType */ + USB4_HID_Supported, /* booleanFieldType */ + USB4_Printer_Supported, /* booleanFieldType */ + USB4_Mass_Storage_Supported, /* booleanFieldType */ + USB4_Video_Supported, /* booleanFieldType */ + USB4_Comms_Networking_Supported, /* booleanFieldType */ + USB4_Media_Transfer_Protocol_Supported, /* booleanFieldType */ + USB4_Smart_Card_Supported, /* booleanFieldType */ + USB4_Still_Image_Capture_Supported, /* booleanFieldType */ + USB4_Monitor_Device_Supported, /* booleanFieldType */ Product_Indexes }; struct vif_Product_t { - struct vif_field_t vif_field[Product_Indexes]; + struct vif_field_t vif_field[Product_Indexes]; struct vif_Usb4RouterListType_t USB4RouterList[MAX_NUM_USB4_ROUTERS]; }; enum vif_indexes { - VIF_Specification, /* version */ - Vendor_Name, /* nonEmptyString */ - Model_Part_Number, /* nonEmptyString */ - Product_Revision, /* nonEmptyString */ - TID, /* nonEmptyString */ - VIF_Product_Type, /* numericFieldType */ - Certification_Type, /* numericFieldType */ + VIF_Specification, /* version */ + Vendor_Name, /* nonEmptyString */ + Model_Part_Number, /* nonEmptyString */ + Product_Revision, /* nonEmptyString */ + TID, /* nonEmptyString */ + VIF_Product_Type, /* numericFieldType */ + Certification_Type, /* numericFieldType */ VIF_Indexes }; enum vif_app_indexes { - Vendor, /* nonEmptyString */ - Name, /* nonEmptyString */ - Version, /* version */ + Vendor, /* nonEmptyString */ + Name, /* nonEmptyString */ + Version, /* version */ VIF_App_Indexes }; struct vif_t { - struct vif_field_t vif_field[VIF_Indexes]; - struct vif_field_t vif_app_field[VIF_App_Indexes]; + struct vif_field_t vif_field[VIF_Indexes]; + struct vif_field_t vif_app_field[VIF_App_Indexes]; - struct vif_Product_t Product; - struct vif_Component_t Component[MAX_NUM_COMPONENTS]; + struct vif_Product_t Product; + struct vif_Component_t Component[MAX_NUM_COMPONENTS]; }; #endif /* __GENVIF_H__ */ diff --git a/util/getversion.sh b/util/getversion.sh index 3146b29c88..f096229db9 100755 --- a/util/getversion.sh +++ b/util/getversion.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2012 The Chromium OS Authors. All rights reserved. +# Copyright 2012 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # @@ -77,7 +77,7 @@ get_tree_version() { # Ex VCSID: 0.0.1-r1519-9b368af6a4943b90941471d0bdf7e7208788f898 if [[ -n "${VCSID}" ]]; then ghash="${VCSID##*-}" - vbase="1.1.9999-${ghash:0:7}" + vbase="v2.1.9999-${ghash:0:8}" else # then ultimately fails to "no_version" vbase="no_version" @@ -140,9 +140,11 @@ main() { if [[ -n "${values[1]}" ]]; then # From each modified repo get the most recently modified file. most_recent_file="$(git status --porcelain | \ - awk '$1 ~ /[M|A|?]/ {print $2}' | \ - xargs ls -t | head -1)" - most_recents+=("$(realpath "${most_recent_file}")") + awk '$1 ~ /[M|A|?]/ {print $2}' | \ + xargs -r ls -t | head -1)" + if [[ -n "${most_recent_file}" ]]; then + most_recents+=("$(realpath "${most_recent_file}")") + fi fi if [ "${component}" != "." ]; then ver+=" ${component}:" diff --git a/util/gpios_to_zephyr_dts.c b/util/gpios_to_zephyr_dts.c index 166c16dde7..d0e51b3e46 100644 --- a/util/gpios_to_zephyr_dts.c +++ b/util/gpios_to_zephyr_dts.c @@ -1,4 +1,4 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. +/* Copyright 2021 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ diff --git a/util/host_command_check.sh b/util/host_command_check.sh index f699803b2e..8dc8280cbd 100755 --- a/util/host_command_check.sh +++ b/util/host_command_check.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2017 The Chromium OS Authors. All rights reserved. +# Copyright 2017 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/util/ide-config.sh b/util/ide-config.sh index 25edca2407..a172cf5767 100755 --- a/util/ide-config.sh +++ b/util/ide-config.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2020 The Chromium OS Authors. All rights reserved. +# Copyright 2020 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # diff --git a/util/inject-keys.py b/util/inject-keys.py index bd10b693ad..7ff72ea134 100755 --- a/util/inject-keys.py +++ b/util/inject-keys.py @@ -1,57 +1,133 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# Copyright 2016 The Chromium OS Authors. All rights reserved. +# Copyright 2016 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # Note: This is a py2/3 compatible file. from __future__ import print_function + import string import subprocess import sys - -KEYMATRIX = {'`': (3, 1), '1': (6, 1), '2': (6, 4), '3': (6, 2), '4': (6, 3), - '5': (3, 3), '6': (3, 6), '7': (6, 6), '8': (6, 5), '9': (6, 9), - '0': (6, 8), '-': (3, 8), '=': (0, 8), 'q': (7, 1), 'w': (7, 4), - 'e': (7, 2), 'r': (7, 3), 't': (2, 3), 'y': (2, 6), 'u': (7, 6), - 'i': (7, 5), 'o': (7, 9), 'p': (7, 8), '[': (2, 8), ']': (2, 5), - '\\': (3, 11), 'a': (4, 1), 's': (4, 4), 'd': (4, 2), 'f': (4, 3), - 'g': (1, 3), 'h': (1, 6), 'j': (4, 6), 'k': (4, 5), 'l': (4, 9), - ';': (4, 8), '\'': (1, 8), 'z': (5, 1), 'x': (5, 4), 'c': (5, 2), - 'v': (5, 3), 'b': (0, 3), 'n': (0, 6), 'm': (5, 6), ',': (5, 5), - '.': (5, 9), '/': (5, 8), ' ': (5, 11), '<right>': (6, 12), - '<alt_r>': (0, 10), '<down>': (6, 11), '<tab>': (2, 1), - '<f10>': (0, 4), '<shift_r>': (7, 7), '<ctrl_r>': (4, 0), - '<esc>': (1, 1), '<backspace>': (1, 11), '<f2>': (3, 2), - '<alt_l>': (6, 10), '<ctrl_l>': (2, 0), '<f1>': (0, 2), - '<search>': (0, 1), '<f3>': (2, 2), '<f4>': (1, 2), '<f5>': (3, 4), - '<f6>': (2, 4), '<f7>': (1, 4), '<f8>': (2, 9), '<f9>': (1, 9), - '<up>': (7, 11), '<shift_l>': (5, 7), '<enter>': (4, 11), - '<left>': (7, 12)} - - -UNSHIFT_TABLE = { '~': '`', '!': '1', '@': '2', '#': '3', '$': '4', - '%': '5', '^': '6', '&': '7', '*': '8', '(': '9', - ')': '0', '_': '-', '+': '=', '{': '[', '}': ']', - '|': '\\', - ':': ';', '"': "'", '<': ',', '>': '.', '?': '/'} +KEYMATRIX = { + "`": (3, 1), + "1": (6, 1), + "2": (6, 4), + "3": (6, 2), + "4": (6, 3), + "5": (3, 3), + "6": (3, 6), + "7": (6, 6), + "8": (6, 5), + "9": (6, 9), + "0": (6, 8), + "-": (3, 8), + "=": (0, 8), + "q": (7, 1), + "w": (7, 4), + "e": (7, 2), + "r": (7, 3), + "t": (2, 3), + "y": (2, 6), + "u": (7, 6), + "i": (7, 5), + "o": (7, 9), + "p": (7, 8), + "[": (2, 8), + "]": (2, 5), + "\\": (3, 11), + "a": (4, 1), + "s": (4, 4), + "d": (4, 2), + "f": (4, 3), + "g": (1, 3), + "h": (1, 6), + "j": (4, 6), + "k": (4, 5), + "l": (4, 9), + ";": (4, 8), + "'": (1, 8), + "z": (5, 1), + "x": (5, 4), + "c": (5, 2), + "v": (5, 3), + "b": (0, 3), + "n": (0, 6), + "m": (5, 6), + ",": (5, 5), + ".": (5, 9), + "/": (5, 8), + " ": (5, 11), + "<right>": (6, 12), + "<alt_r>": (0, 10), + "<down>": (6, 11), + "<tab>": (2, 1), + "<f10>": (0, 4), + "<shift_r>": (7, 7), + "<ctrl_r>": (4, 0), + "<esc>": (1, 1), + "<backspace>": (1, 11), + "<f2>": (3, 2), + "<alt_l>": (6, 10), + "<ctrl_l>": (2, 0), + "<f1>": (0, 2), + "<search>": (0, 1), + "<f3>": (2, 2), + "<f4>": (1, 2), + "<f5>": (3, 4), + "<f6>": (2, 4), + "<f7>": (1, 4), + "<f8>": (2, 9), + "<f9>": (1, 9), + "<up>": (7, 11), + "<shift_l>": (5, 7), + "<enter>": (4, 11), + "<left>": (7, 12), +} + + +UNSHIFT_TABLE = { + "~": "`", + "!": "1", + "@": "2", + "#": "3", + "$": "4", + "%": "5", + "^": "6", + "&": "7", + "*": "8", + "(": "9", + ")": "0", + "_": "-", + "+": "=", + "{": "[", + "}": "]", + "|": "\\", + ":": ";", + '"': "'", + "<": ",", + ">": ".", + "?": "/", +} for c in string.ascii_lowercase: UNSHIFT_TABLE[c.upper()] = c def inject_event(key, press): - if len(key) >= 2 and key[0] != '<': - key = '<' + key + '>' + if len(key) >= 2 and key[0] != "<": + key = "<" + key + ">" if key not in KEYMATRIX: print("%s: invalid key: %s" % (this_script, key)) sys.exit(1) (row, col) = KEYMATRIX[key] - subprocess.call(["ectool", "kbpress", str(row), str(col), - "1" if press else "0"]) + subprocess.call( + ["ectool", "kbpress", str(row), str(col), "1" if press else "0"] + ) def inject_key(key): @@ -73,8 +149,10 @@ def inject_string(string): def usage(): - print("Usage: %s [-s <string>] [-k <key>]" % this_script, - "[-p <pressed-key>] [-r <released-key>] ...") + print( + "Usage: %s [-s <string>] [-k <key>]" % this_script, + "[-p <pressed-key>] [-r <released-key>] ...", + ) print("Examples:") print("%s -s MyPassw0rd -k enter" % this_script) print("%s -p ctrl_l -p alt_l -k f3 -r alt_l -r ctrl_l" % this_script) @@ -85,7 +163,7 @@ def help(): print("Valid keys are:") i = 0 for key in KEYMATRIX: - print("%12s" % key, end='') + print("%12s" % key, end="") i += 1 if i % 4 == 0: print() @@ -114,12 +192,14 @@ usage_check(arg_len > 1, "not enough arguments") usage_check(arg_len % 2 == 1, "mismatched arguments") for i in range(1, arg_len, 2): - usage_check(sys.argv[i] in ("-s", "-k", "-p", "-r"), - "unknown flag: %s" % sys.argv[i]) + usage_check( + sys.argv[i] in ("-s", "-k", "-p", "-r"), + "unknown flag: %s" % sys.argv[i], + ) for i in range(1, arg_len, 2): flag = sys.argv[i] - arg = sys.argv[i+1] + arg = sys.argv[i + 1] if flag == "-s": inject_string(arg) elif flag == "-k": diff --git a/util/iteflash.c b/util/iteflash.c index a4a166d3d8..9085365135 100644 --- a/util/iteflash.c +++ b/util/iteflash.c @@ -1,4 +1,4 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. +/* Copyright 2013 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -38,65 +38,65 @@ #define CR50_USB_PID 0x5014 /* Cr50 exposed properties of the USB I2C endpoint. */ -#define CR50_I2C_SUBCLASS 82 -#define CR50_I2C_PROTOCOL 1 +#define CR50_I2C_SUBCLASS 82 +#define CR50_I2C_PROTOCOL 1 -#define CROS_CMD_ADDR 0x78 /* USB_I2C_CMD_ADDR 0xF0 >> 1 */ -#define CROS_CMD_ITE_SYNC 0 +#define CROS_CMD_ADDR 0x78 /* USB_I2C_CMD_ADDR 0xF0 >> 1 */ +#define CROS_CMD_ITE_SYNC 0 /* DBGR I2C addresses */ -#define I2C_CMD_ADDR 0x5A -#define I2C_DATA_ADDR 0x35 +#define I2C_CMD_ADDR 0x5A +#define I2C_DATA_ADDR 0x35 #define I2C_BLOCK_ADDR 0x79 #define FTDI_I2C_FREQ 400000 /* I2C pins on the FTDI interface */ -#define SCL_BIT BIT(0) -#define SDA_BIT BIT(1) +#define SCL_BIT BIT(0) +#define SDA_BIT BIT(1) /* Chip ID register value */ #define CHIP_ID 0x8380 /* Embedded flash page size */ -#define PAGE_SIZE (1<<8) +#define PAGE_SIZE (1 << 8) /* Embedded flash block write size for different programming modes. */ -#define FTDI_BLOCK_WRITE_SIZE (1<<16) +#define FTDI_BLOCK_WRITE_SIZE (1 << 16) /* JEDEC SPI Flash commands */ -#define SPI_CMD_PAGE_PROGRAM 0x02 -#define SPI_CMD_WRITE_DISABLE 0x04 -#define SPI_CMD_READ_STATUS 0x05 -#define SPI_CMD_WRITE_ENABLE 0x06 -#define SPI_CMD_FAST_READ 0x0B -#define SPI_CMD_CHIP_ERASE 0x60 -#define SPI_CMD_SECTOR_ERASE_1K 0xD7 -#define SPI_CMD_SECTOR_ERASE_4K 0x20 -#define SPI_CMD_WORD_PROGRAM 0xAD -#define SPI_CMD_EWSR 0x50 /* Enable Write Status Register */ -#define SPI_CMD_WRSR 0x01 /* Write Status Register */ -#define SPI_CMD_RDID 0x9F /* Read Flash ID */ +#define SPI_CMD_PAGE_PROGRAM 0x02 +#define SPI_CMD_WRITE_DISABLE 0x04 +#define SPI_CMD_READ_STATUS 0x05 +#define SPI_CMD_WRITE_ENABLE 0x06 +#define SPI_CMD_FAST_READ 0x0B +#define SPI_CMD_CHIP_ERASE 0x60 +#define SPI_CMD_SECTOR_ERASE_1K 0xD7 +#define SPI_CMD_SECTOR_ERASE_4K 0x20 +#define SPI_CMD_WORD_PROGRAM 0xAD +#define SPI_CMD_EWSR 0x50 /* Enable Write Status Register */ +#define SPI_CMD_WRSR 0x01 /* Write Status Register */ +#define SPI_CMD_RDID 0x9F /* Read Flash ID */ /* Size for FTDI outgoing buffer */ -#define FTDI_CMD_BUF_SIZE (1<<12) +#define FTDI_CMD_BUF_SIZE (1 << 12) /* Reset Status */ -#define RSTS_VCCDO_PW_ON 0x40 -#define RSTS_VFSPIPG 0x20 -#define RSTS_HGRST 0x08 -#define RSTS_GRST 0x04 +#define RSTS_VCCDO_PW_ON 0x40 +#define RSTS_VFSPIPG 0x20 +#define RSTS_HGRST 0x08 +#define RSTS_GRST 0x04 /* I2C MUX Configuration: TCA9543 or PCA9546 */ -#define I2C_MUX_CMD_ADDR 0x70 -#define I2C_MUX_CMD_NONE 0x00 -#define I2C_MUX_CMD_INAS 0x01 -#define I2C_MUX_CMD_EC 0x02 +#define I2C_MUX_CMD_ADDR 0x70 +#define I2C_MUX_CMD_NONE 0x00 +#define I2C_MUX_CMD_INAS 0x01 +#define I2C_MUX_CMD_EC 0x02 /* Eflash Type*/ -#define EFLASH_TYPE_8315 0x01 -#define EFLASH_TYPE_KGD 0x02 -#define EFLASH_TYPE_NONE 0xFF +#define EFLASH_TYPE_8315 0x01 +#define EFLASH_TYPE_KGD 0x02 +#define EFLASH_TYPE_NONE 0xFF uint8_t eflash_type; uint8_t spi_cmd_sector_erase; @@ -104,7 +104,6 @@ uint8_t spi_cmd_sector_erase; /* Embedded flash number of pages in a sector erase */ uint8_t sector_erase_pages; - static volatile sig_atomic_t exit_requested; struct i2c_interface; @@ -113,17 +112,17 @@ struct i2c_interface; struct iteflash_config { char *input_filename; char *output_filename; - int send_waveform; /* boolean */ - int erase; /* boolean */ + int send_waveform; /* boolean */ + int erase; /* boolean */ int i2c_mux; /* boolean */ - int debug; /* boolean */ - int disable_watchdog; /* boolean */ - int disable_protect_path; /* boolean */ + int debug; /* boolean */ + int disable_watchdog; /* boolean */ + int disable_protect_path; /* boolean */ int block_write_size; int usb_interface; int usb_vid; int usb_pid; - int verify; /* boolean */ + int verify; /* boolean */ char *usb_serial; char *i2c_dev_path; const struct i2c_interface *i2c_if; @@ -134,8 +133,8 @@ struct iteflash_config { struct common_hnd { struct iteflash_config conf; int flash_size; - int flash_cmd_v2; /* boolean */ - int dbgr_addr_3bytes; /* boolean */ + int flash_cmd_v2; /* boolean */ + int dbgr_addr_3bytes; /* boolean */ union { int i2c_dev_fd; struct usb_endpoint uep; @@ -162,13 +161,13 @@ struct i2c_interface { int (*send_special_waveform)(struct common_hnd *chnd); /* Required, must not be NULL. */ int (*byte_transfer)(struct common_hnd *chnd, uint8_t addr, - uint8_t *data, int write, int numbytes); + uint8_t *data, int write, int numbytes); /* Required, must be positive. */ int default_block_write_size; }; -static int spi_flash_command_short(struct common_hnd *chnd, - uint8_t cmd, char *desc); +static int spi_flash_command_short(struct common_hnd *chnd, uint8_t cmd, + char *desc); static void null_and_free(void **ptr) { @@ -192,7 +191,7 @@ static void config_release(struct iteflash_config *conf) } /* number of bytes to send consecutively before checking for ACKs */ -#define FTDI_TX_BUFFER_LIMIT 32 +#define FTDI_TX_BUFFER_LIMIT 32 static inline int i2c_byte_transfer(struct common_hnd *chnd, uint8_t addr, uint8_t *data, int write, int numbytes) @@ -202,7 +201,7 @@ static inline int i2c_byte_transfer(struct common_hnd *chnd, uint8_t addr, return -1; return chnd->conf.i2c_if->byte_transfer(chnd, addr, data, write, - numbytes); + numbytes); } static int linux_i2c_byte_transfer(struct common_hnd *chnd, uint8_t addr, @@ -225,8 +224,10 @@ static int linux_i2c_byte_transfer(struct common_hnd *chnd, uint8_t addr, ret = ioctl(chnd->i2c_dev_fd, I2C_RDWR, &msgset); if (ret < 0) { extra_int = errno; - fprintf(stderr, "%s: ioctl() failed with return value %d and " - "errno %d\n", __func__, ret, extra_int); + fprintf(stderr, + "%s: ioctl() failed with return value %d and " + "errno %d\n", + __func__, ret, extra_int); if (ret == -1 && extra_int) ret = -abs(extra_int); } else if (ret < nmsgs) { @@ -250,12 +251,17 @@ static int i2c_add_send_byte(struct ftdi_context *ftdi, uint8_t *buf, for (i = 0; i < tcnt; i++) { /* WORKAROUND: force SDA before sending the next byte */ - *b++ = SET_BITS_LOW; *b++ = SDA_BIT; *b++ = SCL_BIT | SDA_BIT; + *b++ = SET_BITS_LOW; + *b++ = SDA_BIT; + *b++ = SCL_BIT | SDA_BIT; /* write byte */ *b++ = MPSSE_DO_WRITE | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *b++ = 0x07; *b++ = *tbuf++; + *b++ = 0x07; + *b++ = *tbuf++; /* prepare for ACK */ - *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SCL_BIT; + *b++ = SET_BITS_LOW; + *b++ = 0; + *b++ = SCL_BIT; /* read ACK */ *b++ = MPSSE_DO_READ | MPSSE_BITMODE | MPSSE_LSB; *b++ = 0; @@ -267,7 +273,7 @@ static int i2c_add_send_byte(struct ftdi_context *ftdi, uint8_t *buf, * On the last byte, or every FTDI_TX_BUFFER_LIMIT bytes, read * the ACK bits. */ - if (i == tcnt-1 || (tx_buffered == FTDI_TX_BUFFER_LIMIT)) { + if (i == tcnt - 1 || (tx_buffered == FTDI_TX_BUFFER_LIMIT)) { /* write data */ ret = ftdi_write_data(ftdi, buf, b - buf); if (ret < 0) { @@ -280,7 +286,7 @@ static int i2c_add_send_byte(struct ftdi_context *ftdi, uint8_t *buf, ack_idx = 0; do { ret = ftdi_read_data(ftdi, &ack[ack_idx], - remaining_data); + remaining_data); if (ret < 0) { fprintf(stderr, "read ACK failed\n"); return ret; @@ -299,7 +305,7 @@ static int i2c_add_send_byte(struct ftdi_context *ftdi, uint8_t *buf, fprintf(stderr, "write ACK fail: %d, 0x%02x\n", ret, failed_ack); - return -ENXIO; + return -ENXIO; } /* reset for next set of transactions */ @@ -318,20 +324,32 @@ static int i2c_add_recv_bytes(struct ftdi_context *ftdi, uint8_t *buf, for (i = 0; i < rcnt; i++) { /* set SCL low */ - *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SCL_BIT; + *b++ = SET_BITS_LOW; + *b++ = 0; + *b++ = SCL_BIT; /* read the byte on the wire */ - *b++ = MPSSE_DO_READ; *b++ = 0; *b++ = 0; + *b++ = MPSSE_DO_READ; + *b++ = 0; + *b++ = 0; if (i == rcnt - 1) { /* NACK last byte */ - *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SCL_BIT; + *b++ = SET_BITS_LOW; + *b++ = 0; + *b++ = SCL_BIT; *b++ = MPSSE_DO_WRITE | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *b++ = 0; *b++ = 0xff; *b++ = SEND_IMMEDIATE; + *b++ = 0; + *b++ = 0xff; + *b++ = SEND_IMMEDIATE; } else { /* ACK all other bytes */ - *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SCL_BIT | SDA_BIT; + *b++ = SET_BITS_LOW; + *b++ = 0; + *b++ = SCL_BIT | SDA_BIT; *b++ = MPSSE_DO_WRITE | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *b++ = 0; *b++ = 0; *b++ = SEND_IMMEDIATE; + *b++ = 0; + *b++ = 0; + *b++ = SEND_IMMEDIATE; } } @@ -401,7 +419,7 @@ static int ccd_i2c_byte_transfer(struct common_hnd *chnd, uint8_t addr, write ? sizeof(usb_buffer) : USB_I2C_HEADER_SIZE + extra, usb_buffer, sizeof(usb_buffer), 1, &response_size); - if (response_size < (USB_I2C_HEADER_SIZE + (write ? 0 : numbytes))) { + if (response_size < (USB_I2C_HEADER_SIZE + (write ? 0 : numbytes))) { fprintf(stderr, "%s: got too few bytes (%zd) in response\n", __func__, response_size); return -1; @@ -417,8 +435,7 @@ static int ccd_i2c_byte_transfer(struct common_hnd *chnd, uint8_t addr, rv = usb_buffer[1]; rv = (rv << 8) + usb_buffer[0]; - fprintf(stderr, "%s: usb i2c error %d\n", - __func__, + fprintf(stderr, "%s: usb i2c error %d\n", __func__, (((uint16_t)usb_buffer[1]) << 8) + usb_buffer[0]); return -rv; @@ -445,14 +462,26 @@ static int ftdi_i2c_byte_transfer(struct common_hnd *chnd, uint8_t addr, /* START condition */ /* SCL & SDA high */ - *b++ = SET_BITS_LOW; *b++ = 0; *b++ = 0; - *b++ = SET_BITS_LOW; *b++ = 0; *b++ = 0; + *b++ = SET_BITS_LOW; + *b++ = 0; + *b++ = 0; + *b++ = SET_BITS_LOW; + *b++ = 0; + *b++ = 0; /* SCL high, SDA low */ - *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SDA_BIT; - *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SDA_BIT; + *b++ = SET_BITS_LOW; + *b++ = 0; + *b++ = SDA_BIT; + *b++ = SET_BITS_LOW; + *b++ = 0; + *b++ = SDA_BIT; /* SCL low, SDA low */ - *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SCL_BIT | SDA_BIT; - *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SCL_BIT | SDA_BIT; + *b++ = SET_BITS_LOW; + *b++ = 0; + *b++ = SCL_BIT | SDA_BIT; + *b++ = SET_BITS_LOW; + *b++ = 0; + *b++ = SCL_BIT | SDA_BIT; /* send address */ slave_addr = (addr << 1) | (write ? 0 : 1); @@ -467,7 +496,7 @@ static int ftdi_i2c_byte_transfer(struct common_hnd *chnd, uint8_t addr, b = buf; if (write) /* write data */ ret = i2c_add_send_byte(ftdi, buf, b, data, numbytes, - chnd->conf.debug); + chnd->conf.debug); else /* read data */ ret = i2c_add_recv_bytes(ftdi, buf, b, data, numbytes); @@ -475,11 +504,19 @@ exit_xfer: b = buf; /* STOP condition */ /* SCL high, SDA low */ - *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SDA_BIT; - *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SDA_BIT; + *b++ = SET_BITS_LOW; + *b++ = 0; + *b++ = SDA_BIT; + *b++ = SET_BITS_LOW; + *b++ = 0; + *b++ = SDA_BIT; /* SCL high, SDA high */ - *b++ = SET_BITS_LOW; *b++ = 0; *b++ = 0; - *b++ = SET_BITS_LOW; *b++ = 0; *b++ = 0; + *b++ = SET_BITS_LOW; + *b++ = 0; + *b++ = 0; + *b++ = SET_BITS_LOW; + *b++ = 0; + *b++ = 0; rets = ftdi_write_data(ftdi, buf, b - buf); if (rets < 0) @@ -549,21 +586,16 @@ static int check_flashid(struct common_hnd *chnd) { int ret = 0; uint8_t id[16], i; - struct cmds commands[] = { - {0x07, 0x7f}, - {0x06, 0xff}, - {0x04, 0x00}, - {0x05, 0xfe}, - {0x08, 0x00}, - {0x05, 0xfd}, - {0x08, 0x9f} - }; + struct cmds commands[] = { { 0x07, 0x7f }, { 0x06, 0xff }, + { 0x04, 0x00 }, { 0x05, 0xfe }, + { 0x08, 0x00 }, { 0x05, 0xfd }, + { 0x08, 0x9f } }; for (i = 0; i < ARRAY_SIZE(commands); i++) { ret = i2c_write_byte(chnd, commands[i].addr, commands[i].cmd); if (ret) { fprintf(stderr, "Flash ID Failed : cmd %x ,data %x\n", - commands[i].addr, commands[i].cmd); + commands[i].addr, commands[i].cmd); return ret; } } @@ -595,7 +627,7 @@ static int check_chipid(struct common_hnd *chnd) int ret; uint8_t ver = 0xff; uint32_t id = 0xffff; - uint16_t v2[7] = {128, 192, 256, 384, 512, 0, 1024}; + uint16_t v2[7] = { 128, 192, 256, 384, 512, 0, 1024 }; /* * Chip Version is mapping from bit 3-0 * Flash size is mapping from bit 7-4 @@ -637,7 +669,7 @@ static int check_chipid(struct common_hnd *chnd) if ((id & 0xff00) != (CHIP_ID & 0xff00)) { id |= 0xff0000; - ret = get_3rd_chip_id_byte(chnd, (uint8_t *)&id+2); + ret = get_3rd_chip_id_byte(chnd, (uint8_t *)&id + 2); if (ret < 0) return ret; @@ -657,7 +689,7 @@ static int check_chipid(struct common_hnd *chnd) } /* compute embedded flash size from CHIPVER field */ if (chnd->flash_cmd_v2) - chnd->flash_size = v2[(ver & 0xF0)>>5] * 1024; + chnd->flash_size = v2[(ver & 0xF0) >> 5] * 1024; else chnd->flash_size = (128 + (ver & 0xF0)) * 1024; @@ -667,29 +699,7 @@ static int check_chipid(struct common_hnd *chnd) } printf("CHIPID %05x, CHIPVER %02x, Flash size %d kB\n", id, ver, - chnd->flash_size / 1024); - - return 0; -} - -/* DBGR Reset */ -static int dbgr_reset(struct common_hnd *chnd, unsigned char val) -{ - int ret = 0; - - /* Reset CPU only, and we keep power state until flashing is done. */ - if (chnd->dbgr_addr_3bytes) - ret |= i2c_write_byte(chnd, 0x80, 0xf0); - - ret |= i2c_write_byte(chnd, 0x2f, 0x20); - ret |= i2c_write_byte(chnd, 0x2e, 0x06); - - /* Enable the Reset Status by val */ - ret |= i2c_write_byte(chnd, 0x30, val); - - ret |= i2c_write_byte(chnd, 0x27, 0x80); - if (ret < 0) - fprintf(stderr, "DBGR RESET FAILED\n"); + chnd->flash_size / 1024); return 0; } @@ -761,7 +771,7 @@ static int dbgr_disable_protect_path(struct common_hnd *chnd) ret |= i2c_write_byte(chnd, 0x2f, 0x20); for (i = 0; i < 32; i++) { - ret |= i2c_write_byte(chnd, 0x2e, 0xa0+i); + ret |= i2c_write_byte(chnd, 0x2e, 0xa0 + i); ret |= i2c_write_byte(chnd, 0x30, 0); } @@ -800,8 +810,8 @@ static int spi_flash_follow_mode_exit(struct common_hnd *chnd, char *desc) ret = (ret ? -EIO : 0); if (ret < 0) - fprintf(stderr, "Flash %s exit follow mode FAILED (%d)\n", - desc, ret); + fprintf(stderr, "Flash %s exit follow mode FAILED (%d)\n", desc, + ret); return ret; } @@ -821,8 +831,8 @@ static int dbgr_stop_ec(struct common_hnd *chnd) } /* SPI Flash generic command, short version */ -static int spi_flash_command_short(struct common_hnd *chnd, - uint8_t cmd, char *desc) +static int spi_flash_command_short(struct common_hnd *chnd, uint8_t cmd, + char *desc) { int ret = 0; @@ -839,8 +849,8 @@ static int spi_flash_command_short(struct common_hnd *chnd, } /* SPI Flash set erase page */ -static int spi_flash_set_erase_page(struct common_hnd *chnd, - int page, char *desc) +static int spi_flash_set_erase_page(struct common_hnd *chnd, int page, + char *desc) { int ret = 0; @@ -862,7 +872,7 @@ static int spi_poll_busy(struct common_hnd *chnd, char *desc) int ret = -EIO; if (spi_flash_command_short(chnd, SPI_CMD_READ_STATUS, - "read status for busy bit") < 0) { + "read status for busy bit") < 0) { fprintf(stderr, "Flash %s wait busy cleared FAILED\n", desc); goto failed_read_status; } @@ -889,7 +899,7 @@ static int spi_check_write_enable(struct common_hnd *chnd, char *desc) int ret = -EIO; if (spi_flash_command_short(chnd, SPI_CMD_READ_STATUS, - "read status for write enable bit") < 0) { + "read status for write enable bit") < 0) { fprintf(stderr, "Flash %s wait WE FAILED\n", desc); goto failed_read_status; } @@ -915,12 +925,8 @@ static int ftdi_config_i2c(struct ftdi_context *ftdi) int ret; static const uint16_t divisor = 60000000 / (2 * FTDI_I2C_FREQ * 3 / 2 /* 3-phase CLK */) - 1; - uint8_t clock_buf[] = { - EN_3_PHASE, - DIS_DIV_5, - TCK_DIVISOR, - divisor & 0xff, - divisor >> 8}; + uint8_t clock_buf[] = { EN_3_PHASE, DIS_DIV_5, TCK_DIVISOR, + divisor & 0xff, divisor >> 8 }; ret = ftdi_set_latency_timer(ftdi, 16 /* ms */); if (ret < 0) @@ -951,7 +957,7 @@ static int ftdi_config_i2c(struct ftdi_context *ftdi) /* Special waveform definition */ #define SPECIAL_LEN_USEC 50000ULL /* us */ -#define SPECIAL_FREQ 400000ULL +#define SPECIAL_FREQ 400000ULL #define SPECIAL_PATTERN 0x0000020301010302ULL #define SPECIAL_PATTERN_SDA_L_SCL_L 0x0000000000000000ULL @@ -960,7 +966,7 @@ static int ftdi_config_i2c(struct ftdi_context *ftdi) #define SPECIAL_PATTERN_SDA_H_SCL_H 0x0303030303030303ULL #define TICK_COUNT 24 -#define MSEC 1000 +#define MSEC 1000 #define USEC 1000000 #define SPECIAL_BUFFER_SIZE \ @@ -975,8 +981,8 @@ static int connect_to_ccd_i2c_bridge(struct common_hnd *chnd) CR50_I2C_PROTOCOL, &chnd->uep); if (rv) { - fprintf(stderr, "%s: usb_findit returned error %d\n", - __func__, rv); + fprintf(stderr, "%s: usb_findit returned error %d\n", __func__, + rv); } return rv; @@ -986,13 +992,11 @@ static int ccd_trigger_special_waveform(struct common_hnd *chnd) { uint8_t response[20]; size_t rsize; - uint8_t req[] = { - 0, /* Port 0. Might be necessary to modify. */ - CROS_CMD_ADDR, /* Chrome OS dedicated address. */ - 1, /* Will send a single byte command. */ - 0, /* No need to read back anything. */ - CROS_CMD_ITE_SYNC - }; + uint8_t req[] = { 0, /* Port 0. Might be necessary to modify. */ + CROS_CMD_ADDR, /* Chrome OS dedicated address. */ + 1, /* Will send a single byte command. */ + 0, /* No need to read back anything. */ + CROS_CMD_ITE_SYNC }; usb_trx(&chnd->uep, req, sizeof(req), response, sizeof(response), 1, &rsize); @@ -1019,7 +1023,7 @@ static int ftdi_send_special_waveform(struct common_hnd *chnd) int i; uint64_t *wave; struct ftdi_context *ftdi = chnd->ftdi_hnd; - uint8_t release_lines[] = {SET_BITS_LOW, 0, 0}; + uint8_t release_lines[] = { SET_BITS_LOW, 0, 0 }; wave = malloc(SPECIAL_BUFFER_SIZE); if (!wave) { @@ -1058,7 +1062,7 @@ static int ftdi_send_special_waveform(struct common_hnd *chnd) usleep(5000); /* program each special tick */ - for (i = 0; i < TICK_COUNT; ) { + for (i = 0; i < TICK_COUNT;) { wave[i++] = SPECIAL_PATTERN_SDA_L_SCL_L; wave[i++] = SPECIAL_PATTERN_SDA_H_SCL_L; wave[i++] = SPECIAL_PATTERN_SDA_L_SCL_L; @@ -1082,7 +1086,7 @@ static int ftdi_send_special_waveform(struct common_hnd *chnd) ftdi_config_i2c(ftdi); ftdi_write_data(ftdi, release_lines, sizeof(release_lines)); - free_and_return: +free_and_return: free(wave); return ret; } @@ -1094,7 +1098,8 @@ static int send_special_waveform(struct common_hnd *chnd) int iterations; if (!chnd->conf.i2c_if->send_special_waveform) { - fprintf(stderr, "This binary does not support sending the ITE " + fprintf(stderr, + "This binary does not support sending the ITE " "special waveform with the chosen I2C interface.\n"); return -1; } @@ -1120,7 +1125,7 @@ static int send_special_waveform(struct common_hnd *chnd) ret = -1; if (!(iterations % max_iterations)) fprintf(stderr, "!please reset EC if flashing" - " sequence is not starting!\n"); + " sequence is not starting!\n"); } } while (ret && (iterations++ < max_iterations)); @@ -1133,10 +1138,10 @@ static int send_special_waveform(struct common_hnd *chnd) } static int windex; -static const char wheel[] = {'|', '/', '-', '\\' }; +static const char wheel[] = { '|', '/', '-', '\\' }; static void draw_spinner(uint32_t remaining, uint32_t size) { - int percent = (size - remaining)*100/size; + int percent = (size - remaining) * 100 / size; fprintf(stderr, "\r%c%3d%%", wheel[windex++], percent); windex %= sizeof(wheel); } @@ -1151,8 +1156,8 @@ static int spi_send_cmd_fast_read(struct common_hnd *chnd, uint32_t addr) ret = spi_flash_command_short(chnd, SPI_CMD_FAST_READ, "fast read"); /* Send address */ ret |= i2c_write_byte(chnd, 0x08, ((addr >> 16) & 0xff)); /* addr_h */ - ret |= i2c_write_byte(chnd, 0x08, ((addr >> 8) & 0xff)); /* addr_m */ - ret |= i2c_write_byte(chnd, 0x08, (addr & 0xff)); /* addr_l */ + ret |= i2c_write_byte(chnd, 0x08, ((addr >> 8) & 0xff)); /* addr_m */ + ret |= i2c_write_byte(chnd, 0x08, (addr & 0xff)); /* addr_l */ /* fake byte */ ret |= i2c_write_byte(chnd, 0x08, 0x00); /* use i2c block read command */ @@ -1171,8 +1176,10 @@ static int command_read_pages(struct common_hnd *chnd, uint32_t address, int cnt; if (address & 0xFF) { - fprintf(stderr, "page read requested at non-page boundary: " - "0x%X\n", address); + fprintf(stderr, + "page read requested at non-page boundary: " + "0x%X\n", + address); return -EINVAL; } @@ -1238,8 +1245,8 @@ static int command_write_pages(struct common_hnd *chnd, uint32_t address, goto failed_write; while (remaining) { - cnt = (remaining > block_write_size) ? - block_write_size : remaining; + cnt = (remaining > block_write_size) ? block_write_size : + remaining; addr_H = (address >> 16) & 0xFF; addr_M = (address >> 8) & 0xFF; addr_L = address & 0xFF; @@ -1248,7 +1255,7 @@ static int command_write_pages(struct common_hnd *chnd, uint32_t address, /* Write enable */ if (spi_flash_command_short(chnd, SPI_CMD_WRITE_ENABLE, - "write enable for AAI write") < 0) + "write enable for AAI write") < 0) goto failed_write; /* Check write enable bit */ @@ -1257,7 +1264,7 @@ static int command_write_pages(struct common_hnd *chnd, uint32_t address, /* Setup write */ if (spi_flash_command_short(chnd, SPI_CMD_WORD_PROGRAM, - "AAI write") < 0) + "AAI write") < 0) goto failed_write; /* Set eflash page address */ @@ -1266,7 +1273,7 @@ static int command_write_pages(struct common_hnd *chnd, uint32_t address, res |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, &addr_L, 1, 1); if (res < 0) { fprintf(stderr, "Flash write set page FAILED (%d)\n", - res); + res); goto failed_write; } @@ -1289,13 +1296,13 @@ static int command_write_pages(struct common_hnd *chnd, uint32_t address, res |= i2c_write_byte(chnd, 0x10, 0x00); if (res < 0) { fprintf(stderr, "Flash end data write FAILED (%d)\n", - res); + res); goto failed_write; } /* Write disable */ if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE, - "write disable for AAI write") < 0) + "write disable for AAI write") < 0) goto failed_write; /* Wait until available */ @@ -1310,7 +1317,7 @@ static int command_write_pages(struct common_hnd *chnd, uint32_t address, res = size; failed_write: if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE, - "write disable exit AAI write") < 0) + "write disable exit AAI write") < 0) res = -EIO; if (spi_flash_follow_mode_exit(chnd, "AAI write") < 0) @@ -1330,13 +1337,13 @@ static int command_write_pages3(struct common_hnd *chnd, uint32_t address, /* SMB_SPI_Flash_Write_Enable */ if (spi_flash_command_short(chnd, SPI_CMD_WRITE_ENABLE, - "SPI Command Write Enable") < 0) { + "SPI Command Write Enable") < 0) { ret = -EIO; goto failed_write; } if (spi_flash_command_short(chnd, SPI_CMD_PAGE_PROGRAM, - "SPI_CMD_PAGE_PROGRAM") < 0) { + "SPI_CMD_PAGE_PROGRAM") < 0) { ret = -EIO; goto failed_write; } @@ -1361,8 +1368,6 @@ failed_write: return ret; } - - static int command_erase(struct common_hnd *chnd, uint32_t len, uint32_t off) { int res = -EIO; @@ -1383,7 +1388,7 @@ static int command_erase(struct common_hnd *chnd, uint32_t len, uint32_t off) draw_spinner(remaining, len); if (spi_flash_command_short(chnd, SPI_CMD_WRITE_ENABLE, - "write enable for erase") < 0) + "write enable for erase") < 0) goto failed_erase; if (spi_check_write_enable(chnd, "erase") < 0) @@ -1392,28 +1397,28 @@ static int command_erase(struct common_hnd *chnd, uint32_t len, uint32_t off) /* do chip erase */ if (remaining == chnd->flash_size) { if (spi_flash_command_short(chnd, SPI_CMD_CHIP_ERASE, - "chip erase") < 0) + "chip erase") < 0) goto failed_erase; goto wait_busy_cleared; } /* do sector erase */ if (spi_flash_command_short(chnd, spi_cmd_sector_erase, - "sector erase") < 0) + "sector erase") < 0) goto failed_erase; if (spi_flash_set_erase_page(chnd, page, "sector erase") < 0) goto failed_erase; -wait_busy_cleared: + wait_busy_cleared: if (spi_poll_busy(chnd, "erase") < 0) goto failed_erase; if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE, - "write disable for erase") < 0) + "write disable for erase") < 0) goto failed_erase; - if (remaining == chnd->flash_size) { + if (remaining == chnd->flash_size) { remaining = 0; draw_spinner(remaining, len); } else { @@ -1428,7 +1433,7 @@ wait_busy_cleared: failed_erase: if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE, - "write disable exit erase") < 0) + "write disable exit erase") < 0) res = -EIO; if (spi_flash_follow_mode_exit(chnd, "erase") < 0) @@ -1443,8 +1448,8 @@ failed_erase: * reset issue while flash. * Add such function to prevent the reset issue. */ -static int command_erase2(struct common_hnd *chnd, uint32_t len, - uint32_t off, uint32_t reset) +static int command_erase2(struct common_hnd *chnd, uint32_t len, uint32_t off, + uint32_t reset) { int res = -EIO; int page = 0; @@ -1468,11 +1473,10 @@ static int command_erase2(struct common_hnd *chnd, uint32_t len, goto failed_erase; while (remaining) { - draw_spinner(remaining, len); if (spi_flash_command_short(chnd, SPI_CMD_WRITE_ENABLE, - "write enable for erase") < 0) + "write enable for erase") < 0) goto failed_erase; if (spi_check_write_enable(chnd, "erase") < 0) @@ -1480,7 +1484,7 @@ static int command_erase2(struct common_hnd *chnd, uint32_t len, /* do sector erase */ if (spi_flash_command_short(chnd, spi_cmd_sector_erase, - "sector erase") < 0) + "sector erase") < 0) goto failed_erase; if (spi_flash_set_erase_page(chnd, page, "sector erase") < 0) @@ -1490,7 +1494,7 @@ static int command_erase2(struct common_hnd *chnd, uint32_t len, goto failed_erase; if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE, - "write disable for erase") < 0) + "write disable for erase") < 0) goto failed_erase; if (reset) { @@ -1501,7 +1505,6 @@ static int command_erase2(struct common_hnd *chnd, uint32_t len, page += sector_erase_pages; remaining -= sector_erase_pages * PAGE_SIZE; draw_spinner(remaining, len); - } /* No error so far */ @@ -1510,7 +1513,7 @@ static int command_erase2(struct common_hnd *chnd, uint32_t len, failed_erase: if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE, - "write disable exit erase") < 0) + "write disable exit erase") < 0) res = -EIO; if (spi_flash_follow_mode_exit(chnd, "erase") < 0) @@ -1604,8 +1607,10 @@ static int write_flash(struct common_hnd *chnd, const char *filename, } res = fread(buffer, 1, size, hnd); if (res <= 0) { - fprintf(stderr, "%s: Failed to read %d bytes from %s with " - "ferror() %d\n", __func__, size, filename, ferror(hnd)); + fprintf(stderr, + "%s: Failed to read %d bytes from %s with " + "ferror() %d\n", + __func__, size, filename, ferror(hnd)); free(buffer); fclose(hnd); return -EIO; @@ -1658,8 +1663,10 @@ static int write_flash2(struct common_hnd *chnd, const char *filename, } res = fread(buffer, 1, size, hnd); if (res <= 0) { - fprintf(stderr, "%s: Failed to read %d bytes from %s with " - "ferror() %d\n", __func__, size, filename, ferror(hnd)); + fprintf(stderr, + "%s: Failed to read %d bytes from %s with " + "ferror() %d\n", + __func__, size, filename, ferror(hnd)); fclose(hnd); free(buffer); return -EIO; @@ -1689,7 +1696,8 @@ __send_aai_cmd: ret |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, &addr_l, 1, 1); /* Send first two bytes of buffe */ ret |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, &buffer[offset], 1, 1); - ret |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, &buffer[offset+1], 1, 1); + ret |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, &buffer[offset + 1], 1, + 1); /* we had sent two bytes */ offset += 2; res -= 2; @@ -1711,8 +1719,8 @@ __send_aai_cmd: two_bytes_sent = 0; cnt -= 2; } - if (i2c_byte_transfer(chnd, I2C_BLOCK_ADDR, &buffer[offset], - 1, cnt) < 0) { + if (i2c_byte_transfer(chnd, I2C_BLOCK_ADDR, &buffer[offset], 1, + cnt) < 0) { ret = -EIO; goto failed_write; } @@ -1728,7 +1736,7 @@ __send_aai_cmd: i2c_write_byte(chnd, 0x10, 0x00); /* write disable command */ spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE, - "SPI write disable"); + "SPI write disable"); goto __send_aai_cmd; } } @@ -1739,7 +1747,7 @@ failed_write: i2c_write_byte(chnd, 0x10, 0x00); /* write disable command */ spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE, - "SPI write disable"); + "SPI write disable"); failed_enter_mode: /* exit follow mode */ spi_flash_follow_mode_exit(chnd, "AAI write"); @@ -1786,8 +1794,10 @@ static int write_flash3(struct common_hnd *chnd, const char *filename, } res = fread(buf, 1, size, hnd); if (res <= 0) { - fprintf(stderr, "%s: Failed to read %d bytes from %s with " - "ferror() %d\n", __func__, size, filename, ferror(hnd)); + fprintf(stderr, + "%s: Failed to read %d bytes from %s with " + "ferror() %d\n", + __func__, size, filename, ferror(hnd)); fclose(hnd); free(buf); return -EIO; @@ -1809,8 +1819,8 @@ static int write_flash3(struct common_hnd *chnd, const char *filename, cnt = (res > block_write_size) ? block_write_size : res; if (chnd->conf.erase && is_empty_page(&buf[offset], cnt)) { /* do nothing */ - } else if (command_write_pages3(chnd, offset, cnt, &buf[offset]) - < 0) { + } else if (command_write_pages3(chnd, offset, cnt, + &buf[offset]) < 0) { ret = -EIO; goto failed_write; } @@ -1823,7 +1833,7 @@ static int write_flash3(struct common_hnd *chnd, const char *filename, failed_write: free(buf); spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE, - "SPI write disable"); + "SPI write disable"); spi_flash_follow_mode_exit(chnd, "Page program"); if (ret < 0) fprintf(stderr, "%s: Error writing to flash\n", __func__); @@ -1833,8 +1843,6 @@ failed_write: return ret; } - - /* Return zero on success, a non-zero value on failures. */ static int verify_flash(struct common_hnd *chnd, const char *filename, uint32_t offset) @@ -1842,7 +1850,7 @@ static int verify_flash(struct common_hnd *chnd, const char *filename, int res; int file_size; FILE *hnd; - uint8_t *buffer = malloc(chnd->flash_size); + uint8_t *buffer = malloc(chnd->flash_size); uint8_t *buffer2 = malloc(chnd->flash_size); if (!buffer || !buffer2) { @@ -1863,9 +1871,10 @@ static int verify_flash(struct common_hnd *chnd, const char *filename, file_size = fread(buffer, 1, chnd->flash_size, hnd); if (file_size <= 0) { - fprintf(stderr, "%s: Failed to read %d bytes from %s with " - "ferror() %d\n", __func__, chnd->flash_size, filename, - ferror(hnd)); + fprintf(stderr, + "%s: Failed to read %d bytes from %s with " + "ferror() %d\n", + __func__, chnd->flash_size, filename, ferror(hnd)); fclose(hnd); res = -EIO; goto exit; @@ -1885,8 +1894,8 @@ exit: return res; } -static struct ftdi_context *open_ftdi_device(int vid, int pid, - int interface, const char *serial) +static struct ftdi_context *open_ftdi_device(int vid, int pid, int interface, + const char *serial) { struct ftdi_context *ftdi; int ret; @@ -1926,17 +1935,19 @@ static int linux_i2c_interface_init(struct common_hnd *chnd) return -1; } printf("Attempting to open Linux i2c-dev path %s\n", - chnd->conf.i2c_dev_path); + chnd->conf.i2c_dev_path); chnd->i2c_dev_fd = open(chnd->conf.i2c_dev_path, O_RDWR); if (chnd->i2c_dev_fd < 0) { err = errno; perror("Failed to open Linux i2c-dev file path with error"); - fprintf(stderr, "Linux i2c-dev file path from --i2c_dev_path " - "is: %s\n", chnd->conf.i2c_dev_path); + fprintf(stderr, + "Linux i2c-dev file path from --i2c_dev_path " + "is: %s\n", + chnd->conf.i2c_dev_path); return err ? err : -1; } printf("Successfully opened Linux i2c-dev path %s\n", - chnd->conf.i2c_dev_path); + chnd->conf.i2c_dev_path); return 0; } @@ -1945,15 +1956,15 @@ static int linux_i2c_interface_shutdown(struct common_hnd *chnd) int err; printf("Attempting to close Linux i2c-dev file descriptor %d\n", - chnd->i2c_dev_fd); + chnd->i2c_dev_fd); if (close(chnd->i2c_dev_fd)) { err = errno; perror("Failed to close Linux i2c-dev file descriptor with " - "error"); + "error"); return err ? err : -1; } printf("Successfully closed Linux i2c-dev file descriptor %d\n", - chnd->i2c_dev_fd); + chnd->i2c_dev_fd); return 0; } @@ -1973,8 +1984,9 @@ static int ccd_i2c_interface_shutdown(struct common_hnd *chnd) static int ftdi_i2c_interface_init(struct common_hnd *chnd) { chnd->ftdi_hnd = open_ftdi_device(chnd->conf.usb_vid, - chnd->conf.usb_pid, chnd->conf.usb_interface, - chnd->conf.usb_serial); + chnd->conf.usb_pid, + chnd->conf.usb_interface, + chnd->conf.usb_serial); if (chnd->ftdi_hnd == NULL) return -1; return 0; @@ -2067,31 +2079,31 @@ static int strdup_with_errmsg(const char *source, char **dest, const char *name) return ret; } -static const struct option longopts[] = { - {"block-write-size", 1, 0, 'b'}, - {"debug", 0, 0, 'd'}, - {"erase", 0, 0, 'e'}, - {"help", 0, 0, 'h'}, - {"i2c-dev-path", 1, 0, 'D'}, - {"i2c-interface", 1, 0, 'c'}, - {"i2c-mux", 0, 0, 'm'}, - {"interface", 1, 0, 'i'}, - {"nodisable-protect-path", 0, 0, 'Z'}, - {"nodisable-watchdog", 0, 0, 'z'}, - {"noverify", 0, 0, 'n'}, - {"product", 1, 0, 'p'}, - {"range", 1, 0, 'R'}, - {"read", 1, 0, 'r'}, - {"send-waveform", 1, 0, 'W'}, - {"serial", 1, 0, 's'}, - {"vendor", 1, 0, 'v'}, - {"write", 1, 0, 'w'}, - {NULL, 0, 0, 0} -}; +static const struct option longopts[] = { { "block-write-size", 1, 0, 'b' }, + { "debug", 0, 0, 'd' }, + { "erase", 0, 0, 'e' }, + { "help", 0, 0, 'h' }, + { "i2c-dev-path", 1, 0, 'D' }, + { "i2c-interface", 1, 0, 'c' }, + { "i2c-mux", 0, 0, 'm' }, + { "interface", 1, 0, 'i' }, + { "nodisable-protect-path", 0, 0, + 'Z' }, + { "nodisable-watchdog", 0, 0, 'z' }, + { "noverify", 0, 0, 'n' }, + { "product", 1, 0, 'p' }, + { "range", 1, 0, 'R' }, + { "read", 1, 0, 'r' }, + { "send-waveform", 1, 0, 'W' }, + { "serial", 1, 0, 's' }, + { "vendor", 1, 0, 'v' }, + { "write", 1, 0, 'w' }, + { NULL, 0, 0, 0 } }; static void display_usage(const char *program) { - fprintf(stderr, "Usage: %s [-d] [-v <VID>] [-p <PID>] \\\n" + fprintf(stderr, + "Usage: %s [-d] [-v <VID>] [-p <PID>] \\\n" "\t[-c <linux|ccd|ftdi>] [-D /dev/i2c-<N>] [-i <1|2>] [-S] \\\n" "\t[-s <serial>] [-e] [-r <file>] [-W <0|1|false|true>] \\\n" "\t[-w <file>] [-R base[:size]] [-m] [-b <size>]\n", @@ -2105,14 +2117,16 @@ static void display_usage(const char *program) "\tonly applicable with --i2c-interface=linux\n"); fprintf(stderr, "-i, --interface <1> : FTDI interface: A=1, B=2," " ...\n"); - fprintf(stderr, "-m, --i2c-mux : Enable i2c-mux (to EC).\n" + fprintf(stderr, + "-m, --i2c-mux : Enable i2c-mux (to EC).\n" "\tSpecify this flag only if the board has an I2C MUX and\n" "\tyou are not using servod.\n"); fprintf(stderr, "-n, --noverify : Don't auto verify.\n"); fprintf(stderr, "-b, --block-write-size <size> : Perform writes in\n" - "\tblocks of this many bytes.\n"); + "\tblocks of this many bytes.\n"); fprintf(stderr, "-p, --product <0x1234> : USB product ID\n"); - fprintf(stderr, "-R, --range base[:size] : Allow to read or write" + fprintf(stderr, + "-R, --range base[:size] : Allow to read or write" " just a slice\n" "\tof the file, starting at <base>:<size> bytes, or til\n" "\tthe end of the file if <size> is not specified, expressed\n" @@ -2121,15 +2135,16 @@ static void display_usage(const char *program) " write it into <file>.\n"); fprintf(stderr, "-s, --serial <serialname> : USB serial string\n"); fprintf(stderr, "-v, --vendor <0x1234> : USB vendor ID\n"); - fprintf(stderr, "-W, --send-waveform <0|1|false|true> : Send the" + fprintf(stderr, + "-W, --send-waveform <0|1|false|true> : Send the" " special waveform.\n" "\tDefault is true. Set to false if ITE direct firmware\n" "\tupdate mode has already been enabled.\n"); fprintf(stderr, "-w, --write <file> : Write <file> to flash.\n"); fprintf(stderr, "-z, --nodisable-watchdog : Do *not* disable EC " - "watchdog.\n"); + "watchdog.\n"); fprintf(stderr, "-Z, --nodisable-protect-path : Do *not* disable EC " - "protect path.\n"); + "protect path.\n"); } /* @@ -2141,7 +2156,7 @@ static int parse_range_options(char *str, struct iteflash_config *conf) char *size; if (!str) { - fprintf(stderr, "missing range base address specification\n"); + fprintf(stderr, "missing range base address specification\n"); return -1; } @@ -2187,14 +2202,16 @@ static int parse_parameters(int argc, char **argv, struct iteflash_config *conf) } else if (!strcasecmp(optarg, "ftdi")) { conf->i2c_if = &ftdi_i2c_interface; } else { - fprintf(stderr, "Unexpected -c / " - "--i2c-interface value: %s\n", optarg); + fprintf(stderr, + "Unexpected -c / " + "--i2c-interface value: %s\n", + optarg); ret = -1; } break; case 'D': ret = strdup_with_errmsg(optarg, &conf->i2c_dev_path, - "-D / --i2c-dev-path"); + "-D / --i2c-dev-path"); break; case 'd': conf->debug = 1; @@ -2224,11 +2241,11 @@ static int parse_parameters(int argc, char **argv, struct iteflash_config *conf) break; case 'r': ret = strdup_with_errmsg(optarg, &conf->input_filename, - "-r / --read"); + "-r / --read"); break; case 's': ret = strdup_with_errmsg(optarg, &conf->usb_serial, - "-s / --serial"); + "-s / --serial"); break; case 'v': conf->usb_vid = strtol(optarg, NULL, 16); @@ -2244,13 +2261,15 @@ static int parse_parameters(int argc, char **argv, struct iteflash_config *conf) conf->send_waveform = 1; break; } - fprintf(stderr, "Unexpected -W / --special-waveform " - "value: %s\n", optarg); + fprintf(stderr, + "Unexpected -W / --special-waveform " + "value: %s\n", + optarg); ret = -1; break; case 'w': ret = strdup_with_errmsg(optarg, &conf->output_filename, - "-w / --write"); + "-w / --write"); break; case 'z': conf->disable_watchdog = 0; @@ -2269,8 +2288,8 @@ static int parse_parameters(int argc, char **argv, struct iteflash_config *conf) static void sighandler(int signum) { int status; - printf("\nCaught signal %d: %s\nExiting...\n", - signum, strsignal(signum)); + printf("\nCaught signal %d: %s\nExiting...\n", signum, + strsignal(signum)); wait(&status); exit_requested = status; } @@ -2340,7 +2359,8 @@ int main(int argc, char **argv) ret = check_chipid(&chnd); if (ret) { - fprintf(stderr, "Failed to get ITE chip ID. This " + fprintf(stderr, + "Failed to get ITE chip ID. This " "could be because the ITE direct firmware " "update (DFU) mode is not enabled.\n"); goto return_after_init; @@ -2386,20 +2406,18 @@ int main(int argc, char **argv) command_erase2(&chnd, chnd.flash_size, 0, 0); else command_erase(&chnd, chnd.flash_size, 0); - /* Call DBGR Rest to clear the EC lock status after erasing */ - dbgr_reset(&chnd, RSTS_VCCDO_PW_ON|RSTS_HGRST|RSTS_GRST); } if (chnd.conf.output_filename) { if (chnd.flash_cmd_v2) switch (eflash_type) { case EFLASH_TYPE_8315: - ret = write_flash2(&chnd, - chnd.conf.output_filename, 0); + ret = write_flash2( + &chnd, chnd.conf.output_filename, 0); break; case EFLASH_TYPE_KGD: - ret = write_flash3(&chnd, - chnd.conf.output_filename, 0); + ret = write_flash3( + &chnd, chnd.conf.output_filename, 0); break; default: printf("Invalid EFLASH TYPE!"); @@ -2420,7 +2438,7 @@ int main(int argc, char **argv) /* Normal exit */ ret = 0; - return_after_init: +return_after_init: /* * Exit DBGR mode. This ensures EC won't hold clock/data pins of I2C. * Avoid resetting EC here because flash_ec will after iteflash exits. @@ -2439,7 +2457,7 @@ int main(int argc, char **argv) ret = other_ret; } - return_after_parse: +return_after_parse: config_release(&chnd.conf); return ret; } diff --git a/util/iteflash.md b/util/iteflash.md index 68f7600d74..d85d99013a 100644 --- a/util/iteflash.md +++ b/util/iteflash.md @@ -6,8 +6,8 @@ First written: 2019-04-02 <br> Last updated: 2019-04-03 -Familiarity with [Chromium OS](https://www.chromium.org/chromium-os) -[Embedded Controller (EC) development](../README.md) is assumed. +Familiarity with [Chromium OS](https://www.chromium.org/chromium-os) and +[Embedded Controller (EC)](../README.md) development is assumed. [TOC] @@ -48,9 +48,10 @@ An ITE EC is reflashed using a Servo by: ### Further reading -Googlers, and Partners involved in ITE EC projects, see -[The State of ITE CrOS EC Reflashing](https://docs.google.com/document/d/1fs29eBvwKrOWYozLZXTg7ObwAO5dyM4Js2Vq301EwAU/preview). -That document is not public, do not request access if you lack it. +* [ITE EC firmware reflashing via Servo: How it works](../docs/ite-ec-reflashing.md) +* Googlers, and Partners involved in ITE EC projects *only*: +[The State of ITE CrOS EC Reflashing](https://docs.google.com/document/d/1fs29eBvwKrOWYozLZXTg7ObwAO5dyM4Js2Vq301EwAU/preview) + * That document is not public, do not request access if you lack it. ## How to reflash diff --git a/util/kconfig_check.py b/util/kconfig_check.py index d1eba8e62b..e745b3aeca 100755 --- a/util/kconfig_check.py +++ b/util/kconfig_check.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Copyright 2021 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Kconfig checker @@ -25,6 +25,7 @@ import os import pathlib import re import sys +import traceback # Try to use kconfiglib if available, but fall back to a simple recursive grep. # This is used by U-Boot in some situations so we keep it to avoid forking this @@ -32,12 +33,13 @@ import sys USE_KCONFIGLIB = False try: import kconfiglib + USE_KCONFIGLIB = True except ImportError: pass # Where we put the new config_allowed file -NEW_ALLOWED_FNAME = pathlib.Path('/tmp/new_config_allowed.txt') +NEW_ALLOWED_FNAME = pathlib.Path("/tmp/new_config_allowed.txt") def parse_args(argv): @@ -49,38 +51,72 @@ def parse_args(argv): Returns: argparse.Namespace object containing the results """ - epilog = '''Checks that new ad-hoc CONFIG options are not introduced without -a corresponding Kconfig option for Zephyr''' + epilog = """Checks that new ad-hoc CONFIG options are not introduced without +a corresponding Kconfig option for Zephyr""" parser = argparse.ArgumentParser(epilog=epilog) - parser.add_argument('-a', '--allowed', type=str, - default='util/config_allowed.txt', - help='File containing list of allowed ad-hoc CONFIGs') - parser.add_argument('-c', '--configs', type=str, default='.config', - help='File containing CONFIG options to check') - parser.add_argument('-d', '--use-defines', action='store_true', - help='Lines in the configs file use #define') parser.add_argument( - '-D', '--debug', action='store_true', - help='Enabling debugging (provides a full traceback on error)') + "-a", + "--allowed", + type=str, + default="util/config_allowed.txt", + help="File containing list of allowed ad-hoc CONFIGs", + ) + parser.add_argument( + "-c", + "--configs", + type=str, + default=".config", + help="File containing CONFIG options to check", + ) + parser.add_argument( + "-d", + "--use-defines", + action="store_true", + help="Lines in the configs file use #define", + ) + parser.add_argument( + "-D", + "--debug", + action="store_true", + help="Enabling debugging (provides a full traceback on error)", + ) + parser.add_argument( + "-i", + "--ignore", + action="append", + help="Kconfig options to ignore (without CONFIG_ prefix)", + ) parser.add_argument( - '-i', '--ignore', action='append', - help='Kconfig options to ignore (without CONFIG_ prefix)') - parser.add_argument('-I', '--search-path', type=str, action='append', - help='Search paths to look for Kconfigs') - parser.add_argument('-p', '--prefix', type=str, default='PLATFORM_EC_', - help='Prefix to string from Kconfig options') - parser.add_argument('-s', '--srctree', type=str, default='zephyr/', - help='Path to source tree to look for Kconfigs') + "-I", + "--search-path", + type=str, + action="append", + help="Search paths to look for Kconfigs", + ) + parser.add_argument( + "-p", + "--prefix", + type=str, + default="PLATFORM_EC_", + help="Prefix to string from Kconfig options", + ) + parser.add_argument( + "-s", + "--srctree", + type=str, + default="zephyr/", + help="Path to source tree to look for Kconfigs", + ) # TODO(sjg@chromium.org): The chroot uses a very old Python. Once it moves # to 3.7 or later we can use this instead: # subparsers = parser.add_subparsers(dest='cmd', required=True) - subparsers = parser.add_subparsers(dest='cmd') + subparsers = parser.add_subparsers(dest="cmd") subparsers.required = True - subparsers.add_parser('build', help='Build new list of ad-hoc CONFIGs') - subparsers.add_parser('check', help='Check for new ad-hoc CONFIGs') + subparsers.add_parser("build", help="Build new list of ad-hoc CONFIGs") + subparsers.add_parser("check", help="Check for new ad-hoc CONFIGs") return parser.parse_args(argv) @@ -107,6 +143,7 @@ class KconfigCheck: the user is exhorted to add a new Kconfig. This helps avoid adding new ad-hoc CONFIG options, eventually returning the number to zero. """ + @classmethod def find_new_adhoc(cls, configs, kconfigs, allowed): """Get a list of new ad-hoc CONFIG options @@ -172,11 +209,15 @@ class KconfigCheck: List of CONFIG_xxx options found in the file, with the 'CONFIG_' prefix removed """ - with open(configs_file, 'r') as inf: - configs = re.findall('%sCONFIG_([A-Za-z0-9_]*)%s' % - ((use_defines and '#define ' or ''), - (use_defines and ' ' or '')), - inf.read()) + with open(configs_file, "r") as inf: + configs = re.findall( + "%sCONFIG_([A-Za-z0-9_]*)%s" + % ( + (use_defines and "#define " or ""), + (use_defines and " " or ""), + ), + inf.read(), + ) return configs @classmethod @@ -190,8 +231,8 @@ class KconfigCheck: List of CONFIG_xxx options found in the file, with the 'CONFIG_' prefix removed """ - with open(allowed_file, 'r') as inf: - configs = re.findall('CONFIG_([A-Za-z0-9_]*)', inf.read()) + with open(allowed_file, "r") as inf: + configs = re.findall("CONFIG_([A-Za-z0-9_]*)", inf.read()) return configs @classmethod @@ -209,15 +250,27 @@ class KconfigCheck: """ kconfig_files = [] for root, dirs, files in os.walk(srcdir): - kconfig_files += [os.path.join(root, fname) - for fname in files if fname.startswith('Kconfig')] - if 'Kconfig' in dirs: - dirs.remove('Kconfig') + kconfig_files += [ + os.path.join(root, fname) + for fname in files + if fname.startswith("Kconfig") + ] + if "Kconfig" in dirs: + dirs.remove("Kconfig") + if "boards" in dirs: + dirs.remove("boards") + if "projects" in dirs: + dirs.remove("projects") + if "test" in dirs: + dirs.remove("test") + if "chip" in dirs: + dirs.remove("chip") return kconfig_files @classmethod - def scan_kconfigs(cls, srcdir, prefix='', search_paths=None, - try_kconfiglib=True): + def scan_kconfigs( + cls, srcdir, prefix="", search_paths=None, try_kconfiglib=True + ): """Scan a source tree for Kconfig options Args: @@ -231,31 +284,42 @@ class KconfigCheck: List of config and menuconfig options found """ if USE_KCONFIGLIB and try_kconfiglib: - os.environ['srctree'] = srcdir - kconf = kconfiglib.Kconfig('Kconfig', warn=False, - search_paths=search_paths, - allow_empty_macros=True) + os.environ["srctree"] = srcdir + kconf = kconfiglib.Kconfig( + "Kconfig", + warn=False, + search_paths=search_paths, + allow_empty_macros=True, + ) # There is always a MODULES config, since kconfiglib is designed for # linux, but we don't want it - kconfigs = [name for name in kconf.syms if name != 'MODULES'] + kconfigs = [name for name in kconf.syms if name != "MODULES"] if prefix: - re_drop_prefix = re.compile(r'^%s' % prefix) - kconfigs = [re_drop_prefix.sub('', name) for name in kconfigs] + re_drop_prefix = re.compile(r"^%s" % prefix) + kconfigs = [re_drop_prefix.sub("", name) for name in kconfigs] else: kconfigs = [] # Remove the prefix if present - expr = re.compile(r'\n(config|menuconfig) (%s)?([A-Za-z0-9_]*)\n' % - prefix) + expr = re.compile( + r"\n(config|menuconfig) (%s)?([A-Za-z0-9_]*)\n" % prefix + ) for fname in cls.find_kconfigs(srcdir): with open(fname) as inf: found = re.findall(expr, inf.read()) kconfigs += [name for kctype, _, name in found] return sorted(kconfigs) - def check_adhoc_configs(self, configs_file, srcdir, allowed_file, - prefix='', use_defines=False, search_paths=None): + def check_adhoc_configs( + self, + configs_file, + srcdir, + allowed_file, + prefix="", + use_defines=False, + search_paths=None, + ): """Find new and unneeded ad-hoc configs in the configs_file Args: @@ -283,8 +347,11 @@ class KconfigCheck: except kconfiglib.KconfigError: # If we don't actually have access to the full Kconfig then we may # get an error. Fall back to using manual methods. - kconfigs = self.scan_kconfigs(srcdir, prefix, search_paths, - try_kconfiglib=False) + print("WARNING: kconfiglib failed", file=sys.stderr) + traceback.print_exc() + kconfigs = self.scan_kconfigs( + srcdir, prefix, search_paths, try_kconfiglib=False + ) allowed = self.read_allowed(allowed_file) new_adhoc = self.find_new_adhoc(configs, kconfigs, allowed) @@ -292,8 +359,16 @@ class KconfigCheck: updated_adhoc = self.get_updated_adhoc(unneeded_adhoc, allowed) return new_adhoc, unneeded_adhoc, updated_adhoc - def do_check(self, configs_file, srcdir, allowed_file, prefix, use_defines, - search_paths, ignore=None): + def do_check( + self, + configs_file, + srcdir, + allowed_file, + prefix, + use_defines, + search_paths, + ignore=None, + ): """Find new ad-hoc configs in the configs_file Args: @@ -313,11 +388,17 @@ class KconfigCheck: Exit code: 0 if OK, 1 if a problem was found """ new_adhoc, unneeded_adhoc, updated_adhoc = self.check_adhoc_configs( - configs_file, srcdir, allowed_file, prefix, use_defines, - search_paths) + configs_file, + srcdir, + allowed_file, + prefix, + use_defines, + search_paths, + ) if new_adhoc: - file_list = '\n'.join(['CONFIG_%s' % name for name in new_adhoc]) - print(f'''Error:\tThe EC is in the process of migrating to Zephyr. + file_list = "\n".join(["CONFIG_%s" % name for name in new_adhoc]) + print( + f"""Error:\tThe EC is in the process of migrating to Zephyr. \tZephyr uses Kconfig for configuration rather than ad-hoc #defines. \tAny new EC CONFIG options must ALSO be added to Zephyr so that new \tfunctionality is available in Zephyr also. The following new ad-hoc @@ -330,19 +411,23 @@ file in zephyr/ and add a 'config' or 'menuconfig' option. Also see details in http://issuetracker.google.com/181253613 To temporarily disable this, use: ALLOW_CONFIG=1 make ... -''', file=sys.stderr) +""", + file=sys.stderr, + ) return 1 if not ignore: ignore = [] unneeded_adhoc = [name for name in unneeded_adhoc if name not in ignore] if unneeded_adhoc: - with open(NEW_ALLOWED_FNAME, 'w') as out: + with open(NEW_ALLOWED_FNAME, "w") as out: for config in updated_adhoc: - print('CONFIG_%s' % config, file=out) - now_in_kconfig = '\n'.join( - ['CONFIG_%s' % name for name in unneeded_adhoc]) - print(f'''The following options are now in Kconfig: + print("CONFIG_%s" % config, file=out) + now_in_kconfig = "\n".join( + ["CONFIG_%s" % name for name in unneeded_adhoc] + ) + print( + f"""The following options are now in Kconfig: {now_in_kconfig} @@ -350,12 +435,20 @@ Please run this to update the list of allowed ad-hoc CONFIGs and include this update in your CL: cp {NEW_ALLOWED_FNAME} util/config_allowed.txt -''') +""" + ) return 1 return 0 - def do_build(self, configs_file, srcdir, allowed_file, prefix, use_defines, - search_paths): + def do_build( + self, + configs_file, + srcdir, + allowed_file, + prefix, + use_defines, + search_paths, + ): """Find new ad-hoc configs in the configs_file Args: @@ -372,13 +465,19 @@ update in your CL: Exit code: 0 if OK, 1 if a problem was found """ new_adhoc, _, updated_adhoc = self.check_adhoc_configs( - configs_file, srcdir, allowed_file, prefix, use_defines, - search_paths) - with open(NEW_ALLOWED_FNAME, 'w') as out: + configs_file, + srcdir, + allowed_file, + prefix, + use_defines, + search_paths, + ) + with open(NEW_ALLOWED_FNAME, "w") as out: combined = sorted(new_adhoc + updated_adhoc) for config in combined: - print(f'CONFIG_{config}', file=out) - print(f'New list is in {NEW_ALLOWED_FNAME}') + print(f"CONFIG_{config}", file=out) + print(f"New list is in {NEW_ALLOWED_FNAME}") + def main(argv): """Main function""" @@ -386,18 +485,27 @@ def main(argv): if not args.debug: sys.tracebacklimit = 0 checker = KconfigCheck() - if args.cmd == 'check': + if args.cmd == "check": return checker.do_check( - configs_file=args.configs, srcdir=args.srctree, - allowed_file=args.allowed, prefix=args.prefix, - use_defines=args.use_defines, search_paths=args.search_path, - ignore=args.ignore) - elif args.cmd == 'build': - return checker.do_build(configs_file=args.configs, srcdir=args.srctree, - allowed_file=args.allowed, prefix=args.prefix, - use_defines=args.use_defines, search_paths=args.search_path) + configs_file=args.configs, + srcdir=args.srctree, + allowed_file=args.allowed, + prefix=args.prefix, + use_defines=args.use_defines, + search_paths=args.search_path, + ignore=args.ignore, + ) + if args.cmd == "build": + return checker.do_build( + configs_file=args.configs, + srcdir=args.srctree, + allowed_file=args.allowed, + prefix=args.prefix, + use_defines=args.use_defines, + search_paths=args.search_path, + ) return 2 -if __name__ == '__main__': +if __name__ == "__main__": sys.exit(main(sys.argv[1:])) diff --git a/util/kconfiglib.py b/util/kconfiglib.py deleted file mode 100644 index 0e05aaaeac..0000000000 --- a/util/kconfiglib.py +++ /dev/null @@ -1,7196 +0,0 @@ -# Copyright (c) 2011-2019, Ulf Magnusson -# SPDX-License-Identifier: ISC - -""" -Overview -======== - -Kconfiglib is a Python 2/3 library for scripting and extracting information -from Kconfig (https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt) -configuration systems. - -See the homepage at https://github.com/ulfalizer/Kconfiglib for a longer -overview. - -Since Kconfiglib 12.0.0, the library version is available in -kconfiglib.VERSION, which is a (<major>, <minor>, <patch>) tuple, e.g. -(12, 0, 0). - - -Using Kconfiglib on the Linux kernel with the Makefile targets -============================================================== - -For the Linux kernel, a handy interface is provided by the -scripts/kconfig/Makefile patch, which can be applied with either 'git am' or -the 'patch' utility: - - $ wget -qO- https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch | git am - $ wget -qO- https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch | patch -p1 - -Warning: Not passing -p1 to patch will cause the wrong file to be patched. - -Please tell me if the patch does not apply. It should be trivial to apply -manually, as it's just a block of text that needs to be inserted near the other -*conf: targets in scripts/kconfig/Makefile. - -Look further down for a motivation for the Makefile patch and for instructions -on how you can use Kconfiglib without it. - -If you do not wish to install Kconfiglib via pip, the Makefile patch is set up -so that you can also just clone Kconfiglib into the kernel root: - - $ git clone git://github.com/ulfalizer/Kconfiglib.git - $ git am Kconfiglib/makefile.patch (or 'patch -p1 < Kconfiglib/makefile.patch') - -Warning: The directory name Kconfiglib/ is significant in this case, because -it's added to PYTHONPATH by the new targets in makefile.patch. - -The targets added by the Makefile patch are described in the following -sections. - - -make kmenuconfig ----------------- - -This target runs the curses menuconfig interface with Python 3. As of -Kconfiglib 12.2.0, both Python 2 and Python 3 are supported (previously, only -Python 3 was supported, so this was a backport). - - -make guiconfig --------------- - -This target runs the Tkinter menuconfig interface. Both Python 2 and Python 3 -are supported. To change the Python interpreter used, pass -PYTHONCMD=<executable> to 'make'. The default is 'python'. - - -make [ARCH=<arch>] iscriptconfig --------------------------------- - -This target gives an interactive Python prompt where a Kconfig instance has -been preloaded and is available in 'kconf'. To change the Python interpreter -used, pass PYTHONCMD=<executable> to 'make'. The default is 'python'. - -To get a feel for the API, try evaluating and printing the symbols in -kconf.defined_syms, and explore the MenuNode menu tree starting at -kconf.top_node by following 'next' and 'list' pointers. - -The item contained in a menu node is found in MenuNode.item (note that this can -be one of the constants kconfiglib.MENU and kconfiglib.COMMENT), and all -symbols and choices have a 'nodes' attribute containing their menu nodes -(usually only one). Printing a menu node will print its item, in Kconfig -format. - -If you want to look up a symbol by name, use the kconf.syms dictionary. - - -make scriptconfig SCRIPT=<script> [SCRIPT_ARG=<arg>] ----------------------------------------------------- - -This target runs the Python script given by the SCRIPT parameter on the -configuration. sys.argv[1] holds the name of the top-level Kconfig file -(currently always "Kconfig" in practice), and sys.argv[2] holds the SCRIPT_ARG -argument, if given. - -See the examples/ subdirectory for example scripts. - - -make dumpvarsconfig -------------------- - -This target prints a list of all environment variables referenced from the -Kconfig files, together with their values. See the -Kconfiglib/examples/dumpvars.py script. - -Only environment variables that are referenced via the Kconfig preprocessor -$(FOO) syntax are included. The preprocessor was added in Linux 4.18. - - -Using Kconfiglib without the Makefile targets -============================================= - -The make targets are only needed to pick up environment variables exported from -the Kbuild makefiles and referenced inside Kconfig files, via e.g. -'source "arch/$(SRCARCH)/Kconfig" and commands run via '$(shell,...)'. - -These variables are referenced as of writing (Linux 4.18), together with sample -values: - - srctree (.) - ARCH (x86) - SRCARCH (x86) - KERNELVERSION (4.18.0) - CC (gcc) - HOSTCC (gcc) - HOSTCXX (g++) - CC_VERSION_TEXT (gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0) - -Older kernels only reference ARCH, SRCARCH, and KERNELVERSION. - -If your kernel is recent enough (4.18+), you can get a list of referenced -environment variables via 'make dumpvarsconfig' (see above). Note that this -command is added by the Makefile patch. - -To run Kconfiglib without the Makefile patch, set the environment variables -manually: - - $ srctree=. ARCH=x86 SRCARCH=x86 KERNELVERSION=`make kernelversion` ... python(3) - >>> import kconfiglib - >>> kconf = kconfiglib.Kconfig() # filename defaults to "Kconfig" - -Search the top-level Makefile for "Additional ARCH settings" to see other -possibilities for ARCH and SRCARCH. - - -Intro to symbol values -====================== - -Kconfiglib has the same assignment semantics as the C implementation. - -Any symbol can be assigned a value by the user (via Kconfig.load_config() or -Symbol.set_value()), but this user value is only respected if the symbol is -visible, which corresponds to it (currently) being visible in the menuconfig -interface. - -For symbols with prompts, the visibility of the symbol is determined by the -condition on the prompt. Symbols without prompts are never visible, so setting -a user value on them is pointless. A warning will be printed by default if -Symbol.set_value() is called on a promptless symbol. Assignments to promptless -symbols are normal within a .config file, so no similar warning will be printed -by load_config(). - -Dependencies from parents and 'if'/'depends on' are propagated to properties, -including prompts, so these two configurations are logically equivalent: - -(1) - - menu "menu" - depends on A - - if B - - config FOO - tristate "foo" if D - default y - depends on C - - endif - - endmenu - -(2) - - menu "menu" - depends on A - - config FOO - tristate "foo" if A && B && C && D - default y if A && B && C - - endmenu - -In this example, A && B && C && D (the prompt condition) needs to be non-n for -FOO to be visible (assignable). If its value is m, the symbol can only be -assigned the value m: The visibility sets an upper bound on the value that can -be assigned by the user, and any higher user value will be truncated down. - -'default' properties are independent of the visibility, though a 'default' will -often get the same condition as the prompt due to dependency propagation. -'default' properties are used if the symbol is not visible or has no user -value. - -Symbols with no user value (or that have a user value but are not visible) and -no (active) 'default' default to n for bool/tristate symbols, and to the empty -string for other symbol types. - -'select' works similarly to symbol visibility, but sets a lower bound on the -value of the symbol. The lower bound is determined by the value of the -select*ing* symbol. 'select' does not respect visibility, so non-visible -symbols can be forced to a particular (minimum) value by a select as well. - -For non-bool/tristate symbols, it only matters whether the visibility is n or -non-n: m visibility acts the same as y visibility. - -Conditions on 'default' and 'select' work in mostly intuitive ways. If the -condition is n, the 'default' or 'select' is disabled. If it is m, the -'default' or 'select' value (the value of the selecting symbol) is truncated -down to m. - -When writing a configuration with Kconfig.write_config(), only symbols that are -visible, have an (active) default, or are selected will get written out (note -that this includes all symbols that would accept user values). Kconfiglib -matches the .config format produced by the C implementations down to the -character. This eases testing. - -For a visible bool/tristate symbol FOO with value n, this line is written to -.config: - - # CONFIG_FOO is not set - -The point is to remember the user n selection (which might differ from the -default value the symbol would get), while at the same sticking to the rule -that undefined corresponds to n (.config uses Makefile format, making the line -above a comment). When the .config file is read back in, this line will be -treated the same as the following assignment: - - CONFIG_FOO=n - -In Kconfiglib, the set of (currently) assignable values for a bool/tristate -symbol appear in Symbol.assignable. For other symbol types, just check if -sym.visibility is non-0 (non-n) to see whether the user value will have an -effect. - - -Intro to the menu tree -====================== - -The menu structure, as seen in e.g. menuconfig, is represented by a tree of -MenuNode objects. The top node of the configuration corresponds to an implicit -top-level menu, the title of which is shown at the top in the standard -menuconfig interface. (The title is also available in Kconfig.mainmenu_text in -Kconfiglib.) - -The top node is found in Kconfig.top_node. From there, you can visit child menu -nodes by following the 'list' pointer, and any following menu nodes by -following the 'next' pointer. Usually, a non-None 'list' pointer indicates a -menu or Choice, but menu nodes for symbols can sometimes have a non-None 'list' -pointer too due to submenus created implicitly from dependencies. - -MenuNode.item is either a Symbol or a Choice object, or one of the constants -MENU and COMMENT. The prompt of the menu node can be found in MenuNode.prompt, -which also holds the title for menus and comments. For Symbol and Choice, -MenuNode.help holds the help text (if any, otherwise None). - -Most symbols will only have a single menu node. A symbol defined in multiple -locations will have one menu node for each location. The list of menu nodes for -a Symbol or Choice can be found in the Symbol/Choice.nodes attribute. - -Note that prompts and help texts for symbols and choices are stored in their -menu node(s) rather than in the Symbol or Choice objects themselves. This makes -it possible to define a symbol in multiple locations with a different prompt or -help text in each location. To get the help text or prompt for a symbol with a -single menu node, do sym.nodes[0].help and sym.nodes[0].prompt, respectively. -The prompt is a (text, condition) tuple, where condition determines the -visibility (see 'Intro to expressions' below). - -This organization mirrors the C implementation. MenuNode is called -'struct menu' there, but I thought "menu" was a confusing name. - -It is possible to give a Choice a name and define it in multiple locations, -hence why Choice.nodes is also a list. - -As a convenience, the properties added at a particular definition location are -available on the MenuNode itself, in e.g. MenuNode.defaults. This is helpful -when generating documentation, so that symbols/choices defined in multiple -locations can be shown with the correct properties at each location. - - -Intro to expressions -==================== - -Expressions can be evaluated with the expr_value() function and printed with -the expr_str() function (these are used internally as well). Evaluating an -expression always yields a tristate value, where n, m, and y are represented as -0, 1, and 2, respectively. - -The following table should help you figure out how expressions are represented. -A, B, C, ... are symbols (Symbol instances), NOT is the kconfiglib.NOT -constant, etc. - -Expression Representation ----------- -------------- -A A -"A" A (constant symbol) -!A (NOT, A) -A && B (AND, A, B) -A && B && C (AND, A, (AND, B, C)) -A || B (OR, A, B) -A || (B && C && D) (OR, A, (AND, B, (AND, C, D))) -A = B (EQUAL, A, B) -A != "foo" (UNEQUAL, A, foo (constant symbol)) -A && B = C && D (AND, A, (AND, (EQUAL, B, C), D)) -n Kconfig.n (constant symbol) -m Kconfig.m (constant symbol) -y Kconfig.y (constant symbol) -"y" Kconfig.y (constant symbol) - -Strings like "foo" in 'default "foo"' or 'depends on SYM = "foo"' are -represented as constant symbols, so the only values that appear in expressions -are symbols***. This mirrors the C implementation. - -***For choice symbols, the parent Choice will appear in expressions as well, -but it's usually invisible as the value interfaces of Symbol and Choice are -identical. This mirrors the C implementation and makes different choice modes -"just work". - -Manual evaluation examples: - - - The value of A && B is min(A.tri_value, B.tri_value) - - - The value of A || B is max(A.tri_value, B.tri_value) - - - The value of !A is 2 - A.tri_value - - - The value of A = B is 2 (y) if A.str_value == B.str_value, and 0 (n) - otherwise. Note that str_value is used here instead of tri_value. - - For constant (as well as undefined) symbols, str_value matches the name of - the symbol. This mirrors the C implementation and explains why - 'depends on SYM = "foo"' above works as expected. - -n/m/y are automatically converted to the corresponding constant symbols -"n"/"m"/"y" (Kconfig.n/m/y) during parsing. - -Kconfig.const_syms is a dictionary like Kconfig.syms but for constant symbols. - -If a condition is missing (e.g., <cond> when the 'if <cond>' is removed from -'default A if <cond>'), it is actually Kconfig.y. The standard __str__() -functions just avoid printing 'if y' conditions to give cleaner output. - - -Kconfig extensions -================== - -Kconfiglib includes a couple of Kconfig extensions: - -'source' with relative path ---------------------------- - -The 'rsource' statement sources Kconfig files with a path relative to directory -of the Kconfig file containing the 'rsource' statement, instead of relative to -the project root. - -Consider following directory tree: - - Project - +--Kconfig - | - +--src - +--Kconfig - | - +--SubSystem1 - +--Kconfig - | - +--ModuleA - +--Kconfig - -In this example, assume that src/SubSystem1/Kconfig wants to source -src/SubSystem1/ModuleA/Kconfig. - -With 'source', this statement would be used: - - source "src/SubSystem1/ModuleA/Kconfig" - -With 'rsource', this turns into - - rsource "ModuleA/Kconfig" - -If an absolute path is given to 'rsource', it acts the same as 'source'. - -'rsource' can be used to create "position-independent" Kconfig trees that can -be moved around freely. - - -Globbing 'source' ------------------ - -'source' and 'rsource' accept glob patterns, sourcing all matching Kconfig -files. They require at least one matching file, raising a KconfigError -otherwise. - -For example, the following statement might source sub1/foofoofoo and -sub2/foobarfoo: - - source "sub[12]/foo*foo" - -The glob patterns accepted are the same as for the standard glob.glob() -function. - -Two additional statements are provided for cases where it's acceptable for a -pattern to match no files: 'osource' and 'orsource' (the o is for "optional"). - -For example, the following statements will be no-ops if neither "foo" nor any -files matching "bar*" exist: - - osource "foo" - osource "bar*" - -'orsource' does a relative optional source. - -'source' and 'osource' are analogous to 'include' and '-include' in Make. - - -Generalized def_* keywords --------------------------- - -def_int, def_hex, and def_string are available in addition to def_bool and -def_tristate, allowing int, hex, and string symbols to be given a type and a -default at the same time. - - -Extra optional warnings ------------------------ - -Some optional warnings can be controlled via environment variables: - - - KCONFIG_WARN_UNDEF: If set to 'y', warnings will be generated for all - references to undefined symbols within Kconfig files. The only gotcha is - that all hex literals must be prefixed with "0x" or "0X", to make it - possible to distinguish them from symbol references. - - Some projects (e.g. the Linux kernel) use multiple Kconfig trees with many - shared Kconfig files, leading to some safe undefined symbol references. - KCONFIG_WARN_UNDEF is useful in projects that only have a single Kconfig - tree though. - - KCONFIG_STRICT is an older alias for this environment variable, supported - for backwards compatibility. - - - KCONFIG_WARN_UNDEF_ASSIGN: If set to 'y', warnings will be generated for - all assignments to undefined symbols within .config files. By default, no - such warnings are generated. - - This warning can also be enabled/disabled via the Kconfig.warn_assign_undef - variable. - - -Preprocessor user functions defined in Python ---------------------------------------------- - -Preprocessor functions can be defined in Python, which makes it simple to -integrate information from existing Python tools into Kconfig (e.g. to have -Kconfig symbols depend on hardware information stored in some other format). - -Putting a Python module named kconfigfunctions(.py) anywhere in sys.path will -cause it to be imported by Kconfiglib (in Kconfig.__init__()). Note that -sys.path can be customized via PYTHONPATH, and includes the directory of the -module being run by default, as well as installation directories. - -If the KCONFIG_FUNCTIONS environment variable is set, it gives a different -module name to use instead of 'kconfigfunctions'. - -The imported module is expected to define a global dictionary named 'functions' -that maps function names to Python functions, as follows: - - def my_fn(kconf, name, arg_1, arg_2, ...): - # kconf: - # Kconfig instance - # - # name: - # Name of the user-defined function ("my-fn"). Think argv[0]. - # - # arg_1, arg_2, ...: - # Arguments passed to the function from Kconfig (strings) - # - # Returns a string to be substituted as the result of calling the - # function - ... - - def my_other_fn(kconf, name, arg_1, arg_2, ...): - ... - - functions = { - "my-fn": (my_fn, <min.args>, <max.args>/None), - "my-other-fn": (my_other_fn, <min.args>, <max.args>/None), - ... - } - - ... - -<min.args> and <max.args> are the minimum and maximum number of arguments -expected by the function (excluding the implicit 'name' argument). If -<max.args> is None, there is no upper limit to the number of arguments. Passing -an invalid number of arguments will generate a KconfigError exception. - -Functions can access the current parsing location as kconf.filename/linenr. -Accessing other fields of the Kconfig object is not safe. See the warning -below. - -Keep in mind that for a variable defined like 'foo = $(fn)', 'fn' will be -called only when 'foo' is expanded. If 'fn' uses the parsing location and the -intent is to use the location of the assignment, you want 'foo := $(fn)' -instead, which calls the function immediately. - -Once defined, user functions can be called from Kconfig in the same way as -other preprocessor functions: - - config FOO - ... - depends on $(my-fn,arg1,arg2) - -If my_fn() returns "n", this will result in - - config FOO - ... - depends on n - -Warning -******* - -User-defined preprocessor functions are called as they're encountered at parse -time, before all Kconfig files have been processed, and before the menu tree -has been finalized. There are no guarantees that accessing Kconfig symbols or -the menu tree via the 'kconf' parameter will work, and it could potentially -lead to a crash. - -Preferably, user-defined functions should be stateless. - - -Feedback -======== - -Send bug reports, suggestions, and questions to ulfalizer a.t Google's email -service, or open a ticket on the GitHub page. -""" -import errno -import importlib -import os -import re -import sys - -# Get rid of some attribute lookups. These are obvious in context. -from glob import iglob -from os.path import dirname, exists, expandvars, islink, join, realpath - - -VERSION = (14, 1, 0) - - -# File layout: -# -# Public classes -# Public functions -# Internal functions -# Global constants - -# Line length: 79 columns - - -# -# Public classes -# - - -class Kconfig(object): - """ - Represents a Kconfig configuration, e.g. for x86 or ARM. This is the set of - symbols, choices, and menu nodes appearing in the configuration. Creating - any number of Kconfig objects (including for different architectures) is - safe. Kconfiglib doesn't keep any global state. - - The following attributes are available. They should be treated as - read-only, and some are implemented through @property magic. - - syms: - A dictionary with all symbols in the configuration, indexed by name. Also - includes all symbols that are referenced in expressions but never - defined, except for constant (quoted) symbols. - - Undefined symbols can be recognized by Symbol.nodes being empty -- see - the 'Intro to the menu tree' section in the module docstring. - - const_syms: - A dictionary like 'syms' for constant (quoted) symbols - - named_choices: - A dictionary like 'syms' for named choices (choice FOO) - - defined_syms: - A list with all defined symbols, in the same order as they appear in the - Kconfig files. Symbols defined in multiple locations appear multiple - times. - - Note: You probably want to use 'unique_defined_syms' instead. This - attribute is mostly maintained for backwards compatibility. - - unique_defined_syms: - A list like 'defined_syms', but with duplicates removed. Just the first - instance is kept for symbols defined in multiple locations. Kconfig order - is preserved otherwise. - - Using this attribute instead of 'defined_syms' can save work, and - automatically gives reasonable behavior when writing configuration output - (symbols defined in multiple locations only generate output once, while - still preserving Kconfig order for readability). - - choices: - A list with all choices, in the same order as they appear in the Kconfig - files. - - Note: You probably want to use 'unique_choices' instead. This attribute - is mostly maintained for backwards compatibility. - - unique_choices: - Analogous to 'unique_defined_syms', for choices. Named choices can have - multiple definition locations. - - menus: - A list with all menus, in the same order as they appear in the Kconfig - files - - comments: - A list with all comments, in the same order as they appear in the Kconfig - files - - kconfig_filenames: - A list with the filenames of all Kconfig files included in the - configuration, relative to $srctree (or relative to the current directory - if $srctree isn't set), except absolute paths (e.g. - 'source "/foo/Kconfig"') are kept as-is. - - The files are listed in the order they are source'd, starting with the - top-level Kconfig file. If a file is source'd multiple times, it will - appear multiple times. Use set() to get unique filenames. - - Note that Kconfig.sync_deps() already indirectly catches any file - modifications that change configuration output. - - env_vars: - A set() with the names of all environment variables referenced in the - Kconfig files. - - Only environment variables referenced with the preprocessor $(FOO) syntax - will be registered. The older $FOO syntax is only supported for backwards - compatibility. - - Also note that $(FOO) won't be registered unless the environment variable - $FOO is actually set. If it isn't, $(FOO) is an expansion of an unset - preprocessor variable (which gives the empty string). - - Another gotcha is that environment variables referenced in the values of - recursively expanded preprocessor variables (those defined with =) will - only be registered if the variable is actually used (expanded) somewhere. - - The note from the 'kconfig_filenames' documentation applies here too. - - n/m/y: - The predefined constant symbols n/m/y. Also available in const_syms. - - modules: - The Symbol instance for the modules symbol. Currently hardcoded to - MODULES, which is backwards compatible. Kconfiglib will warn if - 'option modules' is set on some other symbol. Tell me if you need proper - 'option modules' support. - - 'modules' is never None. If the MODULES symbol is not explicitly defined, - its tri_value will be 0 (n), as expected. - - A simple way to enable modules is to do 'kconf.modules.set_value(2)' - (provided the MODULES symbol is defined and visible). Modules are - disabled by default in the kernel Kconfig files as of writing, though - nearly all defconfig files enable them (with 'CONFIG_MODULES=y'). - - defconfig_list: - The Symbol instance for the 'option defconfig_list' symbol, or None if no - defconfig_list symbol exists. The defconfig filename derived from this - symbol can be found in Kconfig.defconfig_filename. - - defconfig_filename: - The filename given by the defconfig_list symbol. This is taken from the - first 'default' with a satisfied condition where the specified file - exists (can be opened for reading). If a defconfig file foo/defconfig is - not found and $srctree was set when the Kconfig was created, - $srctree/foo/defconfig is looked up as well. - - 'defconfig_filename' is None if either no defconfig_list symbol exists, - or if the defconfig_list symbol has no 'default' with a satisfied - condition that specifies a file that exists. - - Gotcha: scripts/kconfig/Makefile might pass --defconfig=<defconfig> to - scripts/kconfig/conf when running e.g. 'make defconfig'. This option - overrides the defconfig_list symbol, meaning defconfig_filename might not - always match what 'make defconfig' would use. - - top_node: - The menu node (see the MenuNode class) of the implicit top-level menu. - Acts as the root of the menu tree. - - mainmenu_text: - The prompt (title) of the top menu (top_node). Defaults to "Main menu". - Can be changed with the 'mainmenu' statement (see kconfig-language.txt). - - variables: - A dictionary with all preprocessor variables, indexed by name. See the - Variable class. - - warn: - Set this variable to True/False to enable/disable warnings. See - Kconfig.__init__(). - - When 'warn' is False, the values of the other warning-related variables - are ignored. - - This variable as well as the other warn* variables can be read to check - the current warning settings. - - warn_to_stderr: - Set this variable to True/False to enable/disable warnings on stderr. See - Kconfig.__init__(). - - warn_assign_undef: - Set this variable to True to generate warnings for assignments to - undefined symbols in configuration files. - - This variable is False by default unless the KCONFIG_WARN_UNDEF_ASSIGN - environment variable was set to 'y' when the Kconfig instance was - created. - - warn_assign_override: - Set this variable to True to generate warnings for multiple assignments - to the same symbol in configuration files, where the assignments set - different values (e.g. CONFIG_FOO=m followed by CONFIG_FOO=y, where the - last value would get used). - - This variable is True by default. Disabling it might be useful when - merging configurations. - - warn_assign_redun: - Like warn_assign_override, but for multiple assignments setting a symbol - to the same value. - - This variable is True by default. Disabling it might be useful when - merging configurations. - - warnings: - A list of strings containing all warnings that have been generated, for - cases where more flexibility is needed. - - See the 'warn_to_stderr' parameter to Kconfig.__init__() and the - Kconfig.warn_to_stderr variable as well. Note that warnings still get - added to Kconfig.warnings when 'warn_to_stderr' is True. - - Just as for warnings printed to stderr, only warnings that are enabled - will get added to Kconfig.warnings. See the various Kconfig.warn* - variables. - - missing_syms: - A list with (name, value) tuples for all assignments to undefined symbols - within the most recently loaded .config file(s). 'name' is the symbol - name without the 'CONFIG_' prefix. 'value' is a string that gives the - right-hand side of the assignment verbatim. - - See Kconfig.load_config() as well. - - srctree: - The value the $srctree environment variable had when the Kconfig instance - was created, or the empty string if $srctree wasn't set. This gives nice - behavior with os.path.join(), which treats "" as the current directory, - without adding "./". - - Kconfig files are looked up relative to $srctree (unless absolute paths - are used), and .config files are looked up relative to $srctree if they - are not found in the current directory. This is used to support - out-of-tree builds. The C tools use this environment variable in the same - way. - - Changing $srctree after creating the Kconfig instance has no effect. Only - the value when the configuration is loaded matters. This avoids surprises - if multiple configurations are loaded with different values for $srctree. - - config_prefix: - The value the CONFIG_ environment variable had when the Kconfig instance - was created, or "CONFIG_" if CONFIG_ wasn't set. This is the prefix used - (and expected) on symbol names in .config files and C headers. Used in - the same way in the C tools. - - config_header: - The value the KCONFIG_CONFIG_HEADER environment variable had when the - Kconfig instance was created, or the empty string if - KCONFIG_CONFIG_HEADER wasn't set. This string is inserted verbatim at the - beginning of configuration files. See write_config(). - - header_header: - The value the KCONFIG_AUTOHEADER_HEADER environment variable had when the - Kconfig instance was created, or the empty string if - KCONFIG_AUTOHEADER_HEADER wasn't set. This string is inserted verbatim at - the beginning of header files. See write_autoconf(). - - filename/linenr: - The current parsing location, for use in Python preprocessor functions. - See the module docstring. - """ - __slots__ = ( - "_encoding", - "_functions", - "_set_match", - "_srctree_prefix", - "_unset_match", - "_warn_assign_no_prompt", - "allow_empty_macros", - "choices", - "comments", - "config_header", - "config_prefix", - "const_syms", - "defconfig_list", - "defined_syms", - "env_vars", - "header_header", - "kconfig_filenames", - "m", - "menus", - "missing_syms", - "modules", - "n", - "named_choices", - "srctree", - "search_paths", - "syms", - "top_node", - "unique_choices", - "unique_defined_syms", - "variables", - "warn", - "warn_assign_override", - "warn_assign_redun", - "warn_assign_undef", - "warn_to_stderr", - "warnings", - "y", - - # Parsing-related - "_parsing_kconfigs", - "_readline", - "filename", - "linenr", - "_include_path", - "_filestack", - "_line", - "_tokens", - "_tokens_i", - "_reuse_tokens", - ) - - # - # Public interface - # - - def __init__(self, filename="Kconfig", warn=True, warn_to_stderr=True, - encoding="utf-8", suppress_traceback=False, search_paths=None, - allow_empty_macros=False): - """ - Creates a new Kconfig object by parsing Kconfig files. - Note that Kconfig files are not the same as .config files (which store - configuration symbol values). - - See the module docstring for some environment variables that influence - default warning settings (KCONFIG_WARN_UNDEF and - KCONFIG_WARN_UNDEF_ASSIGN). - - Raises KconfigError on syntax/semantic errors, and OSError or (possibly - a subclass of) IOError on IO errors ('errno', 'strerror', and - 'filename' are available). Note that IOError is an alias for OSError on - Python 3, so it's enough to catch OSError there. If you need Python 2/3 - compatibility, it's easiest to catch EnvironmentError, which is a - common base class of OSError/IOError on Python 2 and an alias for - OSError on Python 3. - - filename (default: "Kconfig"): - The Kconfig file to load. For the Linux kernel, you'll want "Kconfig" - from the top-level directory, as environment variables will make sure - the right Kconfig is included from there (arch/$SRCARCH/Kconfig as of - writing). - - If $srctree is set, 'filename' will be looked up relative to it. - $srctree is also used to look up source'd files within Kconfig files. - See the class documentation. - - If you are using Kconfiglib via 'make scriptconfig', the filename of - the base base Kconfig file will be in sys.argv[1]. It's currently - always "Kconfig" in practice. - - warn (default: True): - True if warnings related to this configuration should be generated. - This can be changed later by setting Kconfig.warn to True/False. It - is provided as a constructor argument since warnings might be - generated during parsing. - - See the other Kconfig.warn_* variables as well, which enable or - suppress certain warnings when warnings are enabled. - - All generated warnings are added to the Kconfig.warnings list. See - the class documentation. - - warn_to_stderr (default: True): - True if warnings should be printed to stderr in addition to being - added to Kconfig.warnings. - - This can be changed later by setting Kconfig.warn_to_stderr to - True/False. - - encoding (default: "utf-8"): - The encoding to use when reading and writing files, and when decoding - output from commands run via $(shell). If None, the encoding - specified in the current locale will be used. - - The "utf-8" default avoids exceptions on systems that are configured - to use the C locale, which implies an ASCII encoding. - - This parameter has no effect on Python 2, due to implementation - issues (regular strings turning into Unicode strings, which are - distinct in Python 2). Python 2 doesn't decode regular strings - anyway. - - Related PEP: https://www.python.org/dev/peps/pep-0538/ - - suppress_traceback (default: False): - Helper for tools. When True, any EnvironmentError or KconfigError - generated during parsing is caught, the exception message is printed - to stderr together with the command name, and sys.exit(1) is called - (which generates SystemExit). - - This hides the Python traceback for "expected" errors like syntax - errors in Kconfig files. - - Other exceptions besides EnvironmentError and KconfigError are still - propagated when suppress_traceback is True. - - search_paths (default: None): - List of paths to search for Kconfig files. This is needed when the - files are split between two project directories, as is done with - Zephyr OS, for example. It allows files in one project to reference - files in another. - - This argument affects the operation of commands which include other - Kconfig files, such as `source` and `rsource`. - - When not None, it should be a list of paths to directories to search. - Each search path is prepended to the relative filename to assist in - finding the file. The proeect directories should have distinct - filenames and/or subdirectory structures, so avoid ambiguity. - - allow_empty_macros (default: False): - Normally when macros expand to empty it means that the macro is not - defined. This is considered an error and parsing of the Kconfig files - aborts with an exception. In some cases it is useful to continue - parsing, to obtain what information is available. - - An example is where the value of various macros is not known but the - caller simply wants to get a list of the available Kconfig options. - - Pass True here to allow empty / undefined macros. - """ - try: - self._init(filename, warn, warn_to_stderr, encoding, search_paths, - allow_empty_macros) - except (EnvironmentError, KconfigError) as e: - if suppress_traceback: - cmd = sys.argv[0] # Empty string if missing - if cmd: - cmd += ": " - # Some long exception messages have extra newlines for better - # formatting when reported as an unhandled exception. Strip - # them here. - sys.exit(cmd + str(e).strip()) - raise - - def _init(self, filename, warn, warn_to_stderr, encoding, search_paths, - allow_empty_macros): - # See __init__() - - self._encoding = encoding - - self.srctree = os.getenv("srctree", "") - # A prefix we can reliably strip from glob() results to get a filename - # relative to $srctree. relpath() can cause issues for symlinks, - # because it assumes symlink/../foo is the same as foo/. - self._srctree_prefix = realpath(self.srctree) + os.sep - self.search_paths = search_paths - self.allow_empty_macros = allow_empty_macros - - self.warn = warn - self.warn_to_stderr = warn_to_stderr - self.warn_assign_undef = os.getenv("KCONFIG_WARN_UNDEF_ASSIGN") == "y" - self.warn_assign_override = True - self.warn_assign_redun = True - self._warn_assign_no_prompt = True - - self.warnings = [] - - self.config_prefix = os.getenv("CONFIG_", "CONFIG_") - # Regular expressions for parsing .config files - self._set_match = _re_match(self.config_prefix + r"([^=]+)=(.*)") - self._unset_match = _re_match(r"# {}([^ ]+) is not set".format( - self.config_prefix)) - - self.config_header = os.getenv("KCONFIG_CONFIG_HEADER", "") - self.header_header = os.getenv("KCONFIG_AUTOHEADER_HEADER", "") - - self.syms = {} - self.const_syms = {} - self.defined_syms = [] - self.missing_syms = [] - self.named_choices = {} - self.choices = [] - self.menus = [] - self.comments = [] - - for nmy in "n", "m", "y": - sym = Symbol() - sym.kconfig = self - sym.name = nmy - sym.is_constant = True - sym.orig_type = TRISTATE - sym._cached_tri_val = STR_TO_TRI[nmy] - - self.const_syms[nmy] = sym - - self.n = self.const_syms["n"] - self.m = self.const_syms["m"] - self.y = self.const_syms["y"] - - # Make n/m/y well-formed symbols - for nmy in "n", "m", "y": - sym = self.const_syms[nmy] - sym.rev_dep = sym.weak_rev_dep = sym.direct_dep = self.n - - # Maps preprocessor variables names to Variable instances - self.variables = {} - - # Predefined preprocessor functions, with min/max number of arguments - self._functions = { - "info": (_info_fn, 1, 1), - "error-if": (_error_if_fn, 2, 2), - "filename": (_filename_fn, 0, 0), - "lineno": (_lineno_fn, 0, 0), - "shell": (_shell_fn, 1, 1), - "warning-if": (_warning_if_fn, 2, 2), - } - - # Add any user-defined preprocessor functions - try: - self._functions.update( - importlib.import_module( - os.getenv("KCONFIG_FUNCTIONS", "kconfigfunctions") - ).functions) - except ImportError: - pass - - # This determines whether previously unseen symbols are registered. - # They shouldn't be if we parse expressions after parsing, as part of - # Kconfig.eval_string(). - self._parsing_kconfigs = True - - self.modules = self._lookup_sym("MODULES") - self.defconfig_list = None - - self.top_node = MenuNode() - self.top_node.kconfig = self - self.top_node.item = MENU - self.top_node.is_menuconfig = True - self.top_node.visibility = self.y - self.top_node.prompt = ("Main menu", self.y) - self.top_node.parent = None - self.top_node.dep = self.y - self.top_node.filename = filename - self.top_node.linenr = 1 - self.top_node.include_path = () - - # Parse the Kconfig files - - # Not used internally. Provided as a convenience. - self.kconfig_filenames = [filename] - self.env_vars = set() - - # Keeps track of the location in the parent Kconfig files. Kconfig - # files usually source other Kconfig files. See _enter_file(). - self._filestack = [] - self._include_path = () - - # The current parsing location - self.filename = filename - self.linenr = 0 - - # Used to avoid retokenizing lines when we discover that they're not - # part of the construct currently being parsed. This is kinda like an - # unget operation. - self._reuse_tokens = False - - # Open the top-level Kconfig file. Store the readline() method directly - # as a small optimization. - self._readline = self._open(join(self.srctree, filename), "r").readline - - try: - # Parse the Kconfig files. Returns the last node, which we - # terminate with '.next = None'. - self._parse_block(None, self.top_node, self.top_node).next = None - self.top_node.list = self.top_node.next - self.top_node.next = None - except UnicodeDecodeError as e: - _decoding_error(e, self.filename) - - # Close the top-level Kconfig file. __self__ fetches the 'file' object - # for the method. - self._readline.__self__.close() - - self._parsing_kconfigs = False - - # Do various menu tree post-processing - self._finalize_node(self.top_node, self.y) - - self.unique_defined_syms = _ordered_unique(self.defined_syms) - self.unique_choices = _ordered_unique(self.choices) - - # Do sanity checks. Some of these depend on everything being finalized. - self._check_sym_sanity() - self._check_choice_sanity() - - # KCONFIG_STRICT is an older alias for KCONFIG_WARN_UNDEF, supported - # for backwards compatibility - if os.getenv("KCONFIG_WARN_UNDEF") == "y" or \ - os.getenv("KCONFIG_STRICT") == "y": - - self._check_undef_syms() - - # Build Symbol._dependents for all symbols and choices - self._build_dep() - - # Check for dependency loops - check_dep_loop_sym = _check_dep_loop_sym # Micro-optimization - for sym in self.unique_defined_syms: - check_dep_loop_sym(sym, False) - - # Add extra dependencies from choices to choice symbols that get - # awkward during dependency loop detection - self._add_choice_deps() - - @property - def mainmenu_text(self): - """ - See the class documentation. - """ - return self.top_node.prompt[0] - - @property - def defconfig_filename(self): - """ - See the class documentation. - """ - if self.defconfig_list: - for filename, cond in self.defconfig_list.defaults: - if expr_value(cond): - try: - with self._open_config(filename.str_value) as f: - return f.name - except EnvironmentError: - continue - - return None - - def load_config(self, filename=None, replace=True, verbose=None): - """ - Loads symbol values from a file in the .config format. Equivalent to - calling Symbol.set_value() to set each of the values. - - "# CONFIG_FOO is not set" within a .config file sets the user value of - FOO to n. The C tools work the same way. - - For each symbol, the Symbol.user_value attribute holds the value the - symbol was assigned in the .config file (if any). The user value might - differ from Symbol.str/tri_value if there are unsatisfied dependencies. - - Calling this function also updates the Kconfig.missing_syms attribute - with a list of all assignments to undefined symbols within the - configuration file. Kconfig.missing_syms is cleared if 'replace' is - True, and appended to otherwise. See the documentation for - Kconfig.missing_syms as well. - - See the Kconfig.__init__() docstring for raised exceptions - (OSError/IOError). KconfigError is never raised here. - - filename (default: None): - Path to load configuration from (a string). Respects $srctree if set - (see the class documentation). - - If 'filename' is None (the default), the configuration file to load - (if any) is calculated automatically, giving the behavior you'd - usually want: - - 1. If the KCONFIG_CONFIG environment variable is set, it gives the - path to the configuration file to load. Otherwise, ".config" is - used. See standard_config_filename(). - - 2. If the path from (1.) doesn't exist, the configuration file - given by kconf.defconfig_filename is loaded instead, which is - derived from the 'option defconfig_list' symbol. - - 3. If (1.) and (2.) fail to find a configuration file to load, no - configuration file is loaded, and symbols retain their current - values (e.g., their default values). This is not an error. - - See the return value as well. - - replace (default: True): - If True, all existing user values will be cleared before loading the - .config. Pass False to merge configurations. - - verbose (default: None): - Limited backwards compatibility to prevent crashes. A warning is - printed if anything but None is passed. - - Prior to Kconfiglib 12.0.0, this option enabled printing of messages - to stdout when 'filename' was None. A message is (always) returned - now instead, which is more flexible. - - Will probably be removed in some future version. - - Returns a string with a message saying which file got loaded (or - possibly that no file got loaded, when 'filename' is None). This is - meant to reduce boilerplate in tools, which can do e.g. - print(kconf.load_config()). The returned message distinguishes between - loading (replace == True) and merging (replace == False). - """ - if verbose is not None: - _warn_verbose_deprecated("load_config") - - msg = None - if filename is None: - filename = standard_config_filename() - if not exists(filename) and \ - not exists(join(self.srctree, filename)): - defconfig = self.defconfig_filename - if defconfig is None: - return "Using default symbol values (no '{}')" \ - .format(filename) - - msg = " default configuration '{}' (no '{}')" \ - .format(defconfig, filename) - filename = defconfig - - if not msg: - msg = " configuration '{}'".format(filename) - - # Disable the warning about assigning to symbols without prompts. This - # is normal and expected within a .config file. - self._warn_assign_no_prompt = False - - # This stub only exists to make sure _warn_assign_no_prompt gets - # reenabled - try: - self._load_config(filename, replace) - except UnicodeDecodeError as e: - _decoding_error(e, filename) - finally: - self._warn_assign_no_prompt = True - - return ("Loaded" if replace else "Merged") + msg - - def _load_config(self, filename, replace): - with self._open_config(filename) as f: - if replace: - self.missing_syms = [] - - # If we're replacing the configuration, keep track of which - # symbols and choices got set so that we can unset the rest - # later. This avoids invalidating everything and is faster. - # Another benefit is that invalidation must be rock solid for - # it to work, making it a good test. - - for sym in self.unique_defined_syms: - sym._was_set = False - - for choice in self.unique_choices: - choice._was_set = False - - # Small optimizations - set_match = self._set_match - unset_match = self._unset_match - get_sym = self.syms.get - - for linenr, line in enumerate(f, 1): - # The C tools ignore trailing whitespace - line = line.rstrip() - - match = set_match(line) - if match: - name, val = match.groups() - sym = get_sym(name) - if not sym or not sym.nodes: - self._undef_assign(name, val, filename, linenr) - continue - - if sym.orig_type in _BOOL_TRISTATE: - # The C implementation only checks the first character - # to the right of '=', for whatever reason - if not (sym.orig_type is BOOL - and val.startswith(("y", "n")) or - sym.orig_type is TRISTATE - and val.startswith(("y", "m", "n"))): - self._warn("'{}' is not a valid value for the {} " - "symbol {}. Assignment ignored." - .format(val, TYPE_TO_STR[sym.orig_type], - sym.name_and_loc), - filename, linenr) - continue - - val = val[0] - - if sym.choice and val != "n": - # During .config loading, we infer the mode of the - # choice from the kind of values that are assigned - # to the choice symbols - - prev_mode = sym.choice.user_value - if prev_mode is not None and \ - TRI_TO_STR[prev_mode] != val: - - self._warn("both m and y assigned to symbols " - "within the same choice", - filename, linenr) - - # Set the choice's mode - sym.choice.set_value(val) - - elif sym.orig_type is STRING: - match = _conf_string_match(val) - if not match: - self._warn("malformed string literal in " - "assignment to {}. Assignment ignored." - .format(sym.name_and_loc), - filename, linenr) - continue - - val = unescape(match.group(1)) - - else: - match = unset_match(line) - if not match: - # Print a warning for lines that match neither - # set_match() nor unset_match() and that are not blank - # lines or comments. 'line' has already been - # rstrip()'d, so blank lines show up as "" here. - if line and not line.lstrip().startswith("#"): - self._warn("ignoring malformed line '{}'" - .format(line), - filename, linenr) - - continue - - name = match.group(1) - sym = get_sym(name) - if not sym or not sym.nodes: - self._undef_assign(name, "n", filename, linenr) - continue - - if sym.orig_type not in _BOOL_TRISTATE: - continue - - val = "n" - - # Done parsing the assignment. Set the value. - - if sym._was_set: - self._assigned_twice(sym, val, filename, linenr) - - sym.set_value(val) - - if replace: - # If we're replacing the configuration, unset the symbols that - # didn't get set - - for sym in self.unique_defined_syms: - if not sym._was_set: - sym.unset_value() - - for choice in self.unique_choices: - if not choice._was_set: - choice.unset_value() - - def _undef_assign(self, name, val, filename, linenr): - # Called for assignments to undefined symbols during .config loading - - self.missing_syms.append((name, val)) - if self.warn_assign_undef: - self._warn( - "attempt to assign the value '{}' to the undefined symbol {}" - .format(val, name), filename, linenr) - - def _assigned_twice(self, sym, new_val, filename, linenr): - # Called when a symbol is assigned more than once in a .config file - - # Use strings for bool/tristate user values in the warning - if sym.orig_type in _BOOL_TRISTATE: - user_val = TRI_TO_STR[sym.user_value] - else: - user_val = sym.user_value - - msg = '{} set more than once. Old value "{}", new value "{}".'.format( - sym.name_and_loc, user_val, new_val) - - if user_val == new_val: - if self.warn_assign_redun: - self._warn(msg, filename, linenr) - elif self.warn_assign_override: - self._warn(msg, filename, linenr) - - def load_allconfig(self, filename): - """ - Helper for all*config. Loads (merges) the configuration file specified - by KCONFIG_ALLCONFIG, if any. See Documentation/kbuild/kconfig.txt in - the Linux kernel. - - Disables warnings for duplicated assignments within configuration files - for the duration of the call - (kconf.warn_assign_override/warn_assign_redun = False), and restores - the previous warning settings at the end. The KCONFIG_ALLCONFIG - configuration file is expected to override symbols. - - Exits with sys.exit() (which raises a SystemExit exception) and prints - an error to stderr if KCONFIG_ALLCONFIG is set but the configuration - file can't be opened. - - filename: - Command-specific configuration filename - "allyes.config", - "allno.config", etc. - """ - load_allconfig(self, filename) - - def write_autoconf(self, filename=None, header=None): - r""" - Writes out symbol values as a C header file, matching the format used - by include/generated/autoconf.h in the kernel. - - The ordering of the #defines matches the one generated by - write_config(). The order in the C implementation depends on the hash - table implementation as of writing, and so won't match. - - If 'filename' exists and its contents is identical to what would get - written out, it is left untouched. This avoids updating file metadata - like the modification time and possibly triggering redundant work in - build tools. - - filename (default: None): - Path to write header to. - - If None (the default), the path in the environment variable - KCONFIG_AUTOHEADER is used if set, and "include/generated/autoconf.h" - otherwise. This is compatible with the C tools. - - header (default: None): - Text inserted verbatim at the beginning of the file. You would - usually want it enclosed in '/* */' to make it a C comment, and - include a trailing newline. - - If None (the default), the value of the environment variable - KCONFIG_AUTOHEADER_HEADER had when the Kconfig instance was created - will be used if it was set, and no header otherwise. See the - Kconfig.header_header attribute. - - Returns a string with a message saying that the header got saved, or - that there were no changes to it. This is meant to reduce boilerplate - in tools, which can do e.g. print(kconf.write_autoconf()). - """ - if filename is None: - filename = os.getenv("KCONFIG_AUTOHEADER", - "include/generated/autoconf.h") - - if self._write_if_changed(filename, self._autoconf_contents(header)): - return "Kconfig header saved to '{}'".format(filename) - return "No change to Kconfig header in '{}'".format(filename) - - def _autoconf_contents(self, header): - # write_autoconf() helper. Returns the contents to write as a string, - # with 'header' or KCONFIG_AUTOHEADER_HEADER at the beginning. - - if header is None: - header = self.header_header - - chunks = [header] # "".join()ed later - add = chunks.append - - for sym in self.unique_defined_syms: - # _write_to_conf is determined when the value is calculated. This - # is a hidden function call due to property magic. - # - # Note: In client code, you can check if sym.config_string is empty - # instead, to avoid accessing the internal _write_to_conf variable - # (though it's likely to keep working). - val = sym.str_value - if not sym._write_to_conf: - continue - - if sym.orig_type in _BOOL_TRISTATE: - if val == "y": - add("#define {}{} 1\n" - .format(self.config_prefix, sym.name)) - elif val == "m": - add("#define {}{}_MODULE 1\n" - .format(self.config_prefix, sym.name)) - - elif sym.orig_type is STRING: - add('#define {}{} "{}"\n' - .format(self.config_prefix, sym.name, escape(val))) - - else: # sym.orig_type in _INT_HEX: - if sym.orig_type is HEX and \ - not val.startswith(("0x", "0X")): - val = "0x" + val - - add("#define {}{} {}\n" - .format(self.config_prefix, sym.name, val)) - - return "".join(chunks) - - def write_config(self, filename=None, header=None, save_old=True, - verbose=None): - r""" - Writes out symbol values in the .config format. The format matches the - C implementation, including ordering. - - Symbols appear in the same order in generated .config files as they do - in the Kconfig files. For symbols defined in multiple locations, a - single assignment is written out corresponding to the first location - where the symbol is defined. - - See the 'Intro to symbol values' section in the module docstring to - understand which symbols get written out. - - If 'filename' exists and its contents is identical to what would get - written out, it is left untouched. This avoids updating file metadata - like the modification time and possibly triggering redundant work in - build tools. - - See the Kconfig.__init__() docstring for raised exceptions - (OSError/IOError). KconfigError is never raised here. - - filename (default: None): - Path to write configuration to (a string). - - If None (the default), the path in the environment variable - KCONFIG_CONFIG is used if set, and ".config" otherwise. See - standard_config_filename(). - - header (default: None): - Text inserted verbatim at the beginning of the file. You would - usually want each line to start with '#' to make it a comment, and - include a trailing newline. - - if None (the default), the value of the environment variable - KCONFIG_CONFIG_HEADER had when the Kconfig instance was created will - be used if it was set, and no header otherwise. See the - Kconfig.config_header attribute. - - save_old (default: True): - If True and <filename> already exists, a copy of it will be saved to - <filename>.old in the same directory before the new configuration is - written. - - Errors are silently ignored if <filename>.old cannot be written (e.g. - due to being a directory, or <filename> being something like - /dev/null). - - verbose (default: None): - Limited backwards compatibility to prevent crashes. A warning is - printed if anything but None is passed. - - Prior to Kconfiglib 12.0.0, this option enabled printing of messages - to stdout when 'filename' was None. A message is (always) returned - now instead, which is more flexible. - - Will probably be removed in some future version. - - Returns a string with a message saying which file got saved. This is - meant to reduce boilerplate in tools, which can do e.g. - print(kconf.write_config()). - """ - if verbose is not None: - _warn_verbose_deprecated("write_config") - - if filename is None: - filename = standard_config_filename() - - contents = self._config_contents(header) - if self._contents_eq(filename, contents): - return "No change to configuration in '{}'".format(filename) - - if save_old: - _save_old(filename) - - with self._open(filename, "w") as f: - f.write(contents) - - return "Configuration saved to '{}'".format(filename) - - def _config_contents(self, header): - # write_config() helper. Returns the contents to write as a string, - # with 'header' or KCONFIG_CONFIG_HEADER at the beginning. - # - # More memory friendly would be to 'yield' the strings and - # "".join(_config_contents()), but it was a bit slower on my system. - - # node_iter() was used here before commit 3aea9f7 ("Add '# end of - # <menu>' after menus in .config"). Those comments get tricky to - # implement with it. - - for sym in self.unique_defined_syms: - sym._visited = False - - if header is None: - header = self.config_header - - chunks = [header] # "".join()ed later - add = chunks.append - - # Did we just print an '# end of ...' comment? - after_end_comment = False - - node = self.top_node - while 1: - # Jump to the next node with an iterative tree walk - if node.list: - node = node.list - elif node.next: - node = node.next - else: - while node.parent: - node = node.parent - - # Add a comment when leaving visible menus - if node.item is MENU and expr_value(node.dep) and \ - expr_value(node.visibility) and \ - node is not self.top_node: - add("# end of {}\n".format(node.prompt[0])) - after_end_comment = True - - if node.next: - node = node.next - break - else: - # No more nodes - return "".join(chunks) - - # Generate configuration output for the node - - item = node.item - - if item.__class__ is Symbol: - if item._visited: - continue - item._visited = True - - conf_string = item.config_string - if not conf_string: - continue - - if after_end_comment: - # Add a blank line before the first symbol printed after an - # '# end of ...' comment - after_end_comment = False - add("\n") - add(conf_string) - - elif expr_value(node.dep) and \ - ((item is MENU and expr_value(node.visibility)) or - item is COMMENT): - - add("\n#\n# {}\n#\n".format(node.prompt[0])) - after_end_comment = False - - def write_min_config(self, filename, header=None): - """ - Writes out a "minimal" configuration file, omitting symbols whose value - matches their default value. The format matches the one produced by - 'make savedefconfig'. - - The resulting configuration file is incomplete, but a complete - configuration can be derived from it by loading it. Minimal - configuration files can serve as a more manageable configuration format - compared to a "full" .config file, especially when configurations files - are merged or edited by hand. - - See the Kconfig.__init__() docstring for raised exceptions - (OSError/IOError). KconfigError is never raised here. - - filename: - Path to write minimal configuration to. - - header (default: None): - Text inserted verbatim at the beginning of the file. You would - usually want each line to start with '#' to make it a comment, and - include a final terminating newline. - - if None (the default), the value of the environment variable - KCONFIG_CONFIG_HEADER had when the Kconfig instance was created will - be used if it was set, and no header otherwise. See the - Kconfig.config_header attribute. - - Returns a string with a message saying the minimal configuration got - saved, or that there were no changes to it. This is meant to reduce - boilerplate in tools, which can do e.g. - print(kconf.write_min_config()). - """ - if self._write_if_changed(filename, self._min_config_contents(header)): - return "Minimal configuration saved to '{}'".format(filename) - return "No change to minimal configuration in '{}'".format(filename) - - def _min_config_contents(self, header): - # write_min_config() helper. Returns the contents to write as a string, - # with 'header' or KCONFIG_CONFIG_HEADER at the beginning. - - if header is None: - header = self.config_header - - chunks = [header] # "".join()ed later - add = chunks.append - - for sym in self.unique_defined_syms: - # Skip symbols that cannot be changed. Only check - # non-choice symbols, as selects don't affect choice - # symbols. - if not sym.choice and \ - sym.visibility <= expr_value(sym.rev_dep): - continue - - # Skip symbols whose value matches their default - if sym.str_value == sym._str_default(): - continue - - # Skip symbols that would be selected by default in a - # choice, unless the choice is optional or the symbol type - # isn't bool (it might be possible to set the choice mode - # to n or the symbol to m in those cases). - if sym.choice and \ - not sym.choice.is_optional and \ - sym.choice._selection_from_defaults() is sym and \ - sym.orig_type is BOOL and \ - sym.tri_value == 2: - continue - - add(sym.config_string) - - return "".join(chunks) - - def sync_deps(self, path): - """ - Creates or updates a directory structure that can be used to avoid - doing a full rebuild whenever the configuration is changed, mirroring - include/config/ in the kernel. - - This function is intended to be called during each build, before - compiling source files that depend on configuration symbols. - - See the Kconfig.__init__() docstring for raised exceptions - (OSError/IOError). KconfigError is never raised here. - - path: - Path to directory - - sync_deps(path) does the following: - - 1. If the directory <path> does not exist, it is created. - - 2. If <path>/auto.conf exists, old symbol values are loaded from it, - which are then compared against the current symbol values. If a - symbol has changed value (would generate different output in - autoconf.h compared to before), the change is signaled by - touch'ing a file corresponding to the symbol. - - The first time sync_deps() is run on a directory, <path>/auto.conf - won't exist, and no old symbol values will be available. This - logically has the same effect as updating the entire - configuration. - - The path to a symbol's file is calculated from the symbol's name - by replacing all '_' with '/' and appending '.h'. For example, the - symbol FOO_BAR_BAZ gets the file <path>/foo/bar/baz.h, and FOO - gets the file <path>/foo.h. - - This scheme matches the C tools. The point is to avoid having a - single directory with a huge number of files, which the underlying - filesystem might not handle well. - - 3. A new auto.conf with the current symbol values is written, to keep - track of them for the next build. - - If auto.conf exists and its contents is identical to what would - get written out, it is left untouched. This avoids updating file - metadata like the modification time and possibly triggering - redundant work in build tools. - - - The last piece of the puzzle is knowing what symbols each source file - depends on. Knowing that, dependencies can be added from source files - to the files corresponding to the symbols they depends on. The source - file will then get recompiled (only) when the symbol value changes - (provided sync_deps() is run first during each build). - - The tool in the kernel that extracts symbol dependencies from source - files is scripts/basic/fixdep.c. Missing symbol files also correspond - to "not changed", which fixdep deals with by using the $(wildcard) Make - function when adding symbol prerequisites to source files. - - In case you need a different scheme for your project, the sync_deps() - implementation can be used as a template. - """ - if not exists(path): - os.mkdir(path, 0o755) - - # Load old values from auto.conf, if any - self._load_old_vals(path) - - for sym in self.unique_defined_syms: - # _write_to_conf is determined when the value is calculated. This - # is a hidden function call due to property magic. - # - # Note: In client code, you can check if sym.config_string is empty - # instead, to avoid accessing the internal _write_to_conf variable - # (though it's likely to keep working). - val = sym.str_value - - # n tristate values do not get written to auto.conf and autoconf.h, - # making a missing symbol logically equivalent to n - - if sym._write_to_conf: - if sym._old_val is None and \ - sym.orig_type in _BOOL_TRISTATE and \ - val == "n": - # No old value (the symbol was missing or n), new value n. - # No change. - continue - - if val == sym._old_val: - # New value matches old. No change. - continue - - elif sym._old_val is None: - # The symbol wouldn't appear in autoconf.h (because - # _write_to_conf is false), and it wouldn't have appeared in - # autoconf.h previously either (because it didn't appear in - # auto.conf). No change. - continue - - # 'sym' has a new value. Flag it. - _touch_dep_file(path, sym.name) - - # Remember the current values as the "new old" values. - # - # This call could go anywhere after the call to _load_old_vals(), but - # putting it last means _sync_deps() can be safely rerun if it fails - # before this point. - self._write_old_vals(path) - - def _load_old_vals(self, path): - # Loads old symbol values from auto.conf into a dedicated - # Symbol._old_val field. Mirrors load_config(). - # - # The extra field could be avoided with some trickery involving dumping - # symbol values and restoring them later, but this is simpler and - # faster. The C tools also use a dedicated field for this purpose. - - for sym in self.unique_defined_syms: - sym._old_val = None - - try: - auto_conf = self._open(join(path, "auto.conf"), "r") - except EnvironmentError as e: - if e.errno == errno.ENOENT: - # No old values - return - raise - - with auto_conf as f: - for line in f: - match = self._set_match(line) - if not match: - # We only expect CONFIG_FOO=... (and possibly a header - # comment) in auto.conf - continue - - name, val = match.groups() - if name in self.syms: - sym = self.syms[name] - - if sym.orig_type is STRING: - match = _conf_string_match(val) - if not match: - continue - val = unescape(match.group(1)) - - self.syms[name]._old_val = val - else: - # Flag that the symbol no longer exists, in - # case something still depends on it - _touch_dep_file(path, name) - - def _write_old_vals(self, path): - # Helper for writing auto.conf. Basically just a simplified - # write_config() that doesn't write any comments (including - # '# CONFIG_FOO is not set' comments). The format matches the C - # implementation, though the ordering is arbitrary there (depends on - # the hash table implementation). - # - # A separate helper function is neater than complicating write_config() - # by passing a flag to it, plus we only need to look at symbols here. - - self._write_if_changed( - os.path.join(path, "auto.conf"), - self._old_vals_contents()) - - def _old_vals_contents(self): - # _write_old_vals() helper. Returns the contents to write as a string. - - # Temporary list instead of generator makes this a bit faster - return "".join([ - sym.config_string for sym in self.unique_defined_syms - if not (sym.orig_type in _BOOL_TRISTATE and not sym.tri_value) - ]) - - def node_iter(self, unique_syms=False): - """ - Returns a generator for iterating through all MenuNode's in the Kconfig - tree. The iteration is done in Kconfig definition order (each node is - visited before its children, and the children of a node are visited - before the next node). - - The Kconfig.top_node menu node is skipped. It contains an implicit menu - that holds the top-level items. - - As an example, the following code will produce a list equal to - Kconfig.defined_syms: - - defined_syms = [node.item for node in kconf.node_iter() - if isinstance(node.item, Symbol)] - - unique_syms (default: False): - If True, only the first MenuNode will be included for symbols defined - in multiple locations. - - Using kconf.node_iter(True) in the example above would give a list - equal to unique_defined_syms. - """ - if unique_syms: - for sym in self.unique_defined_syms: - sym._visited = False - - node = self.top_node - while 1: - # Jump to the next node with an iterative tree walk - if node.list: - node = node.list - elif node.next: - node = node.next - else: - while node.parent: - node = node.parent - if node.next: - node = node.next - break - else: - # No more nodes - return - - if unique_syms and node.item.__class__ is Symbol: - if node.item._visited: - continue - node.item._visited = True - - yield node - - def eval_string(self, s): - """ - Returns the tristate value of the expression 's', represented as 0, 1, - and 2 for n, m, and y, respectively. Raises KconfigError on syntax - errors. Warns if undefined symbols are referenced. - - As an example, if FOO and BAR are tristate symbols at least one of - which has the value y, then eval_string("y && (FOO || BAR)") returns - 2 (y). - - To get the string value of non-bool/tristate symbols, use - Symbol.str_value. eval_string() always returns a tristate value, and - all non-bool/tristate symbols have the tristate value 0 (n). - - The expression parsing is consistent with how parsing works for - conditional ('if ...') expressions in the configuration, and matches - the C implementation. m is rewritten to 'm && MODULES', so - eval_string("m") will return 0 (n) unless modules are enabled. - """ - # The parser is optimized to be fast when parsing Kconfig files (where - # an expression can never appear at the beginning of a line). We have - # to monkey-patch things a bit here to reuse it. - - self.filename = None - - self._tokens = self._tokenize("if " + s) - # Strip "if " to avoid giving confusing error messages - self._line = s - self._tokens_i = 1 # Skip the 'if' token - - return expr_value(self._expect_expr_and_eol()) - - def unset_values(self): - """ - Removes any user values from all symbols, as if Kconfig.load_config() - or Symbol.set_value() had never been called. - """ - self._warn_assign_no_prompt = False - try: - # set_value() already rejects undefined symbols, and they don't - # need to be invalidated (because their value never changes), so we - # can just iterate over defined symbols - for sym in self.unique_defined_syms: - sym.unset_value() - - for choice in self.unique_choices: - choice.unset_value() - finally: - self._warn_assign_no_prompt = True - - def enable_warnings(self): - """ - Do 'Kconfig.warn = True' instead. Maintained for backwards - compatibility. - """ - self.warn = True - - def disable_warnings(self): - """ - Do 'Kconfig.warn = False' instead. Maintained for backwards - compatibility. - """ - self.warn = False - - def enable_stderr_warnings(self): - """ - Do 'Kconfig.warn_to_stderr = True' instead. Maintained for backwards - compatibility. - """ - self.warn_to_stderr = True - - def disable_stderr_warnings(self): - """ - Do 'Kconfig.warn_to_stderr = False' instead. Maintained for backwards - compatibility. - """ - self.warn_to_stderr = False - - def enable_undef_warnings(self): - """ - Do 'Kconfig.warn_assign_undef = True' instead. Maintained for backwards - compatibility. - """ - self.warn_assign_undef = True - - def disable_undef_warnings(self): - """ - Do 'Kconfig.warn_assign_undef = False' instead. Maintained for - backwards compatibility. - """ - self.warn_assign_undef = False - - def enable_override_warnings(self): - """ - Do 'Kconfig.warn_assign_override = True' instead. Maintained for - backwards compatibility. - """ - self.warn_assign_override = True - - def disable_override_warnings(self): - """ - Do 'Kconfig.warn_assign_override = False' instead. Maintained for - backwards compatibility. - """ - self.warn_assign_override = False - - def enable_redun_warnings(self): - """ - Do 'Kconfig.warn_assign_redun = True' instead. Maintained for backwards - compatibility. - """ - self.warn_assign_redun = True - - def disable_redun_warnings(self): - """ - Do 'Kconfig.warn_assign_redun = False' instead. Maintained for - backwards compatibility. - """ - self.warn_assign_redun = False - - def __repr__(self): - """ - Returns a string with information about the Kconfig object when it is - evaluated on e.g. the interactive Python prompt. - """ - def status(flag): - return "enabled" if flag else "disabled" - - return "<{}>".format(", ".join(( - "configuration with {} symbols".format(len(self.syms)), - 'main menu prompt "{}"'.format(self.mainmenu_text), - "srctree is current directory" if not self.srctree else - 'srctree "{}"'.format(self.srctree), - 'config symbol prefix "{}"'.format(self.config_prefix), - "warnings " + status(self.warn), - "printing of warnings to stderr " + status(self.warn_to_stderr), - "undef. symbol assignment warnings " + - status(self.warn_assign_undef), - "overriding symbol assignment warnings " + - status(self.warn_assign_override), - "redundant symbol assignment warnings " + - status(self.warn_assign_redun) - ))) - - # - # Private methods - # - - - # - # File reading - # - - def _open_config(self, filename): - # Opens a .config file. First tries to open 'filename', then - # '$srctree/filename' if $srctree was set when the configuration was - # loaded. - - try: - return self._open(filename, "r") - except EnvironmentError as e: - # This will try opening the same file twice if $srctree is unset, - # but it's not a big deal - try: - return self._open(join(self.srctree, filename), "r") - except EnvironmentError as e2: - # This is needed for Python 3, because e2 is deleted after - # the try block: - # - # https://docs.python.org/3/reference/compound_stmts.html#the-try-statement - e = e2 - - raise _KconfigIOError( - e, "Could not open '{}' ({}: {}). Check that the $srctree " - "environment variable ({}) is set correctly." - .format(filename, errno.errorcode[e.errno], e.strerror, - "set to '{}'".format(self.srctree) if self.srctree - else "unset or blank")) - - def _enter_file(self, filename): - # Jumps to the beginning of a sourced Kconfig file, saving the previous - # position and file object. - # - # filename: - # Absolute path to file - - # Path relative to $srctree, stored in e.g. self.filename (which makes - # it indirectly show up in MenuNode.filename). Equals 'filename' for - # absolute paths passed to 'source'. - if filename.startswith(self._srctree_prefix): - # Relative path (or a redundant absolute path to within $srctree, - # but it's probably fine to reduce those too) - rel_filename = filename[len(self._srctree_prefix):] - else: - # Absolute path - rel_filename = filename - - self.kconfig_filenames.append(rel_filename) - - # The parent Kconfig files are represented as a list of - # (<include path>, <Python 'file' object for Kconfig file>) tuples. - # - # <include path> is immutable and holds a *tuple* of - # (<filename>, <linenr>) tuples, giving the locations of the 'source' - # statements in the parent Kconfig files. The current include path is - # also available in Kconfig._include_path. - # - # The point of this redundant setup is to allow Kconfig._include_path - # to be assigned directly to MenuNode.include_path without having to - # copy it, sharing it wherever possible. - - # Save include path and 'file' object (via its 'readline' function) - # before entering the file - self._filestack.append((self._include_path, self._readline)) - - # _include_path is a tuple, so this rebinds the variable instead of - # doing in-place modification - self._include_path += ((self.filename, self.linenr),) - - # Check for recursive 'source' - for name, _ in self._include_path: - if name == rel_filename: - raise KconfigError( - "\n{}:{}: recursive 'source' of '{}' detected. Check that " - "environment variables are set correctly.\n" - "Include path:\n{}" - .format(self.filename, self.linenr, rel_filename, - "\n".join("{}:{}".format(name, linenr) - for name, linenr in self._include_path))) - - try: - self._readline = self._open(filename, "r").readline - except EnvironmentError as e: - # We already know that the file exists - raise _KconfigIOError( - e, "{}:{}: Could not open '{}' (in '{}') ({}: {})" - .format(self.filename, self.linenr, filename, - self._line.strip(), - errno.errorcode[e.errno], e.strerror)) - - self.filename = rel_filename - self.linenr = 0 - - def _leave_file(self): - # Returns from a Kconfig file to the file that sourced it. See - # _enter_file(). - - # Restore location from parent Kconfig file - self.filename, self.linenr = self._include_path[-1] - # Restore include path and 'file' object - self._readline.__self__.close() # __self__ fetches the 'file' object - self._include_path, self._readline = self._filestack.pop() - - def _next_line(self): - # Fetches and tokenizes the next line from the current Kconfig file. - # Returns False at EOF and True otherwise. - - # We might already have tokens from parsing a line and discovering that - # it's part of a different construct - if self._reuse_tokens: - self._reuse_tokens = False - # self._tokens_i is known to be 1 here, because _parse_props() - # leaves it like that when it can't recognize a line (or parses a - # help text) - return True - - # readline() returns '' over and over at EOF, which we rely on for help - # texts at the end of files (see _line_after_help()) - line = self._readline() - if not line: - return False - self.linenr += 1 - - # Handle line joining - while line.endswith("\\\n"): - line = line[:-2] + self._readline() - self.linenr += 1 - - self._tokens = self._tokenize(line) - # Initialize to 1 instead of 0 to factor out code from _parse_block() - # and _parse_props(). They immediately fetch self._tokens[0]. - self._tokens_i = 1 - - return True - - def _line_after_help(self, line): - # Tokenizes a line after a help text. This case is special in that the - # line has already been fetched (to discover that it isn't part of the - # help text). - # - # An earlier version used a _saved_line variable instead that was - # checked in _next_line(). This special-casing gets rid of it and makes - # _reuse_tokens alone sufficient to handle unget. - - # Handle line joining - while line.endswith("\\\n"): - line = line[:-2] + self._readline() - self.linenr += 1 - - self._tokens = self._tokenize(line) - self._reuse_tokens = True - - def _write_if_changed(self, filename, contents): - # Writes 'contents' into 'filename', but only if it differs from the - # current contents of the file. - # - # Another variant would be write a temporary file on the same - # filesystem, compare the files, and rename() the temporary file if it - # differs, but it breaks stuff like write_config("/dev/null"), which is - # used out there to force evaluation-related warnings to be generated. - # This simple version is pretty failsafe and portable. - # - # Returns True if the file has changed and is updated, and False - # otherwise. - - if self._contents_eq(filename, contents): - return False - with self._open(filename, "w") as f: - f.write(contents) - return True - - def _contents_eq(self, filename, contents): - # Returns True if the contents of 'filename' is 'contents' (a string), - # and False otherwise (including if 'filename' can't be opened/read) - - try: - with self._open(filename, "r") as f: - # Robust re. things like encoding and line endings (mmap() - # trickery isn't) - return f.read(len(contents) + 1) == contents - except EnvironmentError: - # If the error here would prevent writing the file as well, we'll - # notice it later - return False - - # - # Tokenization - # - - def _lookup_sym(self, name): - # Fetches the symbol 'name' from the symbol table, creating and - # registering it if it does not exist. If '_parsing_kconfigs' is False, - # it means we're in eval_string(), and new symbols won't be registered. - - if name in self.syms: - return self.syms[name] - - sym = Symbol() - sym.kconfig = self - sym.name = name - sym.is_constant = False - sym.rev_dep = sym.weak_rev_dep = sym.direct_dep = self.n - - if self._parsing_kconfigs: - self.syms[name] = sym - else: - self._warn("no symbol {} in configuration".format(name)) - - return sym - - def _lookup_const_sym(self, name): - # Like _lookup_sym(), for constant (quoted) symbols - - if name in self.const_syms: - return self.const_syms[name] - - sym = Symbol() - sym.kconfig = self - sym.name = name - sym.is_constant = True - sym.rev_dep = sym.weak_rev_dep = sym.direct_dep = self.n - - if self._parsing_kconfigs: - self.const_syms[name] = sym - - return sym - - def _tokenize(self, s): - # Parses 's', returning a None-terminated list of tokens. Registers any - # new symbols encountered with _lookup(_const)_sym(). - # - # Tries to be reasonably speedy by processing chunks of text via - # regexes and string operations where possible. This is the biggest - # hotspot during parsing. - # - # It might be possible to rewrite this to 'yield' tokens instead, - # working across multiple lines. Lookback and compatibility with old - # janky versions of the C tools complicate things though. - - self._line = s # Used for error reporting - - # Initial token on the line - match = _command_match(s) - if not match: - if s.isspace() or s.lstrip().startswith("#"): - return (None,) - self._parse_error("unknown token at start of line") - - # Tricky implementation detail: While parsing a token, 'token' refers - # to the previous token. See _STRING_LEX for why this is needed. - token = _get_keyword(match.group(1)) - if not token: - # Backwards compatibility with old versions of the C tools, which - # (accidentally) accepted stuff like "--help--" and "-help---". - # This was fixed in the C tools by commit c2264564 ("kconfig: warn - # of unhandled characters in Kconfig commands"), committed in July - # 2015, but it seems people still run Kconfiglib on older kernels. - if s.strip(" \t\n-") == "help": - return (_T_HELP, None) - - # If the first token is not a keyword (and not a weird help token), - # we have a preprocessor variable assignment (or a bare macro on a - # line) - self._parse_assignment(s) - return (None,) - - tokens = [token] - # The current index in the string being tokenized - i = match.end() - - # Main tokenization loop (for tokens past the first one) - while i < len(s): - # Test for an identifier/keyword first. This is the most common - # case. - match = _id_keyword_match(s, i) - if match: - # We have an identifier or keyword - - # Check what it is. lookup_sym() will take care of allocating - # new symbols for us the first time we see them. Note that - # 'token' still refers to the previous token. - - name = match.group(1) - keyword = _get_keyword(name) - if keyword: - # It's a keyword - token = keyword - # Jump past it - i = match.end() - - elif token not in _STRING_LEX: - # It's a non-const symbol, except we translate n, m, and y - # into the corresponding constant symbols, like the C - # implementation - - if "$" in name: - # Macro expansion within symbol name - name, s, i = self._expand_name(s, i) - else: - i = match.end() - - token = self.const_syms[name] if name in STR_TO_TRI else \ - self._lookup_sym(name) - - else: - # It's a case of missing quotes. For example, the - # following is accepted: - # - # menu unquoted_title - # - # config A - # tristate unquoted_prompt - # - # endmenu - # - # Named choices ('choice FOO') also end up here. - - if token is not _T_CHOICE: - self._warn("style: quotes recommended around '{}' in '{}'" - .format(name, self._line.strip()), - self.filename, self.linenr) - - token = name - i = match.end() - - else: - # Neither a keyword nor a non-const symbol - - # We always strip whitespace after tokens, so it is safe to - # assume that s[i] is the start of a token here. - c = s[i] - - if c in "\"'": - if "$" not in s and "\\" not in s: - # Fast path for lines without $ and \. Find the - # matching quote. - end_i = s.find(c, i + 1) + 1 - if not end_i: - self._parse_error("unterminated string") - val = s[i + 1:end_i - 1] - i = end_i - else: - # Slow path - s, end_i = self._expand_str(s, i) - - # os.path.expandvars() and the $UNAME_RELEASE replace() - # is a backwards compatibility hack, which should be - # reasonably safe as expandvars() leaves references to - # undefined env. vars. as is. - # - # The preprocessor functionality changed how - # environment variables are referenced, to $(FOO). - val = expandvars(s[i + 1:end_i - 1] - .replace("$UNAME_RELEASE", - _UNAME_RELEASE)) - - i = end_i - - # This is the only place where we don't survive with a - # single token of lookback: 'option env="FOO"' does not - # refer to a constant symbol named "FOO". - token = \ - val if token in _STRING_LEX or tokens[0] is _T_OPTION \ - else self._lookup_const_sym(val) - - elif s.startswith("&&", i): - token = _T_AND - i += 2 - - elif s.startswith("||", i): - token = _T_OR - i += 2 - - elif c == "=": - token = _T_EQUAL - i += 1 - - elif s.startswith("!=", i): - token = _T_UNEQUAL - i += 2 - - elif c == "!": - token = _T_NOT - i += 1 - - elif c == "(": - token = _T_OPEN_PAREN - i += 1 - - elif c == ")": - token = _T_CLOSE_PAREN - i += 1 - - elif c == "#": - break - - - # Very rare - - elif s.startswith("<=", i): - token = _T_LESS_EQUAL - i += 2 - - elif c == "<": - token = _T_LESS - i += 1 - - elif s.startswith(">=", i): - token = _T_GREATER_EQUAL - i += 2 - - elif c == ">": - token = _T_GREATER - i += 1 - - - else: - self._parse_error("unknown tokens in line") - - - # Skip trailing whitespace - while i < len(s) and s[i].isspace(): - i += 1 - - - # Add the token - tokens.append(token) - - # None-terminating the token list makes token fetching simpler/faster - tokens.append(None) - - return tokens - - # Helpers for syntax checking and token fetching. See the - # 'Intro to expressions' section for what a constant symbol is. - # - # More of these could be added, but the single-use cases are inlined as an - # optimization. - - def _expect_sym(self): - token = self._tokens[self._tokens_i] - self._tokens_i += 1 - - if token.__class__ is not Symbol: - self._parse_error("expected symbol") - - return token - - def _expect_nonconst_sym(self): - # Used for 'select' and 'imply' only. We know the token indices. - - token = self._tokens[1] - self._tokens_i = 2 - - if token.__class__ is not Symbol or token.is_constant: - self._parse_error("expected nonconstant symbol") - - return token - - def _expect_str_and_eol(self): - token = self._tokens[self._tokens_i] - self._tokens_i += 1 - - if token.__class__ is not str: - self._parse_error("expected string") - - if self._tokens[self._tokens_i] is not None: - self._trailing_tokens_error() - - return token - - def _expect_expr_and_eol(self): - expr = self._parse_expr(True) - - if self._tokens[self._tokens_i] is not None: - self._trailing_tokens_error() - - return expr - - def _check_token(self, token): - # If the next token is 'token', removes it and returns True - - if self._tokens[self._tokens_i] is token: - self._tokens_i += 1 - return True - return False - - # - # Preprocessor logic - # - - def _parse_assignment(self, s): - # Parses a preprocessor variable assignment, registering the variable - # if it doesn't already exist. Also takes care of bare macros on lines - # (which are allowed, and can be useful for their side effects). - - # Expand any macros in the left-hand side of the assignment (the - # variable name) - s = s.lstrip() - i = 0 - while 1: - i = _assignment_lhs_fragment_match(s, i).end() - if s.startswith("$(", i): - s, i = self._expand_macro(s, i, ()) - else: - break - - if s.isspace(): - # We also accept a bare macro on a line (e.g. - # $(warning-if,$(foo),ops)), provided it expands to a blank string - return - - # Assigned variable - name = s[:i] - - - # Extract assignment operator (=, :=, or +=) and value - rhs_match = _assignment_rhs_match(s, i) - if not rhs_match: - self._parse_error("syntax error") - - op, val = rhs_match.groups() - - - if name in self.variables: - # Already seen variable - var = self.variables[name] - else: - # New variable - var = Variable() - var.kconfig = self - var.name = name - var._n_expansions = 0 - self.variables[name] = var - - # += acts like = on undefined variables (defines a recursive - # variable) - if op == "+=": - op = "=" - - if op == "=": - var.is_recursive = True - var.value = val - elif op == ":=": - var.is_recursive = False - var.value = self._expand_whole(val, ()) - else: # op == "+=" - # += does immediate expansion if the variable was last set - # with := - var.value += " " + (val if var.is_recursive else - self._expand_whole(val, ())) - - def _expand_whole(self, s, args): - # Expands preprocessor macros in all of 's'. Used whenever we don't - # have to worry about delimiters. See _expand_macro() re. the 'args' - # parameter. - # - # Returns the expanded string. - - i = 0 - while 1: - i = s.find("$(", i) - if i == -1: - break - s, i = self._expand_macro(s, i, args) - return s - - def _expand_name(self, s, i): - # Expands a symbol name starting at index 'i' in 's'. - # - # Returns the expanded name, the expanded 's' (including the part - # before the name), and the index of the first character in the next - # token after the name. - - s, end_i = self._expand_name_iter(s, i) - name = s[i:end_i] - # isspace() is False for empty strings - if not name.strip(): - # Avoid creating a Kconfig symbol with a blank name. It's almost - # guaranteed to be an error. - if not self.allow_empty_macros: - self._parse_error("macro expanded to blank string") - - # Skip trailing whitespace - while end_i < len(s) and s[end_i].isspace(): - end_i += 1 - - return name, s, end_i - - def _expand_name_iter(self, s, i): - # Expands a symbol name starting at index 'i' in 's'. - # - # Returns the expanded 's' (including the part before the name) and the - # index of the first character after the expanded name in 's'. - - while 1: - match = _name_special_search(s, i) - - if match.group() != "$(": - return (s, match.start()) - s, i = self._expand_macro(s, match.start(), ()) - - def _expand_str(self, s, i): - # Expands a quoted string starting at index 'i' in 's'. Handles both - # backslash escapes and macro expansion. - # - # Returns the expanded 's' (including the part before the string) and - # the index of the first character after the expanded string in 's'. - - quote = s[i] - i += 1 # Skip over initial "/' - while 1: - match = _string_special_search(s, i) - if not match: - self._parse_error("unterminated string") - - - if match.group() == quote: - # Found the end of the string - return (s, match.end()) - - elif match.group() == "\\": - # Replace '\x' with 'x'. 'i' ends up pointing to the character - # after 'x', which allows macros to be canceled with '\$(foo)'. - i = match.end() - s = s[:match.start()] + s[i:] - - elif match.group() == "$(": - # A macro call within the string - s, i = self._expand_macro(s, match.start(), ()) - - else: - # A ' quote within " quotes or vice versa - i += 1 - - def _expand_macro(self, s, i, args): - # Expands a macro starting at index 'i' in 's'. If this macro resulted - # from the expansion of another macro, 'args' holds the arguments - # passed to that macro. - # - # Returns the expanded 's' (including the part before the macro) and - # the index of the first character after the expanded macro in 's'. - - res = s[:i] - i += 2 # Skip over "$(" - - arg_start = i # Start of current macro argument - new_args = [] # Arguments of this macro call - nesting = 0 # Current parentheses nesting level - - while 1: - match = _macro_special_search(s, i) - if not match: - self._parse_error("missing end parenthesis in macro expansion") - - - if match.group() == "(": - nesting += 1 - i = match.end() - - elif match.group() == ")": - if nesting: - nesting -= 1 - i = match.end() - continue - - # Found the end of the macro - - new_args.append(s[arg_start:match.start()]) - - # $(1) is replaced by the first argument to the function, etc., - # provided at least that many arguments were passed - - try: - # Does the macro look like an integer, with a corresponding - # argument? If so, expand it to the value of the argument. - res += args[int(new_args[0])] - except (ValueError, IndexError): - # Regular variables are just functions without arguments, - # and also go through the function value path - res += self._fn_val(new_args) - - return (res + s[match.end():], len(res)) - - elif match.group() == ",": - i = match.end() - if nesting: - continue - - # Found the end of a macro argument - new_args.append(s[arg_start:match.start()]) - arg_start = i - - else: # match.group() == "$(" - # A nested macro call within the macro - s, i = self._expand_macro(s, match.start(), args) - - def _fn_val(self, args): - # Returns the result of calling the function args[0] with the arguments - # args[1..len(args)-1]. Plain variables are treated as functions - # without arguments. - - fn = args[0] - - if fn in self.variables: - var = self.variables[fn] - - if len(args) == 1: - # Plain variable - if var._n_expansions: - self._parse_error("Preprocessor variable {} recursively " - "references itself".format(var.name)) - elif var._n_expansions > 100: - # Allow functions to call themselves, but guess that functions - # that are overly recursive are stuck - self._parse_error("Preprocessor function {} seems stuck " - "in infinite recursion".format(var.name)) - - var._n_expansions += 1 - res = self._expand_whole(self.variables[fn].value, args) - var._n_expansions -= 1 - return res - - if fn in self._functions: - # Built-in or user-defined function - - py_fn, min_arg, max_arg = self._functions[fn] - - if len(args) - 1 < min_arg or \ - (max_arg is not None and len(args) - 1 > max_arg): - - if min_arg == max_arg: - expected_args = min_arg - elif max_arg is None: - expected_args = "{} or more".format(min_arg) - else: - expected_args = "{}-{}".format(min_arg, max_arg) - - raise KconfigError("{}:{}: bad number of arguments in call " - "to {}, expected {}, got {}" - .format(self.filename, self.linenr, fn, - expected_args, len(args) - 1)) - - return py_fn(self, *args) - - # Environment variables are tried last - if fn in os.environ: - self.env_vars.add(fn) - return os.environ[fn] - - return "" - - # - # Parsing - # - - def _make_and(self, e1, e2): - # Constructs an AND (&&) expression. Performs trivial simplification. - - if e1 is self.y: - return e2 - - if e2 is self.y: - return e1 - - if e1 is self.n or e2 is self.n: - return self.n - - return (AND, e1, e2) - - def _make_or(self, e1, e2): - # Constructs an OR (||) expression. Performs trivial simplification. - - if e1 is self.n: - return e2 - - if e2 is self.n: - return e1 - - if e1 is self.y or e2 is self.y: - return self.y - - return (OR, e1, e2) - - def _parse_block(self, end_token, parent, prev): - # Parses a block, which is the contents of either a file or an if, - # menu, or choice statement. - # - # end_token: - # The token that ends the block, e.g. _T_ENDIF ("endif") for ifs. - # None for files. - # - # parent: - # The parent menu node, corresponding to a menu, Choice, or 'if'. - # 'if's are flattened after parsing. - # - # prev: - # The previous menu node. New nodes will be added after this one (by - # modifying 'next' pointers). - # - # 'prev' is reused to parse a list of child menu nodes (for a menu or - # Choice): After parsing the children, the 'next' pointer is assigned - # to the 'list' pointer to "tilt up" the children above the node. - # - # Returns the final menu node in the block (or 'prev' if the block is - # empty). This allows chaining. - - while self._next_line(): - t0 = self._tokens[0] - - if t0 is _T_CONFIG or t0 is _T_MENUCONFIG: - # The tokenizer allocates Symbol objects for us - sym = self._tokens[1] - - if sym.__class__ is not Symbol or sym.is_constant: - self._parse_error("missing or bad symbol name") - - if self._tokens[2] is not None: - self._trailing_tokens_error() - - self.defined_syms.append(sym) - - node = MenuNode() - node.kconfig = self - node.item = sym - node.is_menuconfig = (t0 is _T_MENUCONFIG) - node.prompt = node.help = node.list = None - node.parent = parent - node.filename = self.filename - node.linenr = self.linenr - node.include_path = self._include_path - - sym.nodes.append(node) - - self._parse_props(node) - - if node.is_menuconfig and not node.prompt: - self._warn("the menuconfig symbol {} has no prompt" - .format(sym.name_and_loc)) - - # Equivalent to - # - # prev.next = node - # prev = node - # - # due to tricky Python semantics. The order matters. - prev.next = prev = node - - elif t0 is None: - # Blank line - continue - - elif t0 in _SOURCE_TOKENS: - pattern = self._expect_str_and_eol() - - if t0 in _REL_SOURCE_TOKENS: - # Relative source - pattern = join(dirname(self.filename), pattern) - - # - glob() doesn't support globbing relative to a directory, so - # we need to prepend $srctree to 'pattern'. Use join() - # instead of '+' so that an absolute path in 'pattern' is - # preserved. - # - # - Sort the glob results to ensure a consistent ordering of - # Kconfig symbols, which indirectly ensures a consistent - # ordering in e.g. .config files - filenames = sorted(iglob(join(self._srctree_prefix, pattern))) - if self.search_paths: - for prefix in self.search_paths: - filenames += sorted(iglob(join(prefix, pattern))) - - if not filenames and t0 in _OBL_SOURCE_TOKENS: - raise KconfigError( - "{}:{}: '{}' not found (in '{}'). Check that " - "environment variables are set correctly (e.g. " - "$srctree, which is {}). Also note that unset " - "environment variables expand to the empty string." - .format(self.filename, self.linenr, pattern, - self._line.strip(), - "set to '{}'".format(self.srctree) - if self.srctree else "unset or blank")) - - for filename in filenames: - self._enter_file(filename) - prev = self._parse_block(None, parent, prev) - self._leave_file() - - elif t0 is end_token: - # Reached the end of the block. Terminate the final node and - # return it. - - if self._tokens[1] is not None: - self._trailing_tokens_error() - - prev.next = None - return prev - - elif t0 is _T_IF: - node = MenuNode() - node.item = node.prompt = None - node.parent = parent - node.dep = self._expect_expr_and_eol() - - self._parse_block(_T_ENDIF, node, node) - node.list = node.next - - prev.next = prev = node - - elif t0 is _T_MENU: - node = MenuNode() - node.kconfig = self - node.item = t0 # _T_MENU == MENU - node.is_menuconfig = True - node.prompt = (self._expect_str_and_eol(), self.y) - node.visibility = self.y - node.parent = parent - node.filename = self.filename - node.linenr = self.linenr - node.include_path = self._include_path - - self.menus.append(node) - - self._parse_props(node) - self._parse_block(_T_ENDMENU, node, node) - node.list = node.next - - prev.next = prev = node - - elif t0 is _T_COMMENT: - node = MenuNode() - node.kconfig = self - node.item = t0 # _T_COMMENT == COMMENT - node.is_menuconfig = False - node.prompt = (self._expect_str_and_eol(), self.y) - node.list = None - node.parent = parent - node.filename = self.filename - node.linenr = self.linenr - node.include_path = self._include_path - - self.comments.append(node) - - self._parse_props(node) - - prev.next = prev = node - - elif t0 is _T_CHOICE: - if self._tokens[1] is None: - choice = Choice() - choice.direct_dep = self.n - else: - # Named choice - name = self._expect_str_and_eol() - choice = self.named_choices.get(name) - if not choice: - choice = Choice() - choice.name = name - choice.direct_dep = self.n - self.named_choices[name] = choice - - self.choices.append(choice) - - node = MenuNode() - node.kconfig = choice.kconfig = self - node.item = choice - node.is_menuconfig = True - node.prompt = node.help = None - node.parent = parent - node.filename = self.filename - node.linenr = self.linenr - node.include_path = self._include_path - - choice.nodes.append(node) - - self._parse_props(node) - self._parse_block(_T_ENDCHOICE, node, node) - node.list = node.next - - prev.next = prev = node - - elif t0 is _T_MAINMENU: - self.top_node.prompt = (self._expect_str_and_eol(), self.y) - - else: - # A valid endchoice/endif/endmenu is caught by the 'end_token' - # check above - self._parse_error( - "no corresponding 'choice'" if t0 is _T_ENDCHOICE else - "no corresponding 'if'" if t0 is _T_ENDIF else - "no corresponding 'menu'" if t0 is _T_ENDMENU else - "unrecognized construct") - - # End of file reached. Return the last node. - - if end_token: - raise KconfigError( - "error: expected '{}' at end of '{}'" - .format("endchoice" if end_token is _T_ENDCHOICE else - "endif" if end_token is _T_ENDIF else - "endmenu", - self.filename)) - - return prev - - def _parse_cond(self): - # Parses an optional 'if <expr>' construct and returns the parsed - # <expr>, or self.y if the next token is not _T_IF - - expr = self._parse_expr(True) if self._check_token(_T_IF) else self.y - - if self._tokens[self._tokens_i] is not None: - self._trailing_tokens_error() - - return expr - - def _parse_props(self, node): - # Parses and adds properties to the MenuNode 'node' (type, 'prompt', - # 'default's, etc.) Properties are later copied up to symbols and - # choices in a separate pass after parsing, in e.g. - # _add_props_to_sym(). - # - # An older version of this code added properties directly to symbols - # and choices instead of to their menu nodes (and handled dependency - # propagation simultaneously), but that loses information on where a - # property is added when a symbol or choice is defined in multiple - # locations. Some Kconfig configuration systems rely heavily on such - # symbols, and better docs can be generated by keeping track of where - # properties are added. - # - # node: - # The menu node we're parsing properties on - - # Dependencies from 'depends on'. Will get propagated to the properties - # below. - node.dep = self.y - - while self._next_line(): - t0 = self._tokens[0] - - if t0 in _TYPE_TOKENS: - # Relies on '_T_BOOL is BOOL', etc., to save a conversion - self._set_type(node.item, t0) - if self._tokens[1] is not None: - self._parse_prompt(node) - - elif t0 is _T_DEPENDS: - if not self._check_token(_T_ON): - self._parse_error("expected 'on' after 'depends'") - - node.dep = self._make_and(node.dep, - self._expect_expr_and_eol()) - - elif t0 is _T_HELP: - self._parse_help(node) - - elif t0 is _T_SELECT: - if node.item.__class__ is not Symbol: - self._parse_error("only symbols can select") - - node.selects.append((self._expect_nonconst_sym(), - self._parse_cond())) - - elif t0 is None: - # Blank line - continue - - elif t0 is _T_DEFAULT: - node.defaults.append((self._parse_expr(False), - self._parse_cond())) - - elif t0 in _DEF_TOKEN_TO_TYPE: - self._set_type(node.item, _DEF_TOKEN_TO_TYPE[t0]) - node.defaults.append((self._parse_expr(False), - self._parse_cond())) - - elif t0 is _T_PROMPT: - self._parse_prompt(node) - - elif t0 is _T_RANGE: - node.ranges.append((self._expect_sym(), self._expect_sym(), - self._parse_cond())) - - elif t0 is _T_IMPLY: - if node.item.__class__ is not Symbol: - self._parse_error("only symbols can imply") - - node.implies.append((self._expect_nonconst_sym(), - self._parse_cond())) - - elif t0 is _T_VISIBLE: - if not self._check_token(_T_IF): - self._parse_error("expected 'if' after 'visible'") - - node.visibility = self._make_and(node.visibility, - self._expect_expr_and_eol()) - - elif t0 is _T_OPTION: - if self._check_token(_T_ENV): - if not self._check_token(_T_EQUAL): - self._parse_error("expected '=' after 'env'") - - env_var = self._expect_str_and_eol() - node.item.env_var = env_var - - if env_var in os.environ: - node.defaults.append( - (self._lookup_const_sym(os.environ[env_var]), - self.y)) - else: - self._warn("{1} has 'option env=\"{0}\"', " - "but the environment variable {0} is not " - "set".format(node.item.name, env_var), - self.filename, self.linenr) - - if env_var != node.item.name: - self._warn("Kconfiglib expands environment variables " - "in strings directly, meaning you do not " - "need 'option env=...' \"bounce\" symbols. " - "For compatibility with the C tools, " - "rename {} to {} (so that the symbol name " - "matches the environment variable name)." - .format(node.item.name, env_var), - self.filename, self.linenr) - - elif self._check_token(_T_DEFCONFIG_LIST): - if not self.defconfig_list: - self.defconfig_list = node.item - else: - self._warn("'option defconfig_list' set on multiple " - "symbols ({0} and {1}). Only {0} will be " - "used.".format(self.defconfig_list.name, - node.item.name), - self.filename, self.linenr) - - elif self._check_token(_T_MODULES): - # To reduce warning spam, only warn if 'option modules' is - # set on some symbol that isn't MODULES, which should be - # safe. I haven't run into any projects that make use - # modules besides the kernel yet, and there it's likely to - # keep being called "MODULES". - if node.item is not self.modules: - self._warn("the 'modules' option is not supported. " - "Let me know if this is a problem for you, " - "as it wouldn't be that hard to implement. " - "Note that modules are supported -- " - "Kconfiglib just assumes the symbol name " - "MODULES, like older versions of the C " - "implementation did when 'option modules' " - "wasn't used.", - self.filename, self.linenr) - - elif self._check_token(_T_ALLNOCONFIG_Y): - if node.item.__class__ is not Symbol: - self._parse_error("the 'allnoconfig_y' option is only " - "valid for symbols") - - node.item.is_allnoconfig_y = True - - else: - self._parse_error("unrecognized option") - - elif t0 is _T_OPTIONAL: - if node.item.__class__ is not Choice: - self._parse_error('"optional" is only valid for choices') - - node.item.is_optional = True - - else: - # Reuse the tokens for the non-property line later - self._reuse_tokens = True - return - - def _set_type(self, sc, new_type): - # Sets the type of 'sc' (symbol or choice) to 'new_type' - - # UNKNOWN is falsy - if sc.orig_type and sc.orig_type is not new_type: - self._warn("{} defined with multiple types, {} will be used" - .format(sc.name_and_loc, TYPE_TO_STR[new_type])) - - sc.orig_type = new_type - - def _parse_prompt(self, node): - # 'prompt' properties override each other within a single definition of - # a symbol, but additional prompts can be added by defining the symbol - # multiple times - - if node.prompt: - self._warn(node.item.name_and_loc + - " defined with multiple prompts in single location") - - prompt = self._tokens[1] - self._tokens_i = 2 - - if prompt.__class__ is not str: - self._parse_error("expected prompt string") - - if prompt != prompt.strip(): - self._warn(node.item.name_and_loc + - " has leading or trailing whitespace in its prompt") - - # This avoid issues for e.g. reStructuredText documentation, where - # '*prompt *' is invalid - prompt = prompt.strip() - - node.prompt = (prompt, self._parse_cond()) - - def _parse_help(self, node): - if node.help is not None: - self._warn(node.item.name_and_loc + " defined with more than " - "one help text -- only the last one will be used") - - # Micro-optimization. This code is pretty hot. - readline = self._readline - - # Find first non-blank (not all-space) line and get its - # indentation - - while 1: - line = readline() - self.linenr += 1 - if not line: - self._empty_help(node, line) - return - if not line.isspace(): - break - - len_ = len # Micro-optimization - - # Use a separate 'expline' variable here and below to avoid stomping on - # any tabs people might've put deliberately into the first line after - # the help text - expline = line.expandtabs() - indent = len_(expline) - len_(expline.lstrip()) - if not indent: - self._empty_help(node, line) - return - - # The help text goes on till the first non-blank line with less indent - # than the first line - - # Add the first line - lines = [expline[indent:]] - add_line = lines.append # Micro-optimization - - while 1: - line = readline() - if line.isspace(): - # No need to preserve the exact whitespace in these - add_line("\n") - elif not line: - # End of file - break - else: - expline = line.expandtabs() - if len_(expline) - len_(expline.lstrip()) < indent: - break - add_line(expline[indent:]) - - self.linenr += len_(lines) - node.help = "".join(lines).rstrip() - if line: - self._line_after_help(line) - - def _empty_help(self, node, line): - self._warn(node.item.name_and_loc + - " has 'help' but empty help text") - node.help = "" - if line: - self._line_after_help(line) - - def _parse_expr(self, transform_m): - # Parses an expression from the tokens in Kconfig._tokens using a - # simple top-down approach. See the module docstring for the expression - # format. - # - # transform_m: - # True if m should be rewritten to m && MODULES. See the - # Kconfig.eval_string() documentation. - - # Grammar: - # - # expr: and_expr ['||' expr] - # and_expr: factor ['&&' and_expr] - # factor: <symbol> ['='/'!='/'<'/... <symbol>] - # '!' factor - # '(' expr ')' - # - # It helps to think of the 'expr: and_expr' case as a single-operand OR - # (no ||), and of the 'and_expr: factor' case as a single-operand AND - # (no &&). Parsing code is always a bit tricky. - - # Mind dump: parse_factor() and two nested loops for OR and AND would - # work as well. The straightforward implementation there gives a - # (op, (op, (op, A, B), C), D) parse for A op B op C op D. Representing - # expressions as (op, [list of operands]) instead goes nicely with that - # version, but is wasteful for short expressions and complicates - # expression evaluation and other code that works on expressions (more - # complicated code likely offsets any performance gain from less - # recursion too). If we also try to optimize the list representation by - # merging lists when possible (e.g. when ANDing two AND expressions), - # we end up allocating a ton of lists instead of reusing expressions, - # which is bad. - - and_expr = self._parse_and_expr(transform_m) - - # Return 'and_expr' directly if we have a "single-operand" OR. - # Otherwise, parse the expression on the right and make an OR node. - # This turns A || B || C || D into (OR, A, (OR, B, (OR, C, D))). - return and_expr if not self._check_token(_T_OR) else \ - (OR, and_expr, self._parse_expr(transform_m)) - - def _parse_and_expr(self, transform_m): - factor = self._parse_factor(transform_m) - - # Return 'factor' directly if we have a "single-operand" AND. - # Otherwise, parse the right operand and make an AND node. This turns - # A && B && C && D into (AND, A, (AND, B, (AND, C, D))). - return factor if not self._check_token(_T_AND) else \ - (AND, factor, self._parse_and_expr(transform_m)) - - def _parse_factor(self, transform_m): - token = self._tokens[self._tokens_i] - self._tokens_i += 1 - - if token.__class__ is Symbol: - # Plain symbol or relation - - if self._tokens[self._tokens_i] not in _RELATIONS: - # Plain symbol - - # For conditional expressions ('depends on <expr>', - # '... if <expr>', etc.), m is rewritten to m && MODULES. - if transform_m and token is self.m: - return (AND, self.m, self.modules) - - return token - - # Relation - # - # _T_EQUAL, _T_UNEQUAL, etc., deliberately have the same values as - # EQUAL, UNEQUAL, etc., so we can just use the token directly - self._tokens_i += 1 - return (self._tokens[self._tokens_i - 1], token, - self._expect_sym()) - - if token is _T_NOT: - # token == _T_NOT == NOT - return (token, self._parse_factor(transform_m)) - - if token is _T_OPEN_PAREN: - expr_parse = self._parse_expr(transform_m) - if self._check_token(_T_CLOSE_PAREN): - return expr_parse - - self._parse_error("malformed expression") - - # - # Caching and invalidation - # - - def _build_dep(self): - # Populates the Symbol/Choice._dependents sets, which contain all other - # items (symbols and choices) that immediately depend on the item in - # the sense that changing the value of the item might affect the value - # of the dependent items. This is used for caching/invalidation. - # - # The calculated sets might be larger than necessary as we don't do any - # complex analysis of the expressions. - - depend_on = _depend_on # Micro-optimization - - # Only calculate _dependents for defined symbols. Constant and - # undefined symbols could theoretically be selected/implied, but it - # wouldn't change their value, so it's not a true dependency. - for sym in self.unique_defined_syms: - # Symbols depend on the following: - - # The prompt conditions - for node in sym.nodes: - if node.prompt: - depend_on(sym, node.prompt[1]) - - # The default values and their conditions - for value, cond in sym.defaults: - depend_on(sym, value) - depend_on(sym, cond) - - # The reverse and weak reverse dependencies - depend_on(sym, sym.rev_dep) - depend_on(sym, sym.weak_rev_dep) - - # The ranges along with their conditions - for low, high, cond in sym.ranges: - depend_on(sym, low) - depend_on(sym, high) - depend_on(sym, cond) - - # The direct dependencies. This is usually redundant, as the direct - # dependencies get propagated to properties, but it's needed to get - # invalidation solid for 'imply', which only checks the direct - # dependencies (even if there are no properties to propagate it - # to). - depend_on(sym, sym.direct_dep) - - # In addition to the above, choice symbols depend on the choice - # they're in, but that's handled automatically since the Choice is - # propagated to the conditions of the properties before - # _build_dep() runs. - - for choice in self.unique_choices: - # Choices depend on the following: - - # The prompt conditions - for node in choice.nodes: - if node.prompt: - depend_on(choice, node.prompt[1]) - - # The default symbol conditions - for _, cond in choice.defaults: - depend_on(choice, cond) - - def _add_choice_deps(self): - # Choices also depend on the choice symbols themselves, because the - # y-mode selection of the choice might change if a choice symbol's - # visibility changes. - # - # We add these dependencies separately after dependency loop detection. - # The invalidation algorithm can handle the resulting - # <choice symbol> <-> <choice> dependency loops, but they make loop - # detection awkward. - - for choice in self.unique_choices: - for sym in choice.syms: - sym._dependents.add(choice) - - def _invalidate_all(self): - # Undefined symbols never change value and don't need to be - # invalidated, so we can just iterate over defined symbols. - # Invalidating constant symbols would break things horribly. - for sym in self.unique_defined_syms: - sym._invalidate() - - for choice in self.unique_choices: - choice._invalidate() - - # - # Post-parsing menu tree processing, including dependency propagation and - # implicit submenu creation - # - - def _finalize_node(self, node, visible_if): - # Finalizes a menu node and its children: - # - # - Copies properties from menu nodes up to their contained - # symbols/choices - # - # - Propagates dependencies from parent to child nodes - # - # - Creates implicit menus (see kconfig-language.txt) - # - # - Removes 'if' nodes - # - # - Sets 'choice' types and registers choice symbols - # - # menu_finalize() in the C implementation is similar. - # - # node: - # The menu node to finalize. This node and its children will have - # been finalized when the function returns, and any implicit menus - # will have been created. - # - # visible_if: - # Dependencies from 'visible if' on parent menus. These are added to - # the prompts of symbols and choices. - - if node.item.__class__ is Symbol: - # Copy defaults, ranges, selects, and implies to the Symbol - self._add_props_to_sym(node) - - # Find any items that should go in an implicit menu rooted at the - # symbol - cur = node - while cur.next and _auto_menu_dep(node, cur.next): - # This makes implicit submenu creation work recursively, with - # implicit menus inside implicit menus - self._finalize_node(cur.next, visible_if) - cur = cur.next - cur.parent = node - - if cur is not node: - # Found symbols that should go in an implicit submenu. Tilt - # them up above us. - node.list = node.next - node.next = cur.next - cur.next = None - - elif node.list: - # The menu node is a choice, menu, or if. Finalize each child node. - - if node.item is MENU: - visible_if = self._make_and(visible_if, node.visibility) - - # Propagate the menu node's dependencies to each child menu node. - # - # This needs to go before the recursive _finalize_node() call so - # that implicit submenu creation can look ahead at dependencies. - self._propagate_deps(node, visible_if) - - # Finalize the children - cur = node.list - while cur: - self._finalize_node(cur, visible_if) - cur = cur.next - - if node.list: - # node's children have been individually finalized. Do final steps - # to finalize this "level" in the menu tree. - _flatten(node.list) - _remove_ifs(node) - - # Empty choices (node.list None) are possible, so this needs to go - # outside - if node.item.__class__ is Choice: - # Add the node's non-node-specific properties to the choice, like - # _add_props_to_sym() does - choice = node.item - choice.direct_dep = self._make_or(choice.direct_dep, node.dep) - choice.defaults += node.defaults - - _finalize_choice(node) - - def _propagate_deps(self, node, visible_if): - # Propagates 'node's dependencies to its child menu nodes - - # If the parent node holds a Choice, we use the Choice itself as the - # parent dependency. This makes sense as the value (mode) of the choice - # limits the visibility of the contained choice symbols. The C - # implementation works the same way. - # - # Due to the similar interface, Choice works as a drop-in replacement - # for Symbol here. - basedep = node.item if node.item.__class__ is Choice else node.dep - - cur = node.list - while cur: - dep = cur.dep = self._make_and(cur.dep, basedep) - - if cur.item.__class__ in _SYMBOL_CHOICE: - # Propagate 'visible if' and dependencies to the prompt - if cur.prompt: - cur.prompt = (cur.prompt[0], - self._make_and( - cur.prompt[1], - self._make_and(visible_if, dep))) - - # Propagate dependencies to defaults - if cur.defaults: - cur.defaults = [(default, self._make_and(cond, dep)) - for default, cond in cur.defaults] - - # Propagate dependencies to ranges - if cur.ranges: - cur.ranges = [(low, high, self._make_and(cond, dep)) - for low, high, cond in cur.ranges] - - # Propagate dependencies to selects - if cur.selects: - cur.selects = [(target, self._make_and(cond, dep)) - for target, cond in cur.selects] - - # Propagate dependencies to implies - if cur.implies: - cur.implies = [(target, self._make_and(cond, dep)) - for target, cond in cur.implies] - - elif cur.prompt: # Not a symbol/choice - # Propagate dependencies to the prompt. 'visible if' is only - # propagated to symbols/choices. - cur.prompt = (cur.prompt[0], - self._make_and(cur.prompt[1], dep)) - - cur = cur.next - - def _add_props_to_sym(self, node): - # Copies properties from the menu node 'node' up to its contained - # symbol, and adds (weak) reverse dependencies to selected/implied - # symbols. - # - # This can't be rolled into _propagate_deps(), because that function - # traverses the menu tree roughly breadth-first, meaning properties on - # symbols defined in multiple locations could end up in the wrong - # order. - - sym = node.item - - # See the Symbol class docstring - sym.direct_dep = self._make_or(sym.direct_dep, node.dep) - - sym.defaults += node.defaults - sym.ranges += node.ranges - sym.selects += node.selects - sym.implies += node.implies - - # Modify the reverse dependencies of the selected symbol - for target, cond in node.selects: - target.rev_dep = self._make_or( - target.rev_dep, - self._make_and(sym, cond)) - - # Modify the weak reverse dependencies of the implied - # symbol - for target, cond in node.implies: - target.weak_rev_dep = self._make_or( - target.weak_rev_dep, - self._make_and(sym, cond)) - - # - # Misc. - # - - def _check_sym_sanity(self): - # Checks various symbol properties that are handiest to check after - # parsing. Only generates errors and warnings. - - def num_ok(sym, type_): - # Returns True if the (possibly constant) symbol 'sym' is valid as a value - # for a symbol of type type_ (INT or HEX) - - # 'not sym.nodes' implies a constant or undefined symbol, e.g. a plain - # "123" - if not sym.nodes: - return _is_base_n(sym.name, _TYPE_TO_BASE[type_]) - - return sym.orig_type is type_ - - for sym in self.unique_defined_syms: - if sym.orig_type in _BOOL_TRISTATE: - # A helper function could be factored out here, but keep it - # speedy/straightforward - - for target_sym, _ in sym.selects: - if target_sym.orig_type not in _BOOL_TRISTATE_UNKNOWN: - self._warn("{} selects the {} symbol {}, which is not " - "bool or tristate" - .format(sym.name_and_loc, - TYPE_TO_STR[target_sym.orig_type], - target_sym.name_and_loc)) - - for target_sym, _ in sym.implies: - if target_sym.orig_type not in _BOOL_TRISTATE_UNKNOWN: - self._warn("{} implies the {} symbol {}, which is not " - "bool or tristate" - .format(sym.name_and_loc, - TYPE_TO_STR[target_sym.orig_type], - target_sym.name_and_loc)) - - elif sym.orig_type: # STRING/INT/HEX - for default, _ in sym.defaults: - if default.__class__ is not Symbol: - raise KconfigError( - "the {} symbol {} has a malformed default {} -- " - "expected a single symbol" - .format(TYPE_TO_STR[sym.orig_type], - sym.name_and_loc, expr_str(default))) - - if sym.orig_type is STRING: - if not default.is_constant and not default.nodes and \ - not default.name.isupper(): - # 'default foo' on a string symbol could be either a symbol - # reference or someone leaving out the quotes. Guess that - # the quotes were left out if 'foo' isn't all-uppercase - # (and no symbol named 'foo' exists). - self._warn("style: quotes recommended around " - "default value for string symbol " - + sym.name_and_loc) - - elif not num_ok(default, sym.orig_type): # INT/HEX - self._warn("the {0} symbol {1} has a non-{0} default {2}" - .format(TYPE_TO_STR[sym.orig_type], - sym.name_and_loc, - default.name_and_loc)) - - if sym.selects or sym.implies: - self._warn("the {} symbol {} has selects or implies" - .format(TYPE_TO_STR[sym.orig_type], - sym.name_and_loc)) - - else: # UNKNOWN - self._warn("{} defined without a type" - .format(sym.name_and_loc)) - - - if sym.ranges: - if sym.orig_type not in _INT_HEX: - self._warn( - "the {} symbol {} has ranges, but is not int or hex" - .format(TYPE_TO_STR[sym.orig_type], - sym.name_and_loc)) - else: - for low, high, _ in sym.ranges: - if not num_ok(low, sym.orig_type) or \ - not num_ok(high, sym.orig_type): - - self._warn("the {0} symbol {1} has a non-{0} " - "range [{2}, {3}]" - .format(TYPE_TO_STR[sym.orig_type], - sym.name_and_loc, - low.name_and_loc, - high.name_and_loc)) - - def _check_choice_sanity(self): - # Checks various choice properties that are handiest to check after - # parsing. Only generates errors and warnings. - - def warn_select_imply(sym, expr, expr_type): - msg = "the choice symbol {} is {} by the following symbols, but " \ - "select/imply has no effect on choice symbols" \ - .format(sym.name_and_loc, expr_type) - - # si = select/imply - for si in split_expr(expr, OR): - msg += "\n - " + split_expr(si, AND)[0].name_and_loc - - self._warn(msg) - - for choice in self.unique_choices: - if choice.orig_type not in _BOOL_TRISTATE: - self._warn("{} defined with type {}" - .format(choice.name_and_loc, - TYPE_TO_STR[choice.orig_type])) - - for node in choice.nodes: - if node.prompt: - break - else: - self._warn(choice.name_and_loc + " defined without a prompt") - - for default, _ in choice.defaults: - if default.__class__ is not Symbol: - raise KconfigError( - "{} has a malformed default {}" - .format(choice.name_and_loc, expr_str(default))) - - if default.choice is not choice: - self._warn("the default selection {} of {} is not " - "contained in the choice" - .format(default.name_and_loc, - choice.name_and_loc)) - - for sym in choice.syms: - if sym.defaults: - self._warn("default on the choice symbol {} will have " - "no effect, as defaults do not affect choice " - "symbols".format(sym.name_and_loc)) - - if sym.rev_dep is not sym.kconfig.n: - warn_select_imply(sym, sym.rev_dep, "selected") - - if sym.weak_rev_dep is not sym.kconfig.n: - warn_select_imply(sym, sym.weak_rev_dep, "implied") - - for node in sym.nodes: - if node.parent.item is choice: - if not node.prompt: - self._warn("the choice symbol {} has no prompt" - .format(sym.name_and_loc)) - - elif node.prompt: - self._warn("the choice symbol {} is defined with a " - "prompt outside the choice" - .format(sym.name_and_loc)) - - def _parse_error(self, msg): - raise KconfigError("{}error: couldn't parse '{}': {}".format( - "" if self.filename is None else - "{}:{}: ".format(self.filename, self.linenr), - self._line.strip(), msg)) - - def _trailing_tokens_error(self): - self._parse_error("extra tokens at end of line") - - def _open(self, filename, mode): - # open() wrapper: - # - # - Enable universal newlines mode on Python 2 to ease - # interoperability between Linux and Windows. It's already the - # default on Python 3. - # - # The "U" flag would currently work for both Python 2 and 3, but it's - # deprecated on Python 3, so play it future-safe. - # - # io.open() defaults to universal newlines on Python 2 (and is an - # alias for open() on Python 3), but it returns 'unicode' strings and - # slows things down: - # - # Parsing x86 Kconfigs on Python 2 - # - # with open(..., "rU"): - # - # real 0m0.930s - # user 0m0.905s - # sys 0m0.025s - # - # with io.open(): - # - # real 0m1.069s - # user 0m1.040s - # sys 0m0.029s - # - # There's no appreciable performance difference between "r" and - # "rU" for parsing performance on Python 2. - # - # - For Python 3, force the encoding. Forcing the encoding on Python 2 - # turns strings into Unicode strings, which gets messy. Python 2 - # doesn't decode regular strings anyway. - return open(filename, "rU" if mode == "r" else mode) if _IS_PY2 else \ - open(filename, mode, encoding=self._encoding) - - def _check_undef_syms(self): - # Prints warnings for all references to undefined symbols within the - # Kconfig files - - def is_num(s): - # Returns True if the string 's' looks like a number. - # - # Internally, all operands in Kconfig are symbols, only undefined symbols - # (which numbers usually are) get their name as their value. - # - # Only hex numbers that start with 0x/0X are classified as numbers. - # Otherwise, symbols whose names happen to contain only the letters A-F - # would trigger false positives. - - try: - int(s) - except ValueError: - if not s.startswith(("0x", "0X")): - return False - - try: - int(s, 16) - except ValueError: - return False - - return True - - for sym in (self.syms.viewvalues if _IS_PY2 else self.syms.values)(): - # - sym.nodes empty means the symbol is undefined (has no - # definition locations) - # - # - Due to Kconfig internals, numbers show up as undefined Kconfig - # symbols, but shouldn't be flagged - # - # - The MODULES symbol always exists - if not sym.nodes and not is_num(sym.name) and \ - sym.name != "MODULES": - - msg = "undefined symbol {}:".format(sym.name) - for node in self.node_iter(): - if sym in node.referenced: - msg += "\n\n- Referenced at {}:{}:\n\n{}" \ - .format(node.filename, node.linenr, node) - self._warn(msg) - - def _warn(self, msg, filename=None, linenr=None): - # For printing general warnings - - if not self.warn: - return - - msg = "warning: " + msg - if filename is not None: - msg = "{}:{}: {}".format(filename, linenr, msg) - - self.warnings.append(msg) - if self.warn_to_stderr: - sys.stderr.write(msg + "\n") - - -class Symbol(object): - """ - Represents a configuration symbol: - - (menu)config FOO - ... - - The following attributes are available. They should be viewed as read-only, - and some are implemented through @property magic (but are still efficient - to access due to internal caching). - - Note: Prompts, help texts, and locations are stored in the Symbol's - MenuNode(s) rather than in the Symbol itself. Check the MenuNode class and - the Symbol.nodes attribute. This organization matches the C tools. - - name: - The name of the symbol, e.g. "FOO" for 'config FOO'. - - type: - The type of the symbol. One of BOOL, TRISTATE, STRING, INT, HEX, UNKNOWN. - UNKNOWN is for undefined symbols, (non-special) constant symbols, and - symbols defined without a type. - - When running without modules (MODULES having the value n), TRISTATE - symbols magically change type to BOOL. This also happens for symbols - within choices in "y" mode. This matches the C tools, and makes sense for - menuconfig-like functionality. - - orig_type: - The type as given in the Kconfig file, without any magic applied. Used - when printing the symbol. - - tri_value: - The tristate value of the symbol as an integer. One of 0, 1, 2, - representing n, m, y. Always 0 (n) for non-bool/tristate symbols. - - This is the symbol value that's used outside of relation expressions - (A, !A, A && B, A || B). - - str_value: - The value of the symbol as a string. Gives the value for string/int/hex - symbols. For bool/tristate symbols, gives "n", "m", or "y". - - This is the symbol value that's used in relational expressions - (A = B, A != B, etc.) - - Gotcha: For int/hex symbols, the exact format of the value is often - preserved (e.g. when writing a .config file), hence why you can't get it - directly as an int. Do int(int_sym.str_value) or - int(hex_sym.str_value, 16) to get the integer value. - - user_value: - The user value of the symbol. None if no user value has been assigned - (via Kconfig.load_config() or Symbol.set_value()). - - Holds 0, 1, or 2 for bool/tristate symbols, and a string for the other - symbol types. - - WARNING: Do not assign directly to this. It will break things. Use - Symbol.set_value(). - - assignable: - A tuple containing the tristate user values that can currently be - assigned to the symbol (that would be respected), ordered from lowest (0, - representing n) to highest (2, representing y). This corresponds to the - selections available in the menuconfig interface. The set of assignable - values is calculated from the symbol's visibility and selects/implies. - - Returns the empty set for non-bool/tristate symbols and for symbols with - visibility n. The other possible values are (0, 2), (0, 1, 2), (1, 2), - (1,), and (2,). A (1,) or (2,) result means the symbol is visible but - "locked" to m or y through a select, perhaps in combination with the - visibility. menuconfig represents this as -M- and -*-, respectively. - - For string/hex/int symbols, check if Symbol.visibility is non-0 (non-n) - instead to determine if the value can be changed. - - Some handy 'assignable' idioms: - - # Is 'sym' an assignable (visible) bool/tristate symbol? - if sym.assignable: - # What's the highest value it can be assigned? [-1] in Python - # gives the last element. - sym_high = sym.assignable[-1] - - # The lowest? - sym_low = sym.assignable[0] - - # Can the symbol be set to at least m? - if sym.assignable[-1] >= 1: - ... - - # Can the symbol be set to m? - if 1 in sym.assignable: - ... - - visibility: - The visibility of the symbol. One of 0, 1, 2, representing n, m, y. See - the module documentation for an overview of symbol values and visibility. - - config_string: - The .config assignment string that would get written out for the symbol - by Kconfig.write_config(). Returns the empty string if no .config - assignment would get written out. - - In general, visible symbols, symbols with (active) defaults, and selected - symbols get written out. This includes all non-n-valued bool/tristate - symbols, and all visible string/int/hex symbols. - - Symbols with the (no longer needed) 'option env=...' option generate no - configuration output, and neither does the special - 'option defconfig_list' symbol. - - Tip: This field is useful when generating custom configuration output, - even for non-.config-like formats. To write just the symbols that would - get written out to .config files, do this: - - if sym.config_string: - *Write symbol, e.g. by looking sym.str_value* - - This is a superset of the symbols written out by write_autoconf(). - That function skips all n-valued symbols. - - There usually won't be any great harm in just writing all symbols either, - though you might get some special symbols and possibly some "redundant" - n-valued symbol entries in there. - - name_and_loc: - Holds a string like - - "MY_SYMBOL (defined at foo/Kconfig:12, bar/Kconfig:14)" - - , giving the name of the symbol and its definition location(s). - - If the symbol is undefined, the location is given as "(undefined)". - - nodes: - A list of MenuNodes for this symbol. Will contain a single MenuNode for - most symbols. Undefined and constant symbols have an empty nodes list. - Symbols defined in multiple locations get one node for each location. - - choice: - Holds the parent Choice for choice symbols, and None for non-choice - symbols. Doubles as a flag for whether a symbol is a choice symbol. - - defaults: - List of (default, cond) tuples for the symbol's 'default' properties. For - example, 'default A && B if C || D' is represented as - ((AND, A, B), (OR, C, D)). If no condition was given, 'cond' is - self.kconfig.y. - - Note that 'depends on' and parent dependencies are propagated to - 'default' conditions. - - selects: - List of (symbol, cond) tuples for the symbol's 'select' properties. For - example, 'select A if B && C' is represented as (A, (AND, B, C)). If no - condition was given, 'cond' is self.kconfig.y. - - Note that 'depends on' and parent dependencies are propagated to 'select' - conditions. - - implies: - Like 'selects', for imply. - - ranges: - List of (low, high, cond) tuples for the symbol's 'range' properties. For - example, 'range 1 2 if A' is represented as (1, 2, A). If there is no - condition, 'cond' is self.kconfig.y. - - Note that 'depends on' and parent dependencies are propagated to 'range' - conditions. - - Gotcha: 1 and 2 above will be represented as (undefined) Symbols rather - than plain integers. Undefined symbols get their name as their string - value, so this works out. The C tools work the same way. - - orig_defaults: - orig_selects: - orig_implies: - orig_ranges: - See the corresponding attributes on the MenuNode class. - - rev_dep: - Reverse dependency expression from other symbols selecting this symbol. - Multiple selections get ORed together. A condition on a select is ANDed - with the selecting symbol. - - For example, if A has 'select FOO' and B has 'select FOO if C', then - FOO's rev_dep will be (OR, A, (AND, B, C)). - - weak_rev_dep: - Like rev_dep, for imply. - - direct_dep: - The direct ('depends on') dependencies for the symbol, or self.kconfig.y - if there are no direct dependencies. - - This attribute includes any dependencies from surrounding menus and ifs. - Those get propagated to the direct dependencies, and the resulting direct - dependencies in turn get propagated to the conditions of all properties. - - If the symbol is defined in multiple locations, the dependencies from the - different locations get ORed together. - - referenced: - A set() with all symbols and choices referenced in the properties and - property conditions of the symbol. - - Also includes dependencies from surrounding menus and ifs, because those - get propagated to the symbol (see the 'Intro to symbol values' section in - the module docstring). - - Choices appear in the dependencies of choice symbols. - - For the following definitions, only B and not C appears in A's - 'referenced'. To get transitive references, you'll have to recursively - expand 'references' until no new items appear. - - config A - bool - depends on B - - config B - bool - depends on C - - config C - bool - - See the Symbol.direct_dep attribute if you're only interested in the - direct dependencies of the symbol (its 'depends on'). You can extract the - symbols in it with the global expr_items() function. - - env_var: - If the Symbol has an 'option env="FOO"' option, this contains the name - ("FOO") of the environment variable. None for symbols without no - 'option env'. - - 'option env="FOO"' acts like a 'default' property whose value is the - value of $FOO. - - Symbols with 'option env' are never written out to .config files, even if - they are visible. env_var corresponds to a flag called SYMBOL_AUTO in the - C implementation. - - is_allnoconfig_y: - True if the symbol has 'option allnoconfig_y' set on it. This has no - effect internally (except when printing symbols), but can be checked by - scripts. - - is_constant: - True if the symbol is a constant (quoted) symbol. - - kconfig: - The Kconfig instance this symbol is from. - """ - __slots__ = ( - "_cached_assignable", - "_cached_str_val", - "_cached_tri_val", - "_cached_vis", - "_dependents", - "_old_val", - "_visited", - "_was_set", - "_write_to_conf", - "choice", - "defaults", - "direct_dep", - "env_var", - "implies", - "is_allnoconfig_y", - "is_constant", - "kconfig", - "name", - "nodes", - "orig_type", - "ranges", - "rev_dep", - "selects", - "user_value", - "weak_rev_dep", - ) - - # - # Public interface - # - - @property - def type(self): - """ - See the class documentation. - """ - if self.orig_type is TRISTATE and \ - (self.choice and self.choice.tri_value == 2 or - not self.kconfig.modules.tri_value): - - return BOOL - - return self.orig_type - - @property - def str_value(self): - """ - See the class documentation. - """ - if self._cached_str_val is not None: - return self._cached_str_val - - if self.orig_type in _BOOL_TRISTATE: - # Also calculates the visibility, so invalidation safe - self._cached_str_val = TRI_TO_STR[self.tri_value] - return self._cached_str_val - - # As a quirk of Kconfig, undefined symbols get their name as their - # string value. This is why things like "FOO = bar" work for seeing if - # FOO has the value "bar". - if not self.orig_type: # UNKNOWN - self._cached_str_val = self.name - return self.name - - val = "" - # Warning: See Symbol._rec_invalidate(), and note that this is a hidden - # function call (property magic) - vis = self.visibility - - self._write_to_conf = (vis != 0) - - if self.orig_type in _INT_HEX: - # The C implementation checks the user value against the range in a - # separate code path (post-processing after loading a .config). - # Checking all values here instead makes more sense for us. It - # requires that we check for a range first. - - base = _TYPE_TO_BASE[self.orig_type] - - # Check if a range is in effect - for low_expr, high_expr, cond in self.ranges: - if expr_value(cond): - has_active_range = True - - # The zeros are from the C implementation running strtoll() - # on empty strings - low = int(low_expr.str_value, base) if \ - _is_base_n(low_expr.str_value, base) else 0 - high = int(high_expr.str_value, base) if \ - _is_base_n(high_expr.str_value, base) else 0 - - break - else: - has_active_range = False - - # Defaults are used if the symbol is invisible, lacks a user value, - # or has an out-of-range user value - use_defaults = True - - if vis and self.user_value: - user_val = int(self.user_value, base) - if has_active_range and not low <= user_val <= high: - num2str = str if base == 10 else hex - self.kconfig._warn( - "user value {} on the {} symbol {} ignored due to " - "being outside the active range ([{}, {}]) -- falling " - "back on defaults" - .format(num2str(user_val), TYPE_TO_STR[self.orig_type], - self.name_and_loc, - num2str(low), num2str(high))) - else: - # If the user value is well-formed and satisfies range - # contraints, it is stored in exactly the same form as - # specified in the assignment (with or without "0x", etc.) - val = self.user_value - use_defaults = False - - if use_defaults: - # No user value or invalid user value. Look at defaults. - - # Used to implement the warning below - has_default = False - - for sym, cond in self.defaults: - if expr_value(cond): - has_default = self._write_to_conf = True - - val = sym.str_value - - if _is_base_n(val, base): - val_num = int(val, base) - else: - val_num = 0 # strtoll() on empty string - - break - else: - val_num = 0 # strtoll() on empty string - - # This clamping procedure runs even if there's no default - if has_active_range: - clamp = None - if val_num < low: - clamp = low - elif val_num > high: - clamp = high - - if clamp is not None: - # The value is rewritten to a standard form if it is - # clamped - val = str(clamp) \ - if self.orig_type is INT else \ - hex(clamp) - - if has_default: - num2str = str if base == 10 else hex - self.kconfig._warn( - "default value {} on {} clamped to {} due to " - "being outside the active range ([{}, {}])" - .format(val_num, self.name_and_loc, - num2str(clamp), num2str(low), - num2str(high))) - - elif self.orig_type is STRING: - if vis and self.user_value is not None: - # If the symbol is visible and has a user value, use that - val = self.user_value - else: - # Otherwise, look at defaults - for sym, cond in self.defaults: - if expr_value(cond): - val = sym.str_value - self._write_to_conf = True - break - - # env_var corresponds to SYMBOL_AUTO in the C implementation, and is - # also set on the defconfig_list symbol there. Test for the - # defconfig_list symbol explicitly instead here, to avoid a nonsensical - # env_var setting and the defconfig_list symbol being printed - # incorrectly. This code is pretty cold anyway. - if self.env_var is not None or self is self.kconfig.defconfig_list: - self._write_to_conf = False - - self._cached_str_val = val - return val - - @property - def tri_value(self): - """ - See the class documentation. - """ - if self._cached_tri_val is not None: - return self._cached_tri_val - - if self.orig_type not in _BOOL_TRISTATE: - if self.orig_type: # != UNKNOWN - # Would take some work to give the location here - self.kconfig._warn( - "The {} symbol {} is being evaluated in a logical context " - "somewhere. It will always evaluate to n." - .format(TYPE_TO_STR[self.orig_type], self.name_and_loc)) - - self._cached_tri_val = 0 - return 0 - - # Warning: See Symbol._rec_invalidate(), and note that this is a hidden - # function call (property magic) - vis = self.visibility - self._write_to_conf = (vis != 0) - - val = 0 - - if not self.choice: - # Non-choice symbol - - if vis and self.user_value is not None: - # If the symbol is visible and has a user value, use that - val = min(self.user_value, vis) - - else: - # Otherwise, look at defaults and weak reverse dependencies - # (implies) - - for default, cond in self.defaults: - dep_val = expr_value(cond) - if dep_val: - val = min(expr_value(default), dep_val) - if val: - self._write_to_conf = True - break - - # Weak reverse dependencies are only considered if our - # direct dependencies are met - dep_val = expr_value(self.weak_rev_dep) - if dep_val and expr_value(self.direct_dep): - val = max(dep_val, val) - self._write_to_conf = True - - # Reverse (select-related) dependencies take precedence - dep_val = expr_value(self.rev_dep) - if dep_val: - if expr_value(self.direct_dep) < dep_val: - self._warn_select_unsatisfied_deps() - - val = max(dep_val, val) - self._write_to_conf = True - - # m is promoted to y for (1) bool symbols and (2) symbols with a - # weak_rev_dep (from imply) of y - if val == 1 and \ - (self.type is BOOL or expr_value(self.weak_rev_dep) == 2): - val = 2 - - elif vis == 2: - # Visible choice symbol in y-mode choice. The choice mode limits - # the visibility of choice symbols, so it's sufficient to just - # check the visibility of the choice symbols themselves. - val = 2 if self.choice.selection is self else 0 - - elif vis and self.user_value: - # Visible choice symbol in m-mode choice, with set non-0 user value - val = 1 - - self._cached_tri_val = val - return val - - @property - def assignable(self): - """ - See the class documentation. - """ - if self._cached_assignable is None: - self._cached_assignable = self._assignable() - return self._cached_assignable - - @property - def visibility(self): - """ - See the class documentation. - """ - if self._cached_vis is None: - self._cached_vis = _visibility(self) - return self._cached_vis - - @property - def config_string(self): - """ - See the class documentation. - """ - # _write_to_conf is determined when the value is calculated. This is a - # hidden function call due to property magic. - val = self.str_value - if not self._write_to_conf: - return "" - - if self.orig_type in _BOOL_TRISTATE: - return "{}{}={}\n" \ - .format(self.kconfig.config_prefix, self.name, val) \ - if val != "n" else \ - "# {}{} is not set\n" \ - .format(self.kconfig.config_prefix, self.name) - - if self.orig_type in _INT_HEX: - return "{}{}={}\n" \ - .format(self.kconfig.config_prefix, self.name, val) - - # sym.orig_type is STRING - return '{}{}="{}"\n' \ - .format(self.kconfig.config_prefix, self.name, escape(val)) - - @property - def name_and_loc(self): - """ - See the class documentation. - """ - return self.name + " " + _locs(self) - - def set_value(self, value): - """ - Sets the user value of the symbol. - - Equal in effect to assigning the value to the symbol within a .config - file. For bool and tristate symbols, use the 'assignable' attribute to - check which values can currently be assigned. Setting values outside - 'assignable' will cause Symbol.user_value to differ from - Symbol.str/tri_value (be truncated down or up). - - Setting a choice symbol to 2 (y) sets Choice.user_selection to the - choice symbol in addition to setting Symbol.user_value. - Choice.user_selection is considered when the choice is in y mode (the - "normal" mode). - - Other symbols that depend (possibly indirectly) on this symbol are - automatically recalculated to reflect the assigned value. - - value: - The user value to give to the symbol. For bool and tristate symbols, - n/m/y can be specified either as 0/1/2 (the usual format for tristate - values in Kconfiglib) or as one of the strings "n", "m", or "y". For - other symbol types, pass a string. - - Note that the value for an int/hex symbol is passed as a string, e.g. - "123" or "0x0123". The format of this string is preserved in the - output. - - Values that are invalid for the type (such as "foo" or 1 (m) for a - BOOL or "0x123" for an INT) are ignored and won't be stored in - Symbol.user_value. Kconfiglib will print a warning by default for - invalid assignments, and set_value() will return False. - - Returns True if the value is valid for the type of the symbol, and - False otherwise. This only looks at the form of the value. For BOOL and - TRISTATE symbols, check the Symbol.assignable attribute to see what - values are currently in range and would actually be reflected in the - value of the symbol. For other symbol types, check whether the - visibility is non-n. - """ - if self.orig_type in _BOOL_TRISTATE and value in STR_TO_TRI: - value = STR_TO_TRI[value] - - # If the new user value matches the old, nothing changes, and we can - # avoid invalidating cached values. - # - # This optimization is skipped for choice symbols: Setting a choice - # symbol's user value to y might change the state of the choice, so it - # wouldn't be safe (symbol user values always match the values set in a - # .config file or via set_value(), and are never implicitly updated). - if value == self.user_value and not self.choice: - self._was_set = True - return True - - # Check if the value is valid for our type - if not (self.orig_type is BOOL and value in (2, 0) or - self.orig_type is TRISTATE and value in TRI_TO_STR or - value.__class__ is str and - (self.orig_type is STRING or - self.orig_type is INT and _is_base_n(value, 10) or - self.orig_type is HEX and _is_base_n(value, 16) - and int(value, 16) >= 0)): - - # Display tristate values as n, m, y in the warning - self.kconfig._warn( - "the value {} is invalid for {}, which has type {} -- " - "assignment ignored" - .format(TRI_TO_STR[value] if value in TRI_TO_STR else - "'{}'".format(value), - self.name_and_loc, TYPE_TO_STR[self.orig_type])) - - return False - - self.user_value = value - self._was_set = True - - if self.choice and value == 2: - # Setting a choice symbol to y makes it the user selection of the - # choice. Like for symbol user values, the user selection is not - # guaranteed to match the actual selection of the choice, as - # dependencies come into play. - self.choice.user_selection = self - self.choice._was_set = True - self.choice._rec_invalidate() - else: - self._rec_invalidate_if_has_prompt() - - return True - - def unset_value(self): - """ - Removes any user value from the symbol, as if the symbol had never - gotten a user value via Kconfig.load_config() or Symbol.set_value(). - """ - if self.user_value is not None: - self.user_value = None - self._rec_invalidate_if_has_prompt() - - @property - def referenced(self): - """ - See the class documentation. - """ - return {item for node in self.nodes for item in node.referenced} - - @property - def orig_defaults(self): - """ - See the class documentation. - """ - return [d for node in self.nodes for d in node.orig_defaults] - - @property - def orig_selects(self): - """ - See the class documentation. - """ - return [s for node in self.nodes for s in node.orig_selects] - - @property - def orig_implies(self): - """ - See the class documentation. - """ - return [i for node in self.nodes for i in node.orig_implies] - - @property - def orig_ranges(self): - """ - See the class documentation. - """ - return [r for node in self.nodes for r in node.orig_ranges] - - def __repr__(self): - """ - Returns a string with information about the symbol (including its name, - value, visibility, and location(s)) when it is evaluated on e.g. the - interactive Python prompt. - """ - fields = ["symbol " + self.name, TYPE_TO_STR[self.type]] - add = fields.append - - for node in self.nodes: - if node.prompt: - add('"{}"'.format(node.prompt[0])) - - # Only add quotes for non-bool/tristate symbols - add("value " + (self.str_value if self.orig_type in _BOOL_TRISTATE - else '"{}"'.format(self.str_value))) - - if not self.is_constant: - # These aren't helpful to show for constant symbols - - if self.user_value is not None: - # Only add quotes for non-bool/tristate symbols - add("user value " + (TRI_TO_STR[self.user_value] - if self.orig_type in _BOOL_TRISTATE - else '"{}"'.format(self.user_value))) - - add("visibility " + TRI_TO_STR[self.visibility]) - - if self.choice: - add("choice symbol") - - if self.is_allnoconfig_y: - add("allnoconfig_y") - - if self is self.kconfig.defconfig_list: - add("is the defconfig_list symbol") - - if self.env_var is not None: - add("from environment variable " + self.env_var) - - if self is self.kconfig.modules: - add("is the modules symbol") - - add("direct deps " + TRI_TO_STR[expr_value(self.direct_dep)]) - - if self.nodes: - for node in self.nodes: - add("{}:{}".format(node.filename, node.linenr)) - else: - add("constant" if self.is_constant else "undefined") - - return "<{}>".format(", ".join(fields)) - - def __str__(self): - """ - Returns a string representation of the symbol when it is printed. - Matches the Kconfig format, with any parent dependencies propagated to - the 'depends on' condition. - - The string is constructed by joining the strings returned by - MenuNode.__str__() for each of the symbol's menu nodes, so symbols - defined in multiple locations will return a string with all - definitions. - - The returned string does not end in a newline. An empty string is - returned for undefined and constant symbols. - """ - return self.custom_str(standard_sc_expr_str) - - def custom_str(self, sc_expr_str_fn): - """ - Works like Symbol.__str__(), but allows a custom format to be used for - all symbol/choice references. See expr_str(). - """ - return "\n\n".join(node.custom_str(sc_expr_str_fn) - for node in self.nodes) - - # - # Private methods - # - - def __init__(self): - """ - Symbol constructor -- not intended to be called directly by Kconfiglib - clients. - """ - # These attributes are always set on the instance from outside and - # don't need defaults: - # kconfig - # direct_dep - # is_constant - # name - # rev_dep - # weak_rev_dep - - # - UNKNOWN == 0 - # - _visited is used during tree iteration and dep. loop detection - self.orig_type = self._visited = 0 - - self.nodes = [] - - self.defaults = [] - self.selects = [] - self.implies = [] - self.ranges = [] - - self.user_value = \ - self.choice = \ - self.env_var = \ - self._cached_str_val = self._cached_tri_val = self._cached_vis = \ - self._cached_assignable = None - - # _write_to_conf is calculated along with the value. If True, the - # Symbol gets a .config entry. - - self.is_allnoconfig_y = \ - self._was_set = \ - self._write_to_conf = False - - # See Kconfig._build_dep() - self._dependents = set() - - def _assignable(self): - # Worker function for the 'assignable' attribute - - if self.orig_type not in _BOOL_TRISTATE: - return () - - # Warning: See Symbol._rec_invalidate(), and note that this is a hidden - # function call (property magic) - vis = self.visibility - if not vis: - return () - - rev_dep_val = expr_value(self.rev_dep) - - if vis == 2: - if self.choice: - return (2,) - - if not rev_dep_val: - if self.type is BOOL or expr_value(self.weak_rev_dep) == 2: - return (0, 2) - return (0, 1, 2) - - if rev_dep_val == 2: - return (2,) - - # rev_dep_val == 1 - - if self.type is BOOL or expr_value(self.weak_rev_dep) == 2: - return (2,) - return (1, 2) - - # vis == 1 - - # Must be a tristate here, because bool m visibility gets promoted to y - - if not rev_dep_val: - return (0, 1) if expr_value(self.weak_rev_dep) != 2 else (0, 2) - - if rev_dep_val == 2: - return (2,) - - # vis == rev_dep_val == 1 - - return (1,) - - def _invalidate(self): - # Marks the symbol as needing to be recalculated - - self._cached_str_val = self._cached_tri_val = self._cached_vis = \ - self._cached_assignable = None - - def _rec_invalidate(self): - # Invalidates the symbol and all items that (possibly) depend on it - - if self is self.kconfig.modules: - # Invalidating MODULES has wide-ranging effects - self.kconfig._invalidate_all() - else: - self._invalidate() - - for item in self._dependents: - # _cached_vis doubles as a flag that tells us whether 'item' - # has cached values, because it's calculated as a side effect - # of calculating all other (non-constant) cached values. - # - # If item._cached_vis is None, it means there can't be cached - # values on other items that depend on 'item', because if there - # were, some value on 'item' would have been calculated and - # item._cached_vis set as a side effect. It's therefore safe to - # stop the invalidation at symbols with _cached_vis None. - # - # This approach massively speeds up scripts that set a lot of - # values, vs simply invalidating all possibly dependent symbols - # (even when you already have a list of all the dependent - # symbols, because some symbols get huge dependency trees). - # - # This gracefully handles dependency loops too, which is nice - # for choices, where the choice depends on the choice symbols - # and vice versa. - if item._cached_vis is not None: - item._rec_invalidate() - - def _rec_invalidate_if_has_prompt(self): - # Invalidates the symbol and its dependent symbols, but only if the - # symbol has a prompt. User values never have an effect on promptless - # symbols, so we skip invalidation for them as an optimization. - # - # This also prevents constant (quoted) symbols from being invalidated - # if set_value() is called on them, which would make them lose their - # value and break things. - # - # Prints a warning if the symbol has no prompt. In some contexts (e.g. - # when loading a .config files) assignments to promptless symbols are - # normal and expected, so the warning can be disabled. - - for node in self.nodes: - if node.prompt: - self._rec_invalidate() - return - - if self.kconfig._warn_assign_no_prompt: - self.kconfig._warn(self.name_and_loc + " has no prompt, meaning " - "user values have no effect on it") - - def _str_default(self): - # write_min_config() helper function. Returns the value the symbol - # would get from defaults if it didn't have a user value. Uses exactly - # the same algorithm as the C implementation (though a bit cleaned up), - # for compatibility. - - if self.orig_type in _BOOL_TRISTATE: - val = 0 - - # Defaults, selects, and implies do not affect choice symbols - if not self.choice: - for default, cond in self.defaults: - cond_val = expr_value(cond) - if cond_val: - val = min(expr_value(default), cond_val) - break - - val = max(expr_value(self.rev_dep), - expr_value(self.weak_rev_dep), - val) - - # Transpose mod to yes if type is bool (possibly due to modules - # being disabled) - if val == 1 and self.type is BOOL: - val = 2 - - return TRI_TO_STR[val] - - if self.orig_type: # STRING/INT/HEX - for default, cond in self.defaults: - if expr_value(cond): - return default.str_value - - return "" - - def _warn_select_unsatisfied_deps(self): - # Helper for printing an informative warning when a symbol with - # unsatisfied direct dependencies (dependencies from 'depends on', ifs, - # and menus) is selected by some other symbol. Also warn if a symbol - # whose direct dependencies evaluate to m is selected to y. - - msg = "{} has direct dependencies {} with value {}, but is " \ - "currently being {}-selected by the following symbols:" \ - .format(self.name_and_loc, expr_str(self.direct_dep), - TRI_TO_STR[expr_value(self.direct_dep)], - TRI_TO_STR[expr_value(self.rev_dep)]) - - # The reverse dependencies from each select are ORed together - for select in split_expr(self.rev_dep, OR): - if expr_value(select) <= expr_value(self.direct_dep): - # Only include selects that exceed the direct dependencies - continue - - # - 'select A if B' turns into A && B - # - 'select A' just turns into A - # - # In both cases, we can split on AND and pick the first operand - selecting_sym = split_expr(select, AND)[0] - - msg += "\n - {}, with value {}, direct dependencies {} " \ - "(value: {})" \ - .format(selecting_sym.name_and_loc, - selecting_sym.str_value, - expr_str(selecting_sym.direct_dep), - TRI_TO_STR[expr_value(selecting_sym.direct_dep)]) - - if select.__class__ is tuple: - msg += ", and select condition {} (value: {})" \ - .format(expr_str(select[2]), - TRI_TO_STR[expr_value(select[2])]) - - self.kconfig._warn(msg) - - -class Choice(object): - """ - Represents a choice statement: - - choice - ... - endchoice - - The following attributes are available on Choice instances. They should be - treated as read-only, and some are implemented through @property magic (but - are still efficient to access due to internal caching). - - Note: Prompts, help texts, and locations are stored in the Choice's - MenuNode(s) rather than in the Choice itself. Check the MenuNode class and - the Choice.nodes attribute. This organization matches the C tools. - - name: - The name of the choice, e.g. "FOO" for 'choice FOO', or None if the - Choice has no name. - - type: - The type of the choice. One of BOOL, TRISTATE, UNKNOWN. UNKNOWN is for - choices defined without a type where none of the contained symbols have a - type either (otherwise the choice inherits the type of the first symbol - defined with a type). - - When running without modules (CONFIG_MODULES=n), TRISTATE choices - magically change type to BOOL. This matches the C tools, and makes sense - for menuconfig-like functionality. - - orig_type: - The type as given in the Kconfig file, without any magic applied. Used - when printing the choice. - - tri_value: - The tristate value (mode) of the choice. A choice can be in one of three - modes: - - 0 (n) - The choice is disabled and no symbols can be selected. For - visible choices, this mode is only possible for choices with - the 'optional' flag set (see kconfig-language.txt). - - 1 (m) - Any number of choice symbols can be set to m, the rest will - be n. - - 2 (y) - One symbol will be y, the rest n. - - Only tristate choices can be in m mode. The visibility of the choice is - an upper bound on the mode, and the mode in turn is an upper bound on the - visibility of the choice symbols. - - To change the mode, use Choice.set_value(). - - Implementation note: - The C tools internally represent choices as a type of symbol, with - special-casing in many code paths. This is why there is a lot of - similarity to Symbol. The value (mode) of a choice is really just a - normal symbol value, and an implicit reverse dependency forces its - lower bound to m for visible non-optional choices (the reverse - dependency is 'm && <visibility>'). - - Symbols within choices get the choice propagated as a dependency to - their properties. This turns the mode of the choice into an upper bound - on e.g. the visibility of choice symbols, and explains the gotcha - related to printing choice symbols mentioned in the module docstring. - - Kconfiglib uses a separate Choice class only because it makes the code - and interface less confusing (especially in a user-facing interface). - Corresponding attributes have the same name in the Symbol and Choice - classes, for consistency and compatibility. - - str_value: - Like choice.tri_value, but gives the value as one of the strings - "n", "m", or "y" - - user_value: - The value (mode) selected by the user through Choice.set_value(). Either - 0, 1, or 2, or None if the user hasn't selected a mode. See - Symbol.user_value. - - WARNING: Do not assign directly to this. It will break things. Use - Choice.set_value() instead. - - assignable: - See the symbol class documentation. Gives the assignable values (modes). - - selection: - The Symbol instance of the currently selected symbol. None if the Choice - is not in y mode or has no selected symbol (due to unsatisfied - dependencies on choice symbols). - - WARNING: Do not assign directly to this. It will break things. Call - sym.set_value(2) on the choice symbol you want to select instead. - - user_selection: - The symbol selected by the user (by setting it to y). Ignored if the - choice is not in y mode, but still remembered so that the choice "snaps - back" to the user selection if the mode is changed back to y. This might - differ from 'selection' due to unsatisfied dependencies. - - WARNING: Do not assign directly to this. It will break things. Call - sym.set_value(2) on the choice symbol to be selected instead. - - visibility: - See the Symbol class documentation. Acts on the value (mode). - - name_and_loc: - Holds a string like - - "<choice MY_CHOICE> (defined at foo/Kconfig:12)" - - , giving the name of the choice and its definition location(s). If the - choice has no name (isn't defined with 'choice MY_CHOICE'), then it will - be shown as "<choice>" before the list of locations (always a single one - in that case). - - syms: - List of symbols contained in the choice. - - Obscure gotcha: If a symbol depends on the previous symbol within a - choice so that an implicit menu is created, it won't be a choice symbol, - and won't be included in 'syms'. - - nodes: - A list of MenuNodes for this choice. In practice, the list will probably - always contain a single MenuNode, but it is possible to give a choice a - name and define it in multiple locations. - - defaults: - List of (symbol, cond) tuples for the choice's 'defaults' properties. For - example, 'default A if B && C' is represented as (A, (AND, B, C)). If - there is no condition, 'cond' is self.kconfig.y. - - Note that 'depends on' and parent dependencies are propagated to - 'default' conditions. - - orig_defaults: - See the corresponding attribute on the MenuNode class. - - direct_dep: - See Symbol.direct_dep. - - referenced: - A set() with all symbols referenced in the properties and property - conditions of the choice. - - Also includes dependencies from surrounding menus and ifs, because those - get propagated to the choice (see the 'Intro to symbol values' section in - the module docstring). - - is_optional: - True if the choice has the 'optional' flag set on it and can be in - n mode. - - kconfig: - The Kconfig instance this choice is from. - """ - __slots__ = ( - "_cached_assignable", - "_cached_selection", - "_cached_vis", - "_dependents", - "_visited", - "_was_set", - "defaults", - "direct_dep", - "is_constant", - "is_optional", - "kconfig", - "name", - "nodes", - "orig_type", - "syms", - "user_selection", - "user_value", - ) - - # - # Public interface - # - - @property - def type(self): - """ - Returns the type of the choice. See Symbol.type. - """ - if self.orig_type is TRISTATE and not self.kconfig.modules.tri_value: - return BOOL - return self.orig_type - - @property - def str_value(self): - """ - See the class documentation. - """ - return TRI_TO_STR[self.tri_value] - - @property - def tri_value(self): - """ - See the class documentation. - """ - # This emulates a reverse dependency of 'm && visibility' for - # non-optional choices, which is how the C implementation does it - - val = 0 if self.is_optional else 1 - - if self.user_value is not None: - val = max(val, self.user_value) - - # Warning: See Symbol._rec_invalidate(), and note that this is a hidden - # function call (property magic) - val = min(val, self.visibility) - - # Promote m to y for boolean choices - return 2 if val == 1 and self.type is BOOL else val - - @property - def assignable(self): - """ - See the class documentation. - """ - if self._cached_assignable is None: - self._cached_assignable = self._assignable() - return self._cached_assignable - - @property - def visibility(self): - """ - See the class documentation. - """ - if self._cached_vis is None: - self._cached_vis = _visibility(self) - return self._cached_vis - - @property - def name_and_loc(self): - """ - See the class documentation. - """ - # Reuse the expression format, which is '<choice (name, if any)>'. - return standard_sc_expr_str(self) + " " + _locs(self) - - @property - def selection(self): - """ - See the class documentation. - """ - if self._cached_selection is _NO_CACHED_SELECTION: - self._cached_selection = self._selection() - return self._cached_selection - - def set_value(self, value): - """ - Sets the user value (mode) of the choice. Like for Symbol.set_value(), - the visibility might truncate the value. Choices without the 'optional' - attribute (is_optional) can never be in n mode, but 0/"n" is still - accepted since it's not a malformed value (though it will have no - effect). - - Returns True if the value is valid for the type of the choice, and - False otherwise. This only looks at the form of the value. Check the - Choice.assignable attribute to see what values are currently in range - and would actually be reflected in the mode of the choice. - """ - if value in STR_TO_TRI: - value = STR_TO_TRI[value] - - if value == self.user_value: - # We know the value must be valid if it was successfully set - # previously - self._was_set = True - return True - - if not (self.orig_type is BOOL and value in (2, 0) or - self.orig_type is TRISTATE and value in TRI_TO_STR): - - # Display tristate values as n, m, y in the warning - self.kconfig._warn( - "the value {} is invalid for {}, which has type {} -- " - "assignment ignored" - .format(TRI_TO_STR[value] if value in TRI_TO_STR else - "'{}'".format(value), - self.name_and_loc, TYPE_TO_STR[self.orig_type])) - - return False - - self.user_value = value - self._was_set = True - self._rec_invalidate() - - return True - - def unset_value(self): - """ - Resets the user value (mode) and user selection of the Choice, as if - the user had never touched the mode or any of the choice symbols. - """ - if self.user_value is not None or self.user_selection: - self.user_value = self.user_selection = None - self._rec_invalidate() - - @property - def referenced(self): - """ - See the class documentation. - """ - return {item for node in self.nodes for item in node.referenced} - - @property - def orig_defaults(self): - """ - See the class documentation. - """ - return [d for node in self.nodes for d in node.orig_defaults] - - def __repr__(self): - """ - Returns a string with information about the choice when it is evaluated - on e.g. the interactive Python prompt. - """ - fields = ["choice " + self.name if self.name else "choice", - TYPE_TO_STR[self.type]] - add = fields.append - - for node in self.nodes: - if node.prompt: - add('"{}"'.format(node.prompt[0])) - - add("mode " + self.str_value) - - if self.user_value is not None: - add('user mode {}'.format(TRI_TO_STR[self.user_value])) - - if self.selection: - add("{} selected".format(self.selection.name)) - - if self.user_selection: - user_sel_str = "{} selected by user" \ - .format(self.user_selection.name) - - if self.selection is not self.user_selection: - user_sel_str += " (overridden)" - - add(user_sel_str) - - add("visibility " + TRI_TO_STR[self.visibility]) - - if self.is_optional: - add("optional") - - for node in self.nodes: - add("{}:{}".format(node.filename, node.linenr)) - - return "<{}>".format(", ".join(fields)) - - def __str__(self): - """ - Returns a string representation of the choice when it is printed. - Matches the Kconfig format (though without the contained choice - symbols), with any parent dependencies propagated to the 'depends on' - condition. - - The returned string does not end in a newline. - - See Symbol.__str__() as well. - """ - return self.custom_str(standard_sc_expr_str) - - def custom_str(self, sc_expr_str_fn): - """ - Works like Choice.__str__(), but allows a custom format to be used for - all symbol/choice references. See expr_str(). - """ - return "\n\n".join(node.custom_str(sc_expr_str_fn) - for node in self.nodes) - - # - # Private methods - # - - def __init__(self): - """ - Choice constructor -- not intended to be called directly by Kconfiglib - clients. - """ - # These attributes are always set on the instance from outside and - # don't need defaults: - # direct_dep - # kconfig - - # - UNKNOWN == 0 - # - _visited is used during dep. loop detection - self.orig_type = self._visited = 0 - - self.nodes = [] - - self.syms = [] - self.defaults = [] - - self.name = \ - self.user_value = self.user_selection = \ - self._cached_vis = self._cached_assignable = None - - self._cached_selection = _NO_CACHED_SELECTION - - # is_constant is checked by _depend_on(). Just set it to avoid having - # to special-case choices. - self.is_constant = self.is_optional = False - - # See Kconfig._build_dep() - self._dependents = set() - - def _assignable(self): - # Worker function for the 'assignable' attribute - - # Warning: See Symbol._rec_invalidate(), and note that this is a hidden - # function call (property magic) - vis = self.visibility - - if not vis: - return () - - if vis == 2: - if not self.is_optional: - return (2,) if self.type is BOOL else (1, 2) - return (0, 2) if self.type is BOOL else (0, 1, 2) - - # vis == 1 - - return (0, 1) if self.is_optional else (1,) - - def _selection(self): - # Worker function for the 'selection' attribute - - # Warning: See Symbol._rec_invalidate(), and note that this is a hidden - # function call (property magic) - if self.tri_value != 2: - # Not in y mode, so no selection - return None - - # Use the user selection if it's visible - if self.user_selection and self.user_selection.visibility: - return self.user_selection - - # Otherwise, check if we have a default - return self._selection_from_defaults() - - def _selection_from_defaults(self): - # Check if we have a default - for sym, cond in self.defaults: - # The default symbol must be visible too - if expr_value(cond) and sym.visibility: - return sym - - # Otherwise, pick the first visible symbol, if any - for sym in self.syms: - if sym.visibility: - return sym - - # Couldn't find a selection - return None - - def _invalidate(self): - self._cached_vis = self._cached_assignable = None - self._cached_selection = _NO_CACHED_SELECTION - - def _rec_invalidate(self): - # See Symbol._rec_invalidate() - - self._invalidate() - - for item in self._dependents: - if item._cached_vis is not None: - item._rec_invalidate() - - -class MenuNode(object): - """ - Represents a menu node in the configuration. This corresponds to an entry - in e.g. the 'make menuconfig' interface, though non-visible choices, menus, - and comments also get menu nodes. If a symbol or choice is defined in - multiple locations, it gets one menu node for each location. - - The top-level menu node, corresponding to the implicit top-level menu, is - available in Kconfig.top_node. - - The menu nodes for a Symbol or Choice can be found in the - Symbol/Choice.nodes attribute. Menus and comments are represented as plain - menu nodes, with their text stored in the prompt attribute (prompt[0]). - This mirrors the C implementation. - - The following attributes are available on MenuNode instances. They should - be viewed as read-only. - - item: - Either a Symbol, a Choice, or one of the constants MENU and COMMENT. - Menus and comments are represented as plain menu nodes. Ifs are collapsed - (matching the C implementation) and do not appear in the final menu tree. - - next: - The following menu node. None if there is no following node. - - list: - The first child menu node. None if there are no children. - - Choices and menus naturally have children, but Symbols can also have - children because of menus created automatically from dependencies (see - kconfig-language.txt). - - parent: - The parent menu node. None if there is no parent. - - prompt: - A (string, cond) tuple with the prompt for the menu node and its - conditional expression (which is self.kconfig.y if there is no - condition). None if there is no prompt. - - For symbols and choices, the prompt is stored in the MenuNode rather than - the Symbol or Choice instance. For menus and comments, the prompt holds - the text. - - defaults: - The 'default' properties for this particular menu node. See - symbol.defaults. - - When evaluating defaults, you should use Symbol/Choice.defaults instead, - as it include properties from all menu nodes (a symbol/choice can have - multiple definition locations/menu nodes). MenuNode.defaults is meant for - documentation generation. - - selects: - Like MenuNode.defaults, for selects. - - implies: - Like MenuNode.defaults, for implies. - - ranges: - Like MenuNode.defaults, for ranges. - - orig_prompt: - orig_defaults: - orig_selects: - orig_implies: - orig_ranges: - These work the like the corresponding attributes without orig_*, but omit - any dependencies propagated from 'depends on' and surrounding 'if's (the - direct dependencies, stored in MenuNode.dep). - - One use for this is generating less cluttered documentation, by only - showing the direct dependencies in one place. - - help: - The help text for the menu node for Symbols and Choices. None if there is - no help text. Always stored in the node rather than the Symbol or Choice. - It is possible to have a separate help text at each location if a symbol - is defined in multiple locations. - - Trailing whitespace (including a final newline) is stripped from the help - text. This was not the case before Kconfiglib 10.21.0, where the format - was undocumented. - - dep: - The direct ('depends on') dependencies for the menu node, or - self.kconfig.y if there are no direct dependencies. - - This attribute includes any dependencies from surrounding menus and ifs. - Those get propagated to the direct dependencies, and the resulting direct - dependencies in turn get propagated to the conditions of all properties. - - If a symbol or choice is defined in multiple locations, only the - properties defined at a particular location get the corresponding - MenuNode.dep dependencies propagated to them. - - visibility: - The 'visible if' dependencies for the menu node (which must represent a - menu), or self.kconfig.y if there are no 'visible if' dependencies. - 'visible if' dependencies are recursively propagated to the prompts of - symbols and choices within the menu. - - referenced: - A set() with all symbols and choices referenced in the properties and - property conditions of the menu node. - - Also includes dependencies inherited from surrounding menus and ifs. - Choices appear in the dependencies of choice symbols. - - is_menuconfig: - Set to True if the children of the menu node should be displayed in a - separate menu. This is the case for the following items: - - - Menus (node.item == MENU) - - - Choices - - - Symbols defined with the 'menuconfig' keyword. The children come from - implicitly created submenus, and should be displayed in a separate - menu rather than being indented. - - 'is_menuconfig' is just a hint on how to display the menu node. It's - ignored internally by Kconfiglib, except when printing symbols. - - filename/linenr: - The location where the menu node appears. The filename is relative to - $srctree (or to the current directory if $srctree isn't set), except - absolute paths are used for paths outside $srctree. - - include_path: - A tuple of (filename, linenr) tuples, giving the locations of the - 'source' statements via which the Kconfig file containing this menu node - was included. The first element is the location of the 'source' statement - in the top-level Kconfig file passed to Kconfig.__init__(), etc. - - Note that the Kconfig file of the menu node itself isn't included. Check - 'filename' and 'linenr' for that. - - kconfig: - The Kconfig instance the menu node is from. - """ - __slots__ = ( - "dep", - "filename", - "help", - "include_path", - "is_menuconfig", - "item", - "kconfig", - "linenr", - "list", - "next", - "parent", - "prompt", - "visibility", - - # Properties - "defaults", - "selects", - "implies", - "ranges", - ) - - def __init__(self): - # Properties defined on this particular menu node. A local 'depends on' - # only applies to these, in case a symbol is defined in multiple - # locations. - self.defaults = [] - self.selects = [] - self.implies = [] - self.ranges = [] - - @property - def orig_prompt(self): - """ - See the class documentation. - """ - if not self.prompt: - return None - return (self.prompt[0], self._strip_dep(self.prompt[1])) - - @property - def orig_defaults(self): - """ - See the class documentation. - """ - return [(default, self._strip_dep(cond)) - for default, cond in self.defaults] - - @property - def orig_selects(self): - """ - See the class documentation. - """ - return [(select, self._strip_dep(cond)) - for select, cond in self.selects] - - @property - def orig_implies(self): - """ - See the class documentation. - """ - return [(imply, self._strip_dep(cond)) - for imply, cond in self.implies] - - @property - def orig_ranges(self): - """ - See the class documentation. - """ - return [(low, high, self._strip_dep(cond)) - for low, high, cond in self.ranges] - - @property - def referenced(self): - """ - See the class documentation. - """ - # self.dep is included to catch dependencies from a lone 'depends on' - # when there are no properties to propagate it to - res = expr_items(self.dep) - - if self.prompt: - res |= expr_items(self.prompt[1]) - - if self.item is MENU: - res |= expr_items(self.visibility) - - for value, cond in self.defaults: - res |= expr_items(value) - res |= expr_items(cond) - - for value, cond in self.selects: - res.add(value) - res |= expr_items(cond) - - for value, cond in self.implies: - res.add(value) - res |= expr_items(cond) - - for low, high, cond in self.ranges: - res.add(low) - res.add(high) - res |= expr_items(cond) - - return res - - def __repr__(self): - """ - Returns a string with information about the menu node when it is - evaluated on e.g. the interactive Python prompt. - """ - fields = [] - add = fields.append - - if self.item.__class__ is Symbol: - add("menu node for symbol " + self.item.name) - - elif self.item.__class__ is Choice: - s = "menu node for choice" - if self.item.name is not None: - s += " " + self.item.name - add(s) - - elif self.item is MENU: - add("menu node for menu") - - else: # self.item is COMMENT - add("menu node for comment") - - if self.prompt: - add('prompt "{}" (visibility {})'.format( - self.prompt[0], TRI_TO_STR[expr_value(self.prompt[1])])) - - if self.item.__class__ is Symbol and self.is_menuconfig: - add("is menuconfig") - - add("deps " + TRI_TO_STR[expr_value(self.dep)]) - - if self.item is MENU: - add("'visible if' deps " + TRI_TO_STR[expr_value(self.visibility)]) - - if self.item.__class__ in _SYMBOL_CHOICE and self.help is not None: - add("has help") - - if self.list: - add("has child") - - if self.next: - add("has next") - - add("{}:{}".format(self.filename, self.linenr)) - - return "<{}>".format(", ".join(fields)) - - def __str__(self): - """ - Returns a string representation of the menu node. Matches the Kconfig - format, with any parent dependencies propagated to the 'depends on' - condition. - - The output could (almost) be fed back into a Kconfig parser to redefine - the object associated with the menu node. See the module documentation - for a gotcha related to choice symbols. - - For symbols and choices with multiple menu nodes (multiple definition - locations), properties that aren't associated with a particular menu - node are shown on all menu nodes ('option env=...', 'optional' for - choices, etc.). - - The returned string does not end in a newline. - """ - return self.custom_str(standard_sc_expr_str) - - def custom_str(self, sc_expr_str_fn): - """ - Works like MenuNode.__str__(), but allows a custom format to be used - for all symbol/choice references. See expr_str(). - """ - return self._menu_comment_node_str(sc_expr_str_fn) \ - if self.item in _MENU_COMMENT else \ - self._sym_choice_node_str(sc_expr_str_fn) - - def _menu_comment_node_str(self, sc_expr_str_fn): - s = '{} "{}"'.format("menu" if self.item is MENU else "comment", - self.prompt[0]) - - if self.dep is not self.kconfig.y: - s += "\n\tdepends on {}".format(expr_str(self.dep, sc_expr_str_fn)) - - if self.item is MENU and self.visibility is not self.kconfig.y: - s += "\n\tvisible if {}".format(expr_str(self.visibility, - sc_expr_str_fn)) - - return s - - def _sym_choice_node_str(self, sc_expr_str_fn): - def indent_add(s): - lines.append("\t" + s) - - def indent_add_cond(s, cond): - if cond is not self.kconfig.y: - s += " if " + expr_str(cond, sc_expr_str_fn) - indent_add(s) - - sc = self.item - - if sc.__class__ is Symbol: - lines = [("menuconfig " if self.is_menuconfig else "config ") - + sc.name] - else: - lines = ["choice " + sc.name if sc.name else "choice"] - - if sc.orig_type and not self.prompt: # sc.orig_type != UNKNOWN - # If there's a prompt, we'll use the '<type> "prompt"' shorthand - # instead - indent_add(TYPE_TO_STR[sc.orig_type]) - - if self.prompt: - if sc.orig_type: - prefix = TYPE_TO_STR[sc.orig_type] - else: - # Symbol defined without a type (which generates a warning) - prefix = "prompt" - - indent_add_cond(prefix + ' "{}"'.format(escape(self.prompt[0])), - self.orig_prompt[1]) - - if sc.__class__ is Symbol: - if sc.is_allnoconfig_y: - indent_add("option allnoconfig_y") - - if sc is sc.kconfig.defconfig_list: - indent_add("option defconfig_list") - - if sc.env_var is not None: - indent_add('option env="{}"'.format(sc.env_var)) - - if sc is sc.kconfig.modules: - indent_add("option modules") - - for low, high, cond in self.orig_ranges: - indent_add_cond( - "range {} {}".format(sc_expr_str_fn(low), - sc_expr_str_fn(high)), - cond) - - for default, cond in self.orig_defaults: - indent_add_cond("default " + expr_str(default, sc_expr_str_fn), - cond) - - if sc.__class__ is Choice and sc.is_optional: - indent_add("optional") - - if sc.__class__ is Symbol: - for select, cond in self.orig_selects: - indent_add_cond("select " + sc_expr_str_fn(select), cond) - - for imply, cond in self.orig_implies: - indent_add_cond("imply " + sc_expr_str_fn(imply), cond) - - if self.dep is not sc.kconfig.y: - indent_add("depends on " + expr_str(self.dep, sc_expr_str_fn)) - - if self.help is not None: - indent_add("help") - for line in self.help.splitlines(): - indent_add(" " + line) - - return "\n".join(lines) - - def _strip_dep(self, expr): - # Helper function for removing MenuNode.dep from 'expr'. Uses two - # pieces of internal knowledge: (1) Expressions are reused rather than - # copied, and (2) the direct dependencies always appear at the end. - - # ... if dep -> ... if y - if self.dep is expr: - return self.kconfig.y - - # (AND, X, dep) -> X - if expr.__class__ is tuple and expr[0] is AND and expr[2] is self.dep: - return expr[1] - - return expr - - -class Variable(object): - """ - Represents a preprocessor variable/function. - - The following attributes are available: - - name: - The name of the variable. - - value: - The unexpanded value of the variable. - - expanded_value: - The expanded value of the variable. For simple variables (those defined - with :=), this will equal 'value'. Accessing this property will raise a - KconfigError if the expansion seems to be stuck in a loop. - - Accessing this field is the same as calling expanded_value_w_args() with - no arguments. I hadn't considered function arguments when adding it. It - is retained for backwards compatibility though. - - is_recursive: - True if the variable is recursive (defined with =). - """ - __slots__ = ( - "_n_expansions", - "is_recursive", - "kconfig", - "name", - "value", - ) - - @property - def expanded_value(self): - """ - See the class documentation. - """ - return self.expanded_value_w_args() - - def expanded_value_w_args(self, *args): - """ - Returns the expanded value of the variable/function. Any arguments - passed will be substituted for $(1), $(2), etc. - - Raises a KconfigError if the expansion seems to be stuck in a loop. - """ - return self.kconfig._fn_val((self.name,) + args) - - def __repr__(self): - return "<variable {}, {}, value '{}'>" \ - .format(self.name, - "recursive" if self.is_recursive else "immediate", - self.value) - - -class KconfigError(Exception): - """ - Exception raised for Kconfig-related errors. - - KconfigError and KconfigSyntaxError are the same class. The - KconfigSyntaxError alias is only maintained for backwards compatibility. - """ - -KconfigSyntaxError = KconfigError # Backwards compatibility - - -class InternalError(Exception): - "Never raised. Kept around for backwards compatibility." - - -# Workaround: -# -# If 'errno' and 'strerror' are set on IOError, then __str__() always returns -# "[Errno <errno>] <strerror>", ignoring any custom message passed to the -# constructor. By defining our own subclass, we can use a custom message while -# also providing 'errno', 'strerror', and 'filename' to scripts. -class _KconfigIOError(IOError): - def __init__(self, ioerror, msg): - self.msg = msg - super(_KconfigIOError, self).__init__( - ioerror.errno, ioerror.strerror, ioerror.filename) - - def __str__(self): - return self.msg - - -# -# Public functions -# - - -def expr_value(expr): - """ - Evaluates the expression 'expr' to a tristate value. Returns 0 (n), 1 (m), - or 2 (y). - - 'expr' must be an already-parsed expression from a Symbol, Choice, or - MenuNode property. To evaluate an expression represented as a string, use - Kconfig.eval_string(). - - Passing subexpressions of expressions to this function works as expected. - """ - if expr.__class__ is not tuple: - return expr.tri_value - - if expr[0] is AND: - v1 = expr_value(expr[1]) - # Short-circuit the n case as an optimization (~5% faster - # allnoconfig.py and allyesconfig.py, as of writing) - return 0 if not v1 else min(v1, expr_value(expr[2])) - - if expr[0] is OR: - v1 = expr_value(expr[1]) - # Short-circuit the y case as an optimization - return 2 if v1 == 2 else max(v1, expr_value(expr[2])) - - if expr[0] is NOT: - return 2 - expr_value(expr[1]) - - # Relation - # - # Implements <, <=, >, >= comparisons as well. These were added to - # kconfig in 31847b67 (kconfig: allow use of relations other than - # (in)equality). - - rel, v1, v2 = expr - - # If both operands are strings... - if v1.orig_type is STRING and v2.orig_type is STRING: - # ...then compare them lexicographically - comp = _strcmp(v1.str_value, v2.str_value) - else: - # Otherwise, try to compare them as numbers - try: - comp = _sym_to_num(v1) - _sym_to_num(v2) - except ValueError: - # Fall back on a lexicographic comparison if the operands don't - # parse as numbers - comp = _strcmp(v1.str_value, v2.str_value) - - return 2*(comp == 0 if rel is EQUAL else - comp != 0 if rel is UNEQUAL else - comp < 0 if rel is LESS else - comp <= 0 if rel is LESS_EQUAL else - comp > 0 if rel is GREATER else - comp >= 0) - - -def standard_sc_expr_str(sc): - """ - Standard symbol/choice printing function. Uses plain Kconfig syntax, and - displays choices as <choice> (or <choice NAME>, for named choices). - - See expr_str(). - """ - if sc.__class__ is Symbol: - if sc.is_constant and sc.name not in STR_TO_TRI: - return '"{}"'.format(escape(sc.name)) - return sc.name - - return "<choice {}>".format(sc.name) if sc.name else "<choice>" - - -def expr_str(expr, sc_expr_str_fn=standard_sc_expr_str): - """ - Returns the string representation of the expression 'expr', as in a Kconfig - file. - - Passing subexpressions of expressions to this function works as expected. - - sc_expr_str_fn (default: standard_sc_expr_str): - This function is called for every symbol/choice (hence "sc") appearing in - the expression, with the symbol/choice as the argument. It is expected to - return a string to be used for the symbol/choice. - - This can be used e.g. to turn symbols/choices into links when generating - documentation, or for printing the value of each symbol/choice after it. - - Note that quoted values are represented as constants symbols - (Symbol.is_constant == True). - """ - if expr.__class__ is not tuple: - return sc_expr_str_fn(expr) - - if expr[0] is AND: - return "{} && {}".format(_parenthesize(expr[1], OR, sc_expr_str_fn), - _parenthesize(expr[2], OR, sc_expr_str_fn)) - - if expr[0] is OR: - # This turns A && B || C && D into "(A && B) || (C && D)", which is - # redundant, but more readable - return "{} || {}".format(_parenthesize(expr[1], AND, sc_expr_str_fn), - _parenthesize(expr[2], AND, sc_expr_str_fn)) - - if expr[0] is NOT: - if expr[1].__class__ is tuple: - return "!({})".format(expr_str(expr[1], sc_expr_str_fn)) - return "!" + sc_expr_str_fn(expr[1]) # Symbol - - # Relation - # - # Relation operands are always symbols (quoted strings are constant - # symbols) - return "{} {} {}".format(sc_expr_str_fn(expr[1]), REL_TO_STR[expr[0]], - sc_expr_str_fn(expr[2])) - - -def expr_items(expr): - """ - Returns a set() of all items (symbols and choices) that appear in the - expression 'expr'. - - Passing subexpressions of expressions to this function works as expected. - """ - res = set() - - def rec(subexpr): - if subexpr.__class__ is tuple: - # AND, OR, NOT, or relation - - rec(subexpr[1]) - - # NOTs only have a single operand - if subexpr[0] is not NOT: - rec(subexpr[2]) - - else: - # Symbol or choice - res.add(subexpr) - - rec(expr) - return res - - -def split_expr(expr, op): - """ - Returns a list containing the top-level AND or OR operands in the - expression 'expr', in the same (left-to-right) order as they appear in - the expression. - - This can be handy e.g. for splitting (weak) reverse dependencies - from 'select' and 'imply' into individual selects/implies. - - op: - Either AND to get AND operands, or OR to get OR operands. - - (Having this as an operand might be more future-safe than having two - hardcoded functions.) - - - Pseudo-code examples: - - split_expr( A , OR ) -> [A] - split_expr( A && B , OR ) -> [A && B] - split_expr( A || B , OR ) -> [A, B] - split_expr( A || B , AND ) -> [A || B] - split_expr( A || B || (C && D) , OR ) -> [A, B, C && D] - - # Second || is not at the top level - split_expr( A || (B && (C || D)) , OR ) -> [A, B && (C || D)] - - # Parentheses don't matter as long as we stay at the top level (don't - # encounter any non-'op' nodes) - split_expr( (A || B) || C , OR ) -> [A, B, C] - split_expr( A || (B || C) , OR ) -> [A, B, C] - """ - res = [] - - def rec(subexpr): - if subexpr.__class__ is tuple and subexpr[0] is op: - rec(subexpr[1]) - rec(subexpr[2]) - else: - res.append(subexpr) - - rec(expr) - return res - - -def escape(s): - r""" - Escapes the string 's' in the same fashion as is done for display in - Kconfig format and when writing strings to a .config file. " and \ are - replaced by \" and \\, respectively. - """ - # \ must be escaped before " to avoid double escaping - return s.replace("\\", r"\\").replace('"', r'\"') - - -def unescape(s): - r""" - Unescapes the string 's'. \ followed by any character is replaced with just - that character. Used internally when reading .config files. - """ - return _unescape_sub(r"\1", s) - -# unescape() helper -_unescape_sub = re.compile(r"\\(.)").sub - - -def standard_kconfig(description=None): - """ - Argument parsing helper for tools that take a single optional Kconfig file - argument (default: Kconfig). Returns the Kconfig instance for the parsed - configuration. Uses argparse internally. - - Exits with sys.exit() (which raises SystemExit) on errors. - - description (default: None): - The 'description' passed to argparse.ArgumentParser(). - argparse.RawDescriptionHelpFormatter is used, so formatting is preserved. - """ - import argparse - - parser = argparse.ArgumentParser( - formatter_class=argparse.RawDescriptionHelpFormatter, - description=description) - - parser.add_argument( - "kconfig", - metavar="KCONFIG", - default="Kconfig", - nargs="?", - help="Top-level Kconfig file (default: Kconfig)") - - return Kconfig(parser.parse_args().kconfig, suppress_traceback=True) - - -def standard_config_filename(): - """ - Helper for tools. Returns the value of KCONFIG_CONFIG (which specifies the - .config file to load/save) if it is set, and ".config" otherwise. - - Calling load_config() with filename=None might give the behavior you want, - without having to use this function. - """ - return os.getenv("KCONFIG_CONFIG", ".config") - - -def load_allconfig(kconf, filename): - """ - Use Kconfig.load_allconfig() instead, which was added in Kconfiglib 13.4.0. - Supported for backwards compatibility. Might be removed at some point after - a long period of deprecation warnings. - """ - allconfig = os.getenv("KCONFIG_ALLCONFIG") - if allconfig is None: - return - - def std_msg(e): - # "Upcasts" a _KconfigIOError to an IOError, removing the custom - # __str__() message. The standard message is better here. - # - # This might also convert an OSError to an IOError in obscure cases, - # but it's probably not a big deal. The distinction is shaky (see - # PEP-3151). - return IOError(e.errno, e.strerror, e.filename) - - old_warn_assign_override = kconf.warn_assign_override - old_warn_assign_redun = kconf.warn_assign_redun - kconf.warn_assign_override = kconf.warn_assign_redun = False - - if allconfig in ("", "1"): - try: - print(kconf.load_config(filename, False)) - except EnvironmentError as e1: - try: - print(kconf.load_config("all.config", False)) - except EnvironmentError as e2: - sys.exit("error: KCONFIG_ALLCONFIG is set, but neither {} " - "nor all.config could be opened: {}, {}" - .format(filename, std_msg(e1), std_msg(e2))) - else: - try: - print(kconf.load_config(allconfig, False)) - except EnvironmentError as e: - sys.exit("error: KCONFIG_ALLCONFIG is set to '{}', which " - "could not be opened: {}" - .format(allconfig, std_msg(e))) - - kconf.warn_assign_override = old_warn_assign_override - kconf.warn_assign_redun = old_warn_assign_redun - - -# -# Internal functions -# - - -def _visibility(sc): - # Symbols and Choices have a "visibility" that acts as an upper bound on - # the values a user can set for them, corresponding to the visibility in - # e.g. 'make menuconfig'. This function calculates the visibility for the - # Symbol or Choice 'sc' -- the logic is nearly identical. - - vis = 0 - - for node in sc.nodes: - if node.prompt: - vis = max(vis, expr_value(node.prompt[1])) - - if sc.__class__ is Symbol and sc.choice: - if sc.choice.orig_type is TRISTATE and \ - sc.orig_type is not TRISTATE and sc.choice.tri_value != 2: - # Non-tristate choice symbols are only visible in y mode - return 0 - - if sc.orig_type is TRISTATE and vis == 1 and sc.choice.tri_value == 2: - # Choice symbols with m visibility are not visible in y mode - return 0 - - # Promote m to y if we're dealing with a non-tristate (possibly due to - # modules being disabled) - if vis == 1 and sc.type is not TRISTATE: - return 2 - - return vis - - -def _depend_on(sc, expr): - # Adds 'sc' (symbol or choice) as a "dependee" to all symbols in 'expr'. - # Constant symbols in 'expr' are skipped as they can never change value - # anyway. - - if expr.__class__ is tuple: - # AND, OR, NOT, or relation - - _depend_on(sc, expr[1]) - - # NOTs only have a single operand - if expr[0] is not NOT: - _depend_on(sc, expr[2]) - - elif not expr.is_constant: - # Non-constant symbol, or choice - expr._dependents.add(sc) - - -def _parenthesize(expr, type_, sc_expr_str_fn): - # expr_str() helper. Adds parentheses around expressions of type 'type_'. - - if expr.__class__ is tuple and expr[0] is type_: - return "({})".format(expr_str(expr, sc_expr_str_fn)) - return expr_str(expr, sc_expr_str_fn) - - -def _ordered_unique(lst): - # Returns 'lst' with any duplicates removed, preserving order. This hacky - # version seems to be a common idiom. It relies on short-circuit evaluation - # and set.add() returning None, which is falsy. - - seen = set() - seen_add = seen.add - return [x for x in lst if x not in seen and not seen_add(x)] - - -def _is_base_n(s, n): - try: - int(s, n) - return True - except ValueError: - return False - - -def _strcmp(s1, s2): - # strcmp()-alike that returns -1, 0, or 1 - - return (s1 > s2) - (s1 < s2) - - -def _sym_to_num(sym): - # expr_value() helper for converting a symbol to a number. Raises - # ValueError for symbols that can't be converted. - - # For BOOL and TRISTATE, n/m/y count as 0/1/2. This mirrors 9059a3493ef - # ("kconfig: fix relational operators for bool and tristate symbols") in - # the C implementation. - return sym.tri_value if sym.orig_type in _BOOL_TRISTATE else \ - int(sym.str_value, _TYPE_TO_BASE[sym.orig_type]) - - -def _touch_dep_file(path, sym_name): - # If sym_name is MY_SYM_NAME, touches my/sym/name.h. See the sync_deps() - # docstring. - - sym_path = path + os.sep + sym_name.lower().replace("_", os.sep) + ".h" - sym_path_dir = dirname(sym_path) - if not exists(sym_path_dir): - os.makedirs(sym_path_dir, 0o755) - - # A kind of truncating touch, mirroring the C tools - os.close(os.open( - sym_path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o644)) - - -def _save_old(path): - # See write_config() - - def copy(src, dst): - # Import as needed, to save some startup time - import shutil - shutil.copyfile(src, dst) - - if islink(path): - # Preserve symlinks - copy_fn = copy - elif hasattr(os, "replace"): - # Python 3 (3.3+) only. Best choice when available, because it - # removes <filename>.old on both *nix and Windows. - copy_fn = os.replace - elif os.name == "posix": - # Removes <filename>.old on POSIX systems - copy_fn = os.rename - else: - # Fall back on copying - copy_fn = copy - - try: - copy_fn(path, path + ".old") - except Exception: - # Ignore errors from 'path' missing as well as other errors. - # <filename>.old file is usually more of a nice-to-have, and not worth - # erroring out over e.g. if <filename>.old happens to be a directory or - # <filename> is something like /dev/null. - pass - - -def _locs(sc): - # Symbol/Choice.name_and_loc helper. Returns the "(defined at ...)" part of - # the string. 'sc' is a Symbol or Choice. - - if sc.nodes: - return "(defined at {})".format( - ", ".join("{0.filename}:{0.linenr}".format(node) - for node in sc.nodes)) - - return "(undefined)" - - -# Menu manipulation - - -def _expr_depends_on(expr, sym): - # Reimplementation of expr_depends_symbol() from mconf.c. Used to determine - # if a submenu should be implicitly created. This also influences which - # items inside choice statements are considered choice items. - - if expr.__class__ is not tuple: - return expr is sym - - if expr[0] in _EQUAL_UNEQUAL: - # Check for one of the following: - # sym = m/y, m/y = sym, sym != n, n != sym - - left, right = expr[1:] - - if right is sym: - left, right = right, left - elif left is not sym: - return False - - return (expr[0] is EQUAL and right is sym.kconfig.m or - right is sym.kconfig.y) or \ - (expr[0] is UNEQUAL and right is sym.kconfig.n) - - return expr[0] is AND and \ - (_expr_depends_on(expr[1], sym) or - _expr_depends_on(expr[2], sym)) - - -def _auto_menu_dep(node1, node2): - # Returns True if node2 has an "automatic menu dependency" on node1. If - # node2 has a prompt, we check its condition. Otherwise, we look directly - # at node2.dep. - - return _expr_depends_on(node2.prompt[1] if node2.prompt else node2.dep, - node1.item) - - -def _flatten(node): - # "Flattens" menu nodes without prompts (e.g. 'if' nodes and non-visible - # symbols with children from automatic menu creation) so that their - # children appear after them instead. This gives a clean menu structure - # with no unexpected "jumps" in the indentation. - # - # Do not flatten promptless choices (which can appear "legitimately" if a - # named choice is defined in multiple locations to add on symbols). It - # looks confusing, and the menuconfig already shows all choice symbols if - # you enter the choice at some location with a prompt. - - while node: - if node.list and not node.prompt and \ - node.item.__class__ is not Choice: - - last_node = node.list - while 1: - last_node.parent = node.parent - if not last_node.next: - break - last_node = last_node.next - - last_node.next = node.next - node.next = node.list - node.list = None - - node = node.next - - -def _remove_ifs(node): - # Removes 'if' nodes (which can be recognized by MenuNode.item being None), - # which are assumed to already have been flattened. The C implementation - # doesn't bother to do this, but we expose the menu tree directly, and it - # makes it nicer to work with. - - cur = node.list - while cur and not cur.item: - cur = cur.next - - node.list = cur - - while cur: - next = cur.next - while next and not next.item: - next = next.next - - # Equivalent to - # - # cur.next = next - # cur = next - # - # due to tricky Python semantics. The order matters. - cur.next = cur = next - - -def _finalize_choice(node): - # Finalizes a choice, marking each symbol whose menu node has the choice as - # the parent as a choice symbol, and automatically determining types if not - # specified. - - choice = node.item - - cur = node.list - while cur: - if cur.item.__class__ is Symbol: - cur.item.choice = choice - choice.syms.append(cur.item) - cur = cur.next - - # If no type is specified for the choice, its type is that of - # the first choice item with a specified type - if not choice.orig_type: - for item in choice.syms: - if item.orig_type: - choice.orig_type = item.orig_type - break - - # Each choice item of UNKNOWN type gets the type of the choice - for sym in choice.syms: - if not sym.orig_type: - sym.orig_type = choice.orig_type - - -def _check_dep_loop_sym(sym, ignore_choice): - # Detects dependency loops using depth-first search on the dependency graph - # (which is calculated earlier in Kconfig._build_dep()). - # - # Algorithm: - # - # 1. Symbols/choices start out with _visited = 0, meaning unvisited. - # - # 2. When a symbol/choice is first visited, _visited is set to 1, meaning - # "visited, potentially part of a dependency loop". The recursive - # search then continues from the symbol/choice. - # - # 3. If we run into a symbol/choice X with _visited already set to 1, - # there's a dependency loop. The loop is found on the call stack by - # recording symbols while returning ("on the way back") until X is seen - # again. - # - # 4. Once a symbol/choice and all its dependencies (or dependents in this - # case) have been checked recursively without detecting any loops, its - # _visited is set to 2, meaning "visited, not part of a dependency - # loop". - # - # This saves work if we run into the symbol/choice again in later calls - # to _check_dep_loop_sym(). We just return immediately. - # - # Choices complicate things, as every choice symbol depends on every other - # choice symbol in a sense. When a choice is "entered" via a choice symbol - # X, we visit all choice symbols from the choice except X, and prevent - # immediately revisiting the choice with a flag (ignore_choice). - # - # Maybe there's a better way to handle this (different flags or the - # like...) - - if not sym._visited: - # sym._visited == 0, unvisited - - sym._visited = 1 - - for dep in sym._dependents: - # Choices show up in Symbol._dependents when the choice has the - # symbol in a 'prompt' or 'default' condition (e.g. - # 'default ... if SYM'). - # - # Since we aren't entering the choice via a choice symbol, all - # choice symbols need to be checked, hence the None. - loop = _check_dep_loop_choice(dep, None) \ - if dep.__class__ is Choice \ - else _check_dep_loop_sym(dep, False) - - if loop: - # Dependency loop found - return _found_dep_loop(loop, sym) - - if sym.choice and not ignore_choice: - loop = _check_dep_loop_choice(sym.choice, sym) - if loop: - # Dependency loop found - return _found_dep_loop(loop, sym) - - # The symbol is not part of a dependency loop - sym._visited = 2 - - # No dependency loop found - return None - - if sym._visited == 2: - # The symbol was checked earlier and is already known to not be part of - # a dependency loop - return None - - # sym._visited == 1, found a dependency loop. Return the symbol as the - # first element in it. - return (sym,) - - -def _check_dep_loop_choice(choice, skip): - if not choice._visited: - # choice._visited == 0, unvisited - - choice._visited = 1 - - # Check for loops involving choice symbols. If we came here via a - # choice symbol, skip that one, as we'd get a false positive - # '<sym FOO> -> <choice> -> <sym FOO>' loop otherwise. - for sym in choice.syms: - if sym is not skip: - # Prevent the choice from being immediately re-entered via the - # "is a choice symbol" path by passing True - loop = _check_dep_loop_sym(sym, True) - if loop: - # Dependency loop found - return _found_dep_loop(loop, choice) - - # The choice is not part of a dependency loop - choice._visited = 2 - - # No dependency loop found - return None - - if choice._visited == 2: - # The choice was checked earlier and is already known to not be part of - # a dependency loop - return None - - # choice._visited == 1, found a dependency loop. Return the choice as the - # first element in it. - return (choice,) - - -def _found_dep_loop(loop, cur): - # Called "on the way back" when we know we have a loop - - # Is the symbol/choice 'cur' where the loop started? - if cur is not loop[0]: - # Nope, it's just a part of the loop - return loop + (cur,) - - # Yep, we have the entire loop. Throw an exception that shows it. - - msg = "\nDependency loop\n" \ - "===============\n\n" - - for item in loop: - if item is not loop[0]: - msg += "...depends on " - if item.__class__ is Symbol and item.choice: - msg += "the choice symbol " - - msg += "{}, with definition...\n\n{}\n\n" \ - .format(item.name_and_loc, item) - - # Small wart: Since we reuse the already calculated - # Symbol/Choice._dependents sets for recursive dependency detection, we - # lose information on whether a dependency came from a 'select'/'imply' - # condition or e.g. a 'depends on'. - # - # This might cause selecting symbols to "disappear". For example, - # a symbol B having 'select A if C' gives a direct dependency from A to - # C, since it corresponds to a reverse dependency of B && C. - # - # Always print reverse dependencies for symbols that have them to make - # sure information isn't lost. I wonder if there's some neat way to - # improve this. - - if item.__class__ is Symbol: - if item.rev_dep is not item.kconfig.n: - msg += "(select-related dependencies: {})\n\n" \ - .format(expr_str(item.rev_dep)) - - if item.weak_rev_dep is not item.kconfig.n: - msg += "(imply-related dependencies: {})\n\n" \ - .format(expr_str(item.rev_dep)) - - msg += "...depends again on " + loop[0].name_and_loc - - raise KconfigError(msg) - - -def _decoding_error(e, filename, macro_linenr=None): - # Gives the filename and context for UnicodeDecodeError's, which are a pain - # to debug otherwise. 'e' is the UnicodeDecodeError object. - # - # If the decoding error is for the output of a $(shell,...) command, - # macro_linenr holds the line number where it was run (the exact line - # number isn't available for decoding errors in files). - - raise KconfigError( - "\n" - "Malformed {} in {}\n" - "Context: {}\n" - "Problematic data: {}\n" - "Reason: {}".format( - e.encoding, - "'{}'".format(filename) if macro_linenr is None else - "output from macro at {}:{}".format(filename, macro_linenr), - e.object[max(e.start - 40, 0):e.end + 40], - e.object[e.start:e.end], - e.reason)) - - -def _warn_verbose_deprecated(fn_name): - sys.stderr.write( - "Deprecation warning: {0}()'s 'verbose' argument has no effect. Since " - "Kconfiglib 12.0.0, the message is returned from {0}() instead, " - "and is always generated. Do e.g. print(kconf.{0}()) if you want to " - "want to show a message like \"Loaded configuration '.config'\" on " - "stdout. The old API required ugly hacks to reuse messages in " - "configuration interfaces.\n".format(fn_name)) - - -# Predefined preprocessor functions - - -def _filename_fn(kconf, _): - return kconf.filename - - -def _lineno_fn(kconf, _): - return str(kconf.linenr) - - -def _info_fn(kconf, _, msg): - print("{}:{}: {}".format(kconf.filename, kconf.linenr, msg)) - - return "" - - -def _warning_if_fn(kconf, _, cond, msg): - if cond == "y": - kconf._warn(msg, kconf.filename, kconf.linenr) - - return "" - - -def _error_if_fn(kconf, _, cond, msg): - if cond == "y": - raise KconfigError("{}:{}: {}".format( - kconf.filename, kconf.linenr, msg)) - - return "" - - -def _shell_fn(kconf, _, command): - import subprocess # Only import as needed, to save some startup time - - stdout, stderr = subprocess.Popen( - command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE - ).communicate() - - if not _IS_PY2: - try: - stdout = stdout.decode(kconf._encoding) - stderr = stderr.decode(kconf._encoding) - except UnicodeDecodeError as e: - _decoding_error(e, kconf.filename, kconf.linenr) - - if stderr: - kconf._warn("'{}' wrote to stderr: {}".format( - command, "\n".join(stderr.splitlines())), - kconf.filename, kconf.linenr) - - # Universal newlines with splitlines() (to prevent e.g. stray \r's in - # command output on Windows), trailing newline removal, and - # newline-to-space conversion. - # - # On Python 3 versions before 3.6, it's not possible to specify the - # encoding when passing universal_newlines=True to Popen() (the 'encoding' - # parameter was added in 3.6), so we do this manual version instead. - return "\n".join(stdout.splitlines()).rstrip("\n").replace("\n", " ") - -# -# Global constants -# - -TRI_TO_STR = { - 0: "n", - 1: "m", - 2: "y", -} - -STR_TO_TRI = { - "n": 0, - "m": 1, - "y": 2, -} - -# Constant representing that there's no cached choice selection. This is -# distinct from a cached None (no selection). Any object that's not None or a -# Symbol will do. We test this with 'is'. -_NO_CACHED_SELECTION = 0 - -# Are we running on Python 2? -_IS_PY2 = sys.version_info[0] < 3 - -try: - _UNAME_RELEASE = os.uname()[2] -except AttributeError: - # Only import as needed, to save some startup time - import platform - _UNAME_RELEASE = platform.uname()[2] - -# The token and type constants below are safe to test with 'is', which is a bit -# faster (~30% faster on my machine, and a few % faster for total parsing -# time), even without assuming Python's small integer optimization (which -# caches small integer objects). The constants end up pointing to unique -# integer objects, and since we consistently refer to them via the names below, -# we always get the same object. -# -# Client code should use == though. - -# Tokens, with values 1, 2, ... . Avoiding 0 simplifies some checks by making -# all tokens except empty strings truthy. -( - _T_ALLNOCONFIG_Y, - _T_AND, - _T_BOOL, - _T_CHOICE, - _T_CLOSE_PAREN, - _T_COMMENT, - _T_CONFIG, - _T_DEFAULT, - _T_DEFCONFIG_LIST, - _T_DEF_BOOL, - _T_DEF_HEX, - _T_DEF_INT, - _T_DEF_STRING, - _T_DEF_TRISTATE, - _T_DEPENDS, - _T_ENDCHOICE, - _T_ENDIF, - _T_ENDMENU, - _T_ENV, - _T_EQUAL, - _T_GREATER, - _T_GREATER_EQUAL, - _T_HELP, - _T_HEX, - _T_IF, - _T_IMPLY, - _T_INT, - _T_LESS, - _T_LESS_EQUAL, - _T_MAINMENU, - _T_MENU, - _T_MENUCONFIG, - _T_MODULES, - _T_NOT, - _T_ON, - _T_OPEN_PAREN, - _T_OPTION, - _T_OPTIONAL, - _T_OR, - _T_ORSOURCE, - _T_OSOURCE, - _T_PROMPT, - _T_RANGE, - _T_RSOURCE, - _T_SELECT, - _T_SOURCE, - _T_STRING, - _T_TRISTATE, - _T_UNEQUAL, - _T_VISIBLE, -) = range(1, 51) - -# Keyword to token map, with the get() method assigned directly as a small -# optimization -_get_keyword = { - "---help---": _T_HELP, - "allnoconfig_y": _T_ALLNOCONFIG_Y, - "bool": _T_BOOL, - "boolean": _T_BOOL, - "choice": _T_CHOICE, - "comment": _T_COMMENT, - "config": _T_CONFIG, - "def_bool": _T_DEF_BOOL, - "def_hex": _T_DEF_HEX, - "def_int": _T_DEF_INT, - "def_string": _T_DEF_STRING, - "def_tristate": _T_DEF_TRISTATE, - "default": _T_DEFAULT, - "defconfig_list": _T_DEFCONFIG_LIST, - "depends": _T_DEPENDS, - "endchoice": _T_ENDCHOICE, - "endif": _T_ENDIF, - "endmenu": _T_ENDMENU, - "env": _T_ENV, - "grsource": _T_ORSOURCE, # Backwards compatibility - "gsource": _T_OSOURCE, # Backwards compatibility - "help": _T_HELP, - "hex": _T_HEX, - "if": _T_IF, - "imply": _T_IMPLY, - "int": _T_INT, - "mainmenu": _T_MAINMENU, - "menu": _T_MENU, - "menuconfig": _T_MENUCONFIG, - "modules": _T_MODULES, - "on": _T_ON, - "option": _T_OPTION, - "optional": _T_OPTIONAL, - "orsource": _T_ORSOURCE, - "osource": _T_OSOURCE, - "prompt": _T_PROMPT, - "range": _T_RANGE, - "rsource": _T_RSOURCE, - "select": _T_SELECT, - "source": _T_SOURCE, - "string": _T_STRING, - "tristate": _T_TRISTATE, - "visible": _T_VISIBLE, -}.get - -# The constants below match the value of the corresponding tokens to remove the -# need for conversion - -# Node types -MENU = _T_MENU -COMMENT = _T_COMMENT - -# Expression types -AND = _T_AND -OR = _T_OR -NOT = _T_NOT -EQUAL = _T_EQUAL -UNEQUAL = _T_UNEQUAL -LESS = _T_LESS -LESS_EQUAL = _T_LESS_EQUAL -GREATER = _T_GREATER -GREATER_EQUAL = _T_GREATER_EQUAL - -REL_TO_STR = { - EQUAL: "=", - UNEQUAL: "!=", - LESS: "<", - LESS_EQUAL: "<=", - GREATER: ">", - GREATER_EQUAL: ">=", -} - -# Symbol/choice types. UNKNOWN is 0 (falsy) to simplify some checks. -# Client code shouldn't rely on it though, as it was non-zero in -# older versions. -UNKNOWN = 0 -BOOL = _T_BOOL -TRISTATE = _T_TRISTATE -STRING = _T_STRING -INT = _T_INT -HEX = _T_HEX - -TYPE_TO_STR = { - UNKNOWN: "unknown", - BOOL: "bool", - TRISTATE: "tristate", - STRING: "string", - INT: "int", - HEX: "hex", -} - -# Used in comparisons. 0 means the base is inferred from the format of the -# string. -_TYPE_TO_BASE = { - HEX: 16, - INT: 10, - STRING: 0, - UNKNOWN: 0, -} - -# def_bool -> BOOL, etc. -_DEF_TOKEN_TO_TYPE = { - _T_DEF_BOOL: BOOL, - _T_DEF_HEX: HEX, - _T_DEF_INT: INT, - _T_DEF_STRING: STRING, - _T_DEF_TRISTATE: TRISTATE, -} - -# Tokens after which strings are expected. This is used to tell strings from -# constant symbol references during tokenization, both of which are enclosed in -# quotes. -# -# Identifier-like lexemes ("missing quotes") are also treated as strings after -# these tokens. _T_CHOICE is included to avoid symbols being registered for -# named choices. -_STRING_LEX = frozenset({ - _T_BOOL, - _T_CHOICE, - _T_COMMENT, - _T_HEX, - _T_INT, - _T_MAINMENU, - _T_MENU, - _T_ORSOURCE, - _T_OSOURCE, - _T_PROMPT, - _T_RSOURCE, - _T_SOURCE, - _T_STRING, - _T_TRISTATE, -}) - -# Various sets for quick membership tests. Gives a single global lookup and -# avoids creating temporary dicts/tuples. - -_TYPE_TOKENS = frozenset({ - _T_BOOL, - _T_TRISTATE, - _T_INT, - _T_HEX, - _T_STRING, -}) - -_SOURCE_TOKENS = frozenset({ - _T_SOURCE, - _T_RSOURCE, - _T_OSOURCE, - _T_ORSOURCE, -}) - -_REL_SOURCE_TOKENS = frozenset({ - _T_RSOURCE, - _T_ORSOURCE, -}) - -# Obligatory (non-optional) sources -_OBL_SOURCE_TOKENS = frozenset({ - _T_SOURCE, - _T_RSOURCE, -}) - -_BOOL_TRISTATE = frozenset({ - BOOL, - TRISTATE, -}) - -_BOOL_TRISTATE_UNKNOWN = frozenset({ - BOOL, - TRISTATE, - UNKNOWN, -}) - -_INT_HEX = frozenset({ - INT, - HEX, -}) - -_SYMBOL_CHOICE = frozenset({ - Symbol, - Choice, -}) - -_MENU_COMMENT = frozenset({ - MENU, - COMMENT, -}) - -_EQUAL_UNEQUAL = frozenset({ - EQUAL, - UNEQUAL, -}) - -_RELATIONS = frozenset({ - EQUAL, - UNEQUAL, - LESS, - LESS_EQUAL, - GREATER, - GREATER_EQUAL, -}) - -# Helper functions for getting compiled regular expressions, with the needed -# matching function returned directly as a small optimization. -# -# Use ASCII regex matching on Python 3. It's already the default on Python 2. - - -def _re_match(regex): - return re.compile(regex, 0 if _IS_PY2 else re.ASCII).match - - -def _re_search(regex): - return re.compile(regex, 0 if _IS_PY2 else re.ASCII).search - - -# Various regular expressions used during parsing - -# The initial token on a line. Also eats leading and trailing whitespace, so -# that we can jump straight to the next token (or to the end of the line if -# there is only one token). -# -# This regex will also fail to match for empty lines and comment lines. -# -# '$' is included to detect preprocessor variable assignments with macro -# expansions in the left-hand side. -_command_match = _re_match(r"\s*([A-Za-z0-9_$-]+)\s*") - -# An identifier/keyword after the first token. Also eats trailing whitespace. -# '$' is included to detect identifiers containing macro expansions. -_id_keyword_match = _re_match(r"([A-Za-z0-9_$/.-]+)\s*") - -# A fragment in the left-hand side of a preprocessor variable assignment. These -# are the portions between macro expansions ($(foo)). Macros are supported in -# the LHS (variable name). -_assignment_lhs_fragment_match = _re_match("[A-Za-z0-9_-]*") - -# The assignment operator and value (right-hand side) in a preprocessor -# variable assignment -_assignment_rhs_match = _re_match(r"\s*(=|:=|\+=)\s*(.*)") - -# Special characters/strings while expanding a macro ('(', ')', ',', and '$(') -_macro_special_search = _re_search(r"\(|\)|,|\$\(") - -# Special characters/strings while expanding a string (quotes, '\', and '$(') -_string_special_search = _re_search(r'"|\'|\\|\$\(') - -# Special characters/strings while expanding a symbol name. Also includes -# end-of-line, in case the macro is the last thing on the line. -_name_special_search = _re_search(r'[^A-Za-z0-9_$/.-]|\$\(|$') - -# A valid right-hand side for an assignment to a string symbol in a .config -# file, including escaped characters. Extracts the contents. -_conf_string_match = _re_match(r'"((?:[^\\"]|\\.)*)"') diff --git a/util/lbcc.c b/util/lbcc.c index 4a3633153e..2429400cad 100644 --- a/util/lbcc.c +++ b/util/lbcc.c @@ -1,5 +1,5 @@ /* - * Copyright 2014 The Chromium OS Authors. All rights reserved. + * Copyright 2014 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -31,10 +31,10 @@ static const char usage[] = /* globals */ static int hit_errors; static int opt_verbose; -static int is_jump_target[EC_LB_PROG_LEN]; /* does program jump here? */ -static int is_instruction[EC_LB_PROG_LEN]; /* instruction or operand? */ -static char *label[EC_LB_PROG_LEN]; /* labels we've seen */ -static char *reloc_label[EC_LB_PROG_LEN]; /* put label target here */ +static int is_jump_target[EC_LB_PROG_LEN]; /* does program jump here? */ +static int is_instruction[EC_LB_PROG_LEN]; /* instruction or operand? */ +static char *label[EC_LB_PROG_LEN]; /* labels we've seen */ +static char *reloc_label[EC_LB_PROG_LEN]; /* put label target here */ static void Error(const char *format, ...) { @@ -66,32 +66,21 @@ struct safe_lightbar_program { #define OP(NAME, BYTES, MNEMONIC) NAME, #include "lightbar_opcode_list.h" -enum lightbyte_opcode { - LIGHTBAR_OPCODE_TABLE - MAX_OPCODE -}; +enum lightbyte_opcode { LIGHTBAR_OPCODE_TABLE MAX_OPCODE }; #undef OP #define OP(NAME, BYTES, MNEMONIC) BYTES, #include "lightbar_opcode_list.h" -static const int num_operands[] = { - LIGHTBAR_OPCODE_TABLE -}; +static const int num_operands[] = { LIGHTBAR_OPCODE_TABLE }; #undef OP #define OP(NAME, BYTES, MNEMONIC) MNEMONIC, #include "lightbar_opcode_list.h" -static const char * const opcode_sym[] = { - LIGHTBAR_OPCODE_TABLE -}; +static const char *const opcode_sym[] = { LIGHTBAR_OPCODE_TABLE }; #undef OP -static const char * const control_sym[] = { - "beg", "end", "phase", "<invalid>" -}; -static const char * const color_sym[] = { - "r", "g", "b", "<invalid>" -}; +static const char *const control_sym[] = { "beg", "end", "phase", "<invalid>" }; +static const char *const color_sym[] = { "r", "g", "b", "<invalid>" }; static void read_binary(FILE *fp, struct safe_lightbar_program *prog) { @@ -232,7 +221,8 @@ static void set_jump_target(uint8_t targ) { if (targ >= EC_LB_PROG_LEN) { Warning("program jumps to 0x%02x, " - "which out of bounds\n", targ); + "which out of bounds\n", + targ); return; } is_jump_target[targ] = 1; @@ -266,7 +256,8 @@ static void disassemble_prog(FILE *fp, struct safe_lightbar_program *prog) for (i = 0; i < EC_LB_PROG_LEN; i++) if (is_jump_target[i] && !is_instruction[i]) { Warning("program jumps to 0x%02x, " - "which is not a valid instruction\n", i); + "which is not a valid instruction\n", + i); } } @@ -295,7 +286,6 @@ static int split_line(char *buf, const char *delim, struct parse_s *elt, elt[i].val = (uint32_t)strtoull(w, &e, 0); if (!e || !*e) elt[i].is_num = 1; - } return i; @@ -377,7 +367,6 @@ static int is_color_arg(char *buf, int expected, uint32_t *valp) } else color = 0; - *valp = ((led & 0xF) << 4) | ((control & 0x3) << 2) | (color & 0x3); return 1; } @@ -390,8 +379,8 @@ static void fixup_symbols(struct safe_lightbar_program *prog) if (reloc_label[i]) { /* Looking for reloc label */ for (j = 0; j < EC_LB_PROG_LEN; j++) { - if (label[j] && !strcmp(label[j], - reloc_label[i])) { + if (label[j] && + !strcmp(label[j], reloc_label[i])) { prog->p.data[i] = j; break; } @@ -402,7 +391,6 @@ static void fixup_symbols(struct safe_lightbar_program *prog) } } - static void compile(FILE *fp, struct safe_lightbar_program *prog) { char buf[128]; @@ -415,7 +403,6 @@ static void compile(FILE *fp, struct safe_lightbar_program *prog) int i; while (fgets(buf, sizeof(buf), fp)) { - /* We truncate lines that are too long */ s = strchr(buf, '\n'); if (chopping) { @@ -458,7 +445,8 @@ static void compile(FILE *fp, struct safe_lightbar_program *prog) if (opcode >= MAX_OPCODE) { Error("Unrecognized opcode \"%s\"" - " at line %d\n", token[wnum].word, line); + " at line %d\n", + token[wnum].word, line); continue; } @@ -488,7 +476,8 @@ static void compile(FILE *fp, struct safe_lightbar_program *prog) reloc_label[addr++] = strdup(token[wnum].word); else { Error("Missing first jump target " - "at line %d\n", line); + "at line %d\n", + line); break; } wnum++; @@ -496,7 +485,8 @@ static void compile(FILE *fp, struct safe_lightbar_program *prog) reloc_label[addr++] = strdup(token[wnum].word); else Error("Missing second jump target " - "at line %d\n", line); + "at line %d\n", + line); break; case SET_BRIGHTNESS: @@ -511,14 +501,13 @@ static void compile(FILE *fp, struct safe_lightbar_program *prog) case SET_RAMP_DELAY: /* one 32-bit arg */ if (token[wnum].is_num) { - prog->p.data[addr++] = - (token[wnum].val >> 24) & 0xff; - prog->p.data[addr++] = - (token[wnum].val >> 16) & 0xff; - prog->p.data[addr++] = - (token[wnum].val >> 8) & 0xff; - prog->p.data[addr++] = - token[wnum].val & 0xff; + prog->p.data[addr++] = (token[wnum].val >> 24) & + 0xff; + prog->p.data[addr++] = (token[wnum].val >> 16) & + 0xff; + prog->p.data[addr++] = (token[wnum].val >> 8) & + 0xff; + prog->p.data[addr++] = token[wnum].val & 0xff; } else { Error("Missing/invalid arg at line %d\n", line); } @@ -535,11 +524,11 @@ static void compile(FILE *fp, struct safe_lightbar_program *prog) prog->p.data[addr++] = token[wnum++].val; /* and the color immediate */ if (token[wnum].is_num) { - prog->p.data[addr++] = - token[wnum++].val; + prog->p.data[addr++] = token[wnum++].val; } else { Error("Missing/Invalid arg " - "at line %d\n", line); + "at line %d\n", + line); break; } break; @@ -559,7 +548,8 @@ static void compile(FILE *fp, struct safe_lightbar_program *prog) token[wnum++].val; } else { Error("Missing/Invalid arg " - "at line %d\n", line); + "at line %d\n", + line); break; } } @@ -604,7 +594,7 @@ int main(int argc, char *argv[]) else progname = argv[0]; - opterr = 0; /* quiet, you */ + opterr = 0; /* quiet, you */ while ((c = getopt(argc, argv, ":dv")) != -1) { switch (c) { case 'd': @@ -676,8 +666,8 @@ int main(int argc, char *argv[]) compile(ifp, &safe_prog); fclose(ifp); if (!hit_errors) { - if (1 != fwrite(safe_prog.p.data, - safe_prog.p.size, 1, ofp)) + if (1 != + fwrite(safe_prog.p.data, safe_prog.p.size, 1, ofp)) Error("%s: Unable to write to %s: %s\n", progname, outfile, strerror(errno)); else diff --git a/util/lbplay.c b/util/lbplay.c index 9ab0564b74..8c02903175 100644 --- a/util/lbplay.c +++ b/util/lbplay.c @@ -1,4 +1,4 @@ -/* Copyright 2014 The Chromium OS Authors. All rights reserved. +/* Copyright 2014 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -126,11 +126,8 @@ int main(int argc, char **argv) * to see what the limit is. The default is 50msec (20Hz). */ for (i = 0; i < 256; i += 4) { - sprintf(buf, "0 %d %d %d 1 %d %d %d 2 %d %d %d 3 %d %d %d", - i, 0, 0, - 0, 0, i, - 255-i, 255, 0, - 0, 255, 255-i); + sprintf(buf, "0 %d %d %d 1 %d %d %d 2 %d %d %d 3 %d %d %d", i, + 0, 0, 0, 0, i, 255 - i, 255, 0, 0, 255, 255 - i); lseek(fd_l, 0, SEEK_SET); if (write(fd_l, buf, strlen(buf) + 1) < 0) perror("write to led control"); diff --git a/util/linux_ec_commands_h_check.sh b/util/linux_ec_commands_h_check.sh index 4c55faca0a..d24beb9b54 100755 --- a/util/linux_ec_commands_h_check.sh +++ b/util/linux_ec_commands_h_check.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2019 The Chromium OS Authors. All rights reserved. +# Copyright 2019 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/util/llvm-gcov.sh b/util/llvm-gcov.sh index 7c1c97a7d5..826a901134 100755 --- a/util/llvm-gcov.sh +++ b/util/llvm-gcov.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Copyright 2021 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/util/lock/android.c b/util/lock/android.c index 8472b6db68..857d6a9473 100644 --- a/util/lock/android.c +++ b/util/lock/android.c @@ -1,6 +1,5 @@ /* - * Copyright 2016, Google Inc. - * All rights reserved. + * Copyright 2016 Google LLC * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -12,7 +11,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. - * * Neither the name of Google Inc. nor the names of its + * * Neither the name of Google LLC nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * diff --git a/util/lock/android.h b/util/lock/android.h index bb08486919..dfdd16ce97 100644 --- a/util/lock/android.h +++ b/util/lock/android.h @@ -1,6 +1,5 @@ /* - * Copyright 2016, Google Inc. - * All rights reserved. + * Copyright 2016 Google LLC * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -12,7 +11,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. - * * Neither the name of Google Inc. nor the names of its + * * Neither the name of Google LLC nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * diff --git a/util/lock/build.mk b/util/lock/build.mk index 65a63ab9db..ea9bf9bf04 100644 --- a/util/lock/build.mk +++ b/util/lock/build.mk @@ -1,5 +1,5 @@ # -*- makefile -*- -# Copyright 2012 The Chromium OS Authors. All rights reserved. +# Copyright 2012 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # diff --git a/util/lock/file_lock.c b/util/lock/file_lock.c index 36b420d287..c0ed8bd88c 100644 --- a/util/lock/file_lock.c +++ b/util/lock/file_lock.c @@ -1,5 +1,4 @@ -/* Copyright 2016, Google Inc. - * All rights reserved. +/* Copyright 2016 Google LLC * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -11,7 +10,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. - * * Neither the name of Google Inc. nor the names of its + * * Neither the name of Google LLC nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -59,7 +58,7 @@ #include "ipc_lock.h" #include "locks.h" -#define SLEEP_INTERVAL_MS 50 +#define SLEEP_INTERVAL_MS 50 static void msecs_to_timespec(int msecs, struct timespec *tmspec) { @@ -100,8 +99,8 @@ static int file_lock_open_or_create(struct ipc_lock *lock) if (!tmpdir) return -1; - if (snprintf(path, sizeof(path), "%s/%s", - tmpdir, lock->filename) < 0) { + if (snprintf(path, sizeof(path), "%s/%s", tmpdir, + lock->filename) < 0) { return -1; } } else { @@ -115,10 +114,9 @@ static int file_lock_open_or_create(struct ipc_lock *lock) return -1; } - if (snprintf(path, sizeof(path), - "%s/%s", dir, lock->filename) < 0) + if (snprintf(path, sizeof(path), "%s/%s", dir, lock->filename) < + 0) return -1; - } lock->fd = open(path, O_RDWR | O_CREAT, 0600); @@ -180,9 +178,9 @@ static int file_lock_write_pid(struct ipc_lock *lock) { ssize_t len; /* - * PIDs are usually 5 digits, but we'll reserve enough room for + * PIDs are usually 5 digits, but we'll reserve enough room for * a value of 2^32 (10 digits) out of paranoia. - */ + */ char pid_str[11]; if (ftruncate(lock->fd, 0) < 0) { diff --git a/util/lock/gec_lock.c b/util/lock/gec_lock.c index d354ea08f3..64aad0f353 100644 --- a/util/lock/gec_lock.c +++ b/util/lock/gec_lock.c @@ -1,5 +1,4 @@ -/* Copyright 2012, Google Inc. - * All rights reserved. +/* Copyright 2012 Google LLC * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -11,7 +10,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. - * * Neither the name of Google Inc. nor the names of its + * * Neither the name of Google LLC nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * diff --git a/util/lock/gec_lock.h b/util/lock/gec_lock.h index 8480700ddd..2e0d8018bc 100644 --- a/util/lock/gec_lock.h +++ b/util/lock/gec_lock.h @@ -1,5 +1,4 @@ -/* Copyright 2012, Google Inc. - * All rights reserved. +/* Copyright 2012 Google LLC * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -11,7 +10,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. - * * Neither the name of Google Inc. nor the names of its + * * Neither the name of Google LLC nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * diff --git a/util/lock/ipc_lock.h b/util/lock/ipc_lock.h index 5d0d321af4..aaa4217ae8 100644 --- a/util/lock/ipc_lock.h +++ b/util/lock/ipc_lock.h @@ -1,5 +1,4 @@ -/* Copyright 2012, Google Inc. - * All rights reserved. +/* Copyright 2012 Google LLC * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -11,7 +10,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. - * * Neither the name of Google Inc. nor the names of its + * * Neither the name of Google LLC nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -32,17 +31,17 @@ #define __UTIL_IPC_LOCK_H struct ipc_lock { - int is_held; /* internal */ - const char *filename; /* provided by the developer */ - int fd; /* internal */ + int is_held; /* internal */ + const char *filename; /* provided by the developer */ + int fd; /* internal */ }; /* don't use C99 initializers here, so this can be used in C++ code */ -#define LOCKFILE_INIT(lockfile) \ - { \ - 0, /* is_held */ \ - lockfile, /* filename */ \ - -1, /* fd */ \ +#define LOCKFILE_INIT(lockfile) \ + { \ + 0, /* is_held */ \ + lockfile, /* filename */ \ + -1, /* fd */ \ } /* diff --git a/util/lock/locks.h b/util/lock/locks.h index 6875d91454..9e470b5f7e 100644 --- a/util/lock/locks.h +++ b/util/lock/locks.h @@ -1,5 +1,4 @@ -/* Copyright 2012, Google Inc. - * All rights reserved. +/* Copyright 2012 Google LLC * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -11,7 +10,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. - * * Neither the name of Google Inc. nor the names of its + * * Neither the name of Google LLC nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -31,8 +30,8 @@ #ifndef __UTIL_LOCKS_H #define __UTIL_LOCKS_H -#define SYSTEM_LOCKFILE_DIR "/run/lock" -#define LOCKFILE_NAME "firmware_utility_lock" -#define CROS_EC_LOCKFILE_NAME "cros_ec_lock" +#define SYSTEM_LOCKFILE_DIR "/run/lock" +#define LOCKFILE_NAME "firmware_utility_lock" +#define CROS_EC_LOCKFILE_NAME "cros_ec_lock" #endif /* __UTIL_LOCKS_H */ diff --git a/util/make_linux_ec_commands_h.sh b/util/make_linux_ec_commands_h.sh index 3afb7c2f41..141a5086de 100755 --- a/util/make_linux_ec_commands_h.sh +++ b/util/make_linux_ec_commands_h.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2019 The Chromium OS Authors. All rights reserved. +# Copyright 2019 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -47,14 +47,14 @@ trap cleanup EXIT # Replace license patch "${tmp}" << EOF @@ -1,6 +1,11 @@ --/* Copyright 2014 The Chromium OS Authors. All rights reserved. +-/* Copyright 2014 The ChromiumOS Authors - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Host communication command constants for ChromeOS EC + * -+ * Copyright (C) 2012 Google, Inc ++ * Copyright 2012 Google, Inc + * + * NOTE: This file is auto-generated from ChromeOS EC Open Source code from + * https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/include/ec_commands.h diff --git a/util/migrated_files.sh b/util/migrated_files.sh index 8ed549b6c5..cec86b565b 100755 --- a/util/migrated_files.sh +++ b/util/migrated_files.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2022 The Chromium OS Authors. All rights reserved. +# Copyright 2022 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -12,7 +12,7 @@ exit_code=0 for file in "$@"; do ec_file="${file##**/platform/ec/}" case "${ec_file}" in - baseboard/*|board/*|chip/*|common/fpsensor/*|test/*|util/*|zephyr/*) ;; + baseboard/*|board/*|chip/*|*fpsensor*|test/*|util/*|zephyr/*) ;; **.c) if ! grep -q -F "\${PLATFORM_EC}/${ec_file}" "${cmakes[@]}" ; then echo -n "WARNING: ${ec_file} is not used in Zephyr EC. Do not edit this" diff --git a/util/misc_util.c b/util/misc_util.c index 1eb6577dbb..29b346f534 100644 --- a/util/misc_util.c +++ b/util/misc_util.c @@ -1,4 +1,4 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. +/* Copyright 2013 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ diff --git a/util/misc_util.h b/util/misc_util.h index 240d735556..d514a2516e 100644 --- a/util/misc_util.h +++ b/util/misc_util.h @@ -1,4 +1,4 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. +/* Copyright 2013 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -7,8 +7,14 @@ #define __UTIL_MISC_UTIL_H /* Don't use a macro where an inline will do... */ -static inline int MIN(int a, int b) { return a < b ? a : b; } -static inline int MAX(int a, int b) { return a > b ? a : b; } +static inline int MIN(int a, int b) +{ + return a < b ? a : b; +} +static inline int MAX(int a, int b) +{ + return a > b ? a : b; +} /** * Write a buffer to the file. diff --git a/util/openocd/board/skyrim.cfg b/util/openocd/board/skyrim.cfg index a8047ade22..11f31c22ef 100644 --- a/util/openocd/board/skyrim.cfg +++ b/util/openocd/board/skyrim.cfg @@ -1,4 +1,4 @@ -# Copyright 2022 The Chromium OS Authors. All rights reserved. +# Copyright 2022 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/util/openocd/npcx.cfg b/util/openocd/npcx.cfg index 0ab2b42888..888ebafcec 100644 --- a/util/openocd/npcx.cfg +++ b/util/openocd/npcx.cfg @@ -1,4 +1,4 @@ -# Copyright 2014 The Chromium OS Authors. All rights reserved. +# Copyright 2014 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # diff --git a/util/openocd/npcx_cmds.tcl b/util/openocd/npcx_cmds.tcl index 759e897131..fb7f634bff 100644 --- a/util/openocd/npcx_cmds.tcl +++ b/util/openocd/npcx_cmds.tcl @@ -1,4 +1,4 @@ -# Copyright 2014 The Chromium OS Authors. All rights reserved. +# Copyright 2014 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # diff --git a/util/openocd/target/npcx993f.cfg b/util/openocd/target/npcx993f.cfg index 690bee489d..b9c7c4e43d 100644 --- a/util/openocd/target/npcx993f.cfg +++ b/util/openocd/target/npcx993f.cfg @@ -1,4 +1,4 @@ -# Copyright 2022 The Chromium OS Authors. All rights reserved. +# Copyright 2022 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/util/openocd/target/npcx99nf.cfg b/util/openocd/target/npcx99nf.cfg index 14dbac9f13..8d0828c4c1 100644 --- a/util/openocd/target/npcx99nf.cfg +++ b/util/openocd/target/npcx99nf.cfg @@ -1,4 +1,4 @@ -# Copyright 2022 The Chromium OS Authors. All rights reserved. +# Copyright 2022 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/util/pinmap/chips/it81302.go b/util/pinmap/chips/it81302.go index 6e593a2c5e..058ac9a03b 100644 --- a/util/pinmap/chips/it81302.go +++ b/util/pinmap/chips/it81302.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/util/pinmap/chips/npcx993.go b/util/pinmap/chips/npcx993.go index 7a865c115d..720cd99fb6 100644 --- a/util/pinmap/chips/npcx993.go +++ b/util/pinmap/chips/npcx993.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/util/pinmap/chips/npcx993_test.go b/util/pinmap/chips/npcx993_test.go index 6ed4bf2357..a3910416a2 100644 --- a/util/pinmap/chips/npcx993_test.go +++ b/util/pinmap/chips/npcx993_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/util/pinmap/chips/register.go b/util/pinmap/chips/register.go index 96b655814e..ff6d047140 100644 --- a/util/pinmap/chips/register.go +++ b/util/pinmap/chips/register.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/util/pinmap/pinmap/main.go b/util/pinmap/pinmap/main.go index 8b1f1f38f6..1576bac0dd 100644 --- a/util/pinmap/pinmap/main.go +++ b/util/pinmap/pinmap/main.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/util/pinmap/pm/chip.go b/util/pinmap/pm/chip.go index a940e7c5fe..9175647c9c 100644 --- a/util/pinmap/pm/chip.go +++ b/util/pinmap/pm/chip.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/util/pinmap/pm/chip_test.go b/util/pinmap/pm/chip_test.go index 0bfe601093..1606646588 100644 --- a/util/pinmap/pm/chip_test.go +++ b/util/pinmap/pm/chip_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/util/pinmap/pm/generate.go b/util/pinmap/pm/generate.go index 835206ad7b..629aeaee15 100644 --- a/util/pinmap/pm/generate.go +++ b/util/pinmap/pm/generate.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -17,7 +17,7 @@ type lineName struct { name string // Pin name } -const header = `/* Copyright %d The Chromium OS Authors. All rights reserved. +const header = `/* Copyright %d The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -87,7 +87,6 @@ func adcConfig(out io.Writer, pin *Pin, chip Chip) { } lc := strings.ToLower(pin.Signal) fmt.Fprintf(out, "\t\tadc_%s: %s {\n", lc, lc) - fmt.Fprintf(out, "\t\t\tlabel = \"%s\";\n", pin.Signal) if len(pin.Enum) > 0 { fmt.Fprintf(out, "\t\t\tenum-name = \"%s\";\n", pin.Enum) } @@ -153,7 +152,7 @@ func i2cConfig(out io.Writer, pin *Pin, chip Chip) { fmt.Fprintf(out, "\t\ti2c_%s: %s {\n", lc, lc) fmt.Fprintf(out, "\t\t\ti2c-port = <&%s>;\n", c) if len(pin.Enum) > 0 { - fmt.Fprintf(out, "\t\t\tenum-name = \"%s\";\n", pin.Enum) + fmt.Fprintf(out, "\t\t\tenum-names = \"%s\";\n", pin.Enum) } fmt.Fprintf(out, "\t\t};\n") } @@ -193,7 +192,7 @@ func generateEnabledNodes(out io.Writer, nodes []string) { func generateLineNames(out io.Writer, gpios map[string][]lineName) { // Sort the GPIO controller names. var gcList []string - for gc, _ := range gpios { + for gc := range gpios { gcList = append(gcList, gc) } sort.Strings(gcList) diff --git a/util/pinmap/pm/generate_test.go b/util/pinmap/pm/generate_test.go index 3903180b1b..3ecdb7d1c2 100644 --- a/util/pinmap/pm/generate_test.go +++ b/util/pinmap/pm/generate_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -72,7 +72,7 @@ func TestGenerate(t *testing.T) { * However this would considerably complicate this test. */ expFmt := - `/* Copyright %d The Chromium OS Authors. All rights reserved. + `/* Copyright %d The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -85,7 +85,6 @@ func TestGenerate(t *testing.T) { compatible = "named-adc-channels"; adc_ec_adc_1: ec_adc_1 { - label = "EC_ADC_1"; enum-name = "ENUM_ADC_1"; io-channels = <&adc0 A1>; }; @@ -117,15 +116,15 @@ func TestGenerate(t *testing.T) { i2c_ec_c_i2c_clk: ec_c_i2c_clk { i2c-port = <&i2c0>; - enum-name = "ENUM_I2C_0"; + enum-names = "ENUM_I2C_0"; }; i2c_ec_b_i2c_clk: ec_b_i2c_clk { i2c-port = <&i2c1>; - enum-name = "ENUM_I2C_1"; + enum-names = "ENUM_I2C_1"; }; i2c_ec_a_i2c_clk: ec_a_i2c_clk { i2c-port = <&i2c2>; - enum-name = "ENUM_I2C_2"; + enum-names = "ENUM_I2C_2"; }; }; }; diff --git a/util/pinmap/pm/pins.go b/util/pinmap/pm/pins.go index cb749eb166..61cd7cc043 100644 --- a/util/pinmap/pm/pins.go +++ b/util/pinmap/pm/pins.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/util/pinmap/pm/reader.go b/util/pinmap/pm/reader.go index 08dbb9e3af..4af8e29ed9 100644 --- a/util/pinmap/pm/reader.go +++ b/util/pinmap/pm/reader.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/util/pinmap/pm/reader_test.go b/util/pinmap/pm/reader_test.go index 5eabf67490..ca004eab6a 100644 --- a/util/pinmap/pm/reader_test.go +++ b/util/pinmap/pm/reader_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/util/pinmap/readers/csv/csv.go b/util/pinmap/readers/csv/csv.go index 562b5c6383..df763561bb 100644 --- a/util/pinmap/readers/csv/csv.go +++ b/util/pinmap/readers/csv/csv.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/util/pinmap/readers/csv/csv_test.go b/util/pinmap/readers/csv/csv_test.go index c0a79ba784..e1140ccb75 100644 --- a/util/pinmap/readers/csv/csv_test.go +++ b/util/pinmap/readers/csv/csv_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/util/pinmap/readers/csv/register.go b/util/pinmap/readers/csv/register.go index b2f2529061..7ccb18e78a 100644 --- a/util/pinmap/readers/csv/register.go +++ b/util/pinmap/readers/csv/register.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2021 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/util/powerd_lock.c b/util/powerd_lock.c index 524b456df2..4fdc799203 100644 --- a/util/powerd_lock.c +++ b/util/powerd_lock.c @@ -1,7 +1,7 @@ /* * This file is ported from the flashrom project. * - * Copyright 2015 The Chromium OS Authors. All rights reserved. + * Copyright 2015 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * diff --git a/util/powerd_lock.h b/util/powerd_lock.h index 86be184a19..1487f28bb7 100644 --- a/util/powerd_lock.h +++ b/util/powerd_lock.h @@ -1,7 +1,7 @@ /* * This file is ported from the flashrom project. * - * Copyright 2015 The Chromium OS Authors. All rights reserved. + * Copyright 2015 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -27,8 +27,8 @@ enum POWERD_ERROR_CODE { POWERD_OK = 0, POWERD_CREATE_LOCK_FILE_ERROR = 0x1, - POWERD_WRITE_LOCK_FILE_ERROR = 0x2, - POWERD_CLOSE_LOCK_FILE_ERROR = 0x4, + POWERD_WRITE_LOCK_FILE_ERROR = 0x2, + POWERD_CLOSE_LOCK_FILE_ERROR = 0x4, POWERD_DELETE_LOCK_FILE_ERROR = 0x8 }; @@ -38,4 +38,4 @@ int disable_power_management(void); /* Re-enable power management. */ int restore_power_management(void); -#endif /* __UTIL_POWERD_LOCK_H */ +#endif /* __UTIL_POWERD_LOCK_H */ diff --git a/util/presubmit_check.sh b/util/presubmit_check.sh index 7d46f38a0f..5cec68ddd4 100755 --- a/util/presubmit_check.sh +++ b/util/presubmit_check.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2014 The Chromium OS Authors. All rights reserved. +# Copyright 2014 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/util/run_ects.py b/util/run_ects.py index 9178328e5f..a3bf4d295c 100644 --- a/util/run_ects.py +++ b/util/run_ects.py @@ -1,10 +1,6 @@ -# Copyright 2017 The Chromium OS Authors. All rights reserved. +# Copyright 2017 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -# -# Ignore indention messages, since legacy scripts use 2 spaces instead of 4. -# pylint: disable=bad-indentation,docstring-section-indent -# pylint: disable=docstring-trailing-quotes """Run all eCTS tests and publish results.""" @@ -16,81 +12,84 @@ import subprocess import sys # List of tests to run. -TESTS = ['meta', 'gpio', 'hook', 'i2c', 'interrupt', 'mutex', 'task', 'timer'] +TESTS = ["meta", "gpio", "hook", "i2c", "interrupt", "mutex", "task", "timer"] class CtsRunner(object): - """Class running eCTS tests.""" - - def __init__(self, ec_dir, dryrun): - self.ec_dir = ec_dir - self.cts_py = [] - if dryrun: - self.cts_py += ['echo'] - self.cts_py += [os.path.join(ec_dir, 'cts/cts.py')] - - def run_cmd(self, cmd): - try: - rc = subprocess.call(cmd) - if rc != 0: - return False - except OSError: - return False - return True - - def run_test(self, test): - cmd = self.cts_py + ['-m', test] - self.run_cmd(cmd) - - def run(self, tests): - for test in tests: - logging.info('Running', test, 'test.') - self.run_test(test) - - def sync(self): - logging.info('Syncing tree...') - os.chdir(self.ec_dir) - cmd = ['repo', 'sync', '.'] - return self.run_cmd(cmd) - - def upload(self): - logging.info('Uploading results...') + """Class running eCTS tests.""" + + def __init__(self, ec_dir, dryrun): + self.ec_dir = ec_dir + self.cts_py = [] + if dryrun: + self.cts_py += ["echo"] + self.cts_py += [os.path.join(ec_dir, "cts/cts.py")] + + def run_cmd(self, cmd): + try: + rc = subprocess.call(cmd) + if rc != 0: + return False + except OSError: + return False + return True + + def run_test(self, test): + cmd = self.cts_py + ["-m", test] + self.run_cmd(cmd) + + def run(self, tests): + for test in tests: + logging.info("Running %s test.", test) + self.run_test(test) + + def sync(self): + logging.info("Syncing tree...") + os.chdir(self.ec_dir) + cmd = ["repo", "sync", "."] + return self.run_cmd(cmd) + + def upload(self): + logging.info("Uploading results...") def main(): - if not os.path.exists('/etc/cros_chroot_version'): - logging.error('This script has to run inside chroot.') - sys.exit(-1) - - ec_dir = os.path.realpath(os.path.dirname(__file__) + '/..') - - parser = argparse.ArgumentParser(description='Run eCTS and report results.') - parser.add_argument('-d', - '--dryrun', - action='store_true', - help='Echo commands to be executed without running them.') - parser.add_argument('-s', - '--sync', - action='store_true', - help='Sync tree before running tests.') - parser.add_argument('-u', - '--upload', - action='store_true', - help='Upload test results.') - args = parser.parse_args() - - runner = CtsRunner(ec_dir, args.dryrun) - - if args.sync: - if not runner.sync(): - logging.error('Failed to sync.') - sys.exit(-1) - - runner.run(TESTS) - - if args.upload: - runner.upload() - - -if __name__ == '__main__': - main() + if not os.path.exists("/etc/cros_chroot_version"): + logging.error("This script has to run inside chroot.") + sys.exit(-1) + + ec_dir = os.path.realpath(os.path.dirname(__file__) + "/..") + + parser = argparse.ArgumentParser(description="Run eCTS and report results.") + parser.add_argument( + "-d", + "--dryrun", + action="store_true", + help="Echo commands to be executed without running them.", + ) + parser.add_argument( + "-s", + "--sync", + action="store_true", + help="Sync tree before running tests.", + ) + parser.add_argument( + "-u", "--upload", action="store_true", help="Upload test results." + ) + args = parser.parse_args() + + runner = CtsRunner(ec_dir, args.dryrun) + + if args.sync: + if not runner.sync(): + logging.error("Failed to sync.") + sys.exit(-1) + + runner.run(TESTS) + + if args.upload: + runner.upload() + + +if __name__ == "__main__": + main() diff --git a/util/run_host_test b/util/run_host_test index cee969dd8c..3108da1852 100755 --- a/util/run_host_test +++ b/util/run_host_test @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# Copyright 2020 The Chromium OS Authors. All rights reserved. +# Copyright 2020 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/util/run_tests.sh b/util/run_tests.sh new file mode 100755 index 0000000000..f8af2dc681 --- /dev/null +++ b/util/run_tests.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Runs all the unit tests in the util dir. Uses relative paths, so don't run +# from any ebuild. + +# Show commands being run. +set -x + +# Exit if any command exits non-zero. +set -e + +# cd to the ec directory. +cd "$(dirname "$(realpath -e "${BASH_SOURCE[0]}")")"/.. + +# Run pytest +pytest util "$@" + +# Run shell tests +cd util +./test-inject-keys.sh diff --git a/util/shuffle_test.sh b/util/shuffle_test.sh new file mode 100755 index 0000000000..dfbc1b7a15 --- /dev/null +++ b/util/shuffle_test.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +set +x + +if [ $# -ne 2 ]; then + echo "Usage: $0 <target> <error regex>" + exit 1 +fi + +target=$1 +pattern=$2 + +zmake build --clobber "${target}" || exit 1 + +echo "Searching for '${pattern}'..." +found_errors=0 +loop_count=100 +start_time=$(date +%Y-%m-%d_%H.%M.%S) +log_dir="/tmp" +EXECUTABLE=./build/zephyr/${target}/build-singleimage/zephyr/zephyr.exe +while [ "${loop_count}" -gt 0 ]; do + seed=${RANDOM} + log_file_prefix="${log_dir}"/shuffle_"${start_time}"_"${seed}" + + echo "[$((100 - loop_count))] Using seed=${seed}" + error_count=$(timeout 150s "${EXECUTABLE}" -seed="${seed}" 2>&1 | + tee "${log_file_prefix}".log | + grep -c "${pattern}") + status=$? + + result="0-matches" + if [ "${status}" -eq 124 ]; then + echo " Timeout" + result="timed-out" + elif [ "${status}" -eq 0 ]; then + echo " Error/timeout" + result="exit-code-${status}" + fi + if [ "${error_count}" -gt 0 ]; then + echo " Found ${error_count} errors matching '${pattern}'" + result="${error_count}-matches" + fi + + # Rename the log file to include the outcome + mv \ + "${log_file_prefix}".log \ + "${log_file_prefix}"_"${result}".log + + found_errors=$((found_errors + error_count)) + loop_count=$((loop_count - 1)) +done + +if [ "${found_errors}" -ne 0 ]; then + exit 1 +fi diff --git a/util/sort_by_unconvered.py b/util/sort_by_unconvered.py new file mode 100755 index 0000000000..217c613aaa --- /dev/null +++ b/util/sort_by_unconvered.py @@ -0,0 +1,59 @@ +#!/usr/bin/python3 +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Prints out the lines in an lcov info file in order by uncovered lines. + +For example to find the file with the most uncovered lines in herobrine (and +therefore the likest easy win) run the coverage commands in zephyr/README.md +and then run: + +util/sort_by_unconvered.py build/zephyr/herobrine_final.info | head +""" + +import argparse +import re +import subprocess + + +def main(): + """Main function""" + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument( + "lcov_files", + nargs="+", + metavar="lcov_file", + help="Name(s) of the lcov files to analyze", + default=[], + ) + args = parser.parse_args() + + cmd = ["lcov", "--list-full-path", "--list"] + args.lcov_files + output = subprocess.run( + cmd, check=True, stdout=subprocess.PIPE, universal_newlines=True + ).stdout + + pattern = re.compile(r"^(/\S+)\s*\|\s*([0-9\.]*)%\s*(\d+)\s*\|") + results = [] + for line in output.splitlines(): + match = pattern.match(line) + if match: + results.append( + ( + match[1], # Filename + match[2], # Percent + int(match[3]), # Total lines + int( + float(match[2]) * int(match[3]) / 100.0 + ), # Covered Lines + ) + ) + + results.sort(key=lambda x: x[2] - x[3], reverse=True) + for res in results: + print(f"{res[0]}: {res[3]}/{res[2]} ({res[1]}%)") + + +if __name__ == "__main__": + main() diff --git a/util/stm32mon.c b/util/stm32mon.c index 129e602439..352158ae73 100644 --- a/util/stm32mon.c +++ b/util/stm32mon.c @@ -1,4 +1,4 @@ -/* Copyright 2012 The Chromium OS Authors. All rights reserved. +/* Copyright 2012 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -17,7 +17,7 @@ /* use cfmakeraw() */ #define _DEFAULT_SOURCE /* Newer glibc */ -#define _BSD_SOURCE /* Older glibc */ +#define _BSD_SOURCE /* Older glibc */ #include <arpa/inet.h> #include <compile_time_macros.h> @@ -39,52 +39,48 @@ #include "ec_version.h" -#define KBYTES_TO_BYTES 1024 +#define KBYTES_TO_BYTES 1024 /* * Some Ubuntu versions do not export SPI_IOC_WR_MODE32 even though * the kernel shipped on those supports it. */ #ifndef SPI_IOC_WR_MODE32 -#define SPI_IOC_WR_MODE32 _IOW(SPI_IOC_MAGIC, 5, __u32) +#define SPI_IOC_WR_MODE32 _IOW(SPI_IOC_MAGIC, 5, __u32) #endif /* Monitor command set */ -#define CMD_INIT 0x7f /* Starts the monitor */ +#define CMD_INIT 0x7f /* Starts the monitor */ -#define CMD_GETCMD 0x00 /* Gets the allowed commands */ -#define CMD_GETVER 0x01 /* Gets the bootloader version */ -#define CMD_GETID 0x02 /* Gets the Chip ID */ -#define CMD_READMEM 0x11 /* Reads memory */ -#define CMD_GO 0x21 /* Jumps to user code */ +#define CMD_GETCMD 0x00 /* Gets the allowed commands */ +#define CMD_GETVER 0x01 /* Gets the bootloader version */ +#define CMD_GETID 0x02 /* Gets the Chip ID */ +#define CMD_READMEM 0x11 /* Reads memory */ +#define CMD_GO 0x21 /* Jumps to user code */ #define CMD_WRITEMEM 0x31 /* Writes memory (SRAM or Flash) */ -#define CMD_ERASE 0x43 /* Erases n pages of Flash memory */ +#define CMD_ERASE 0x43 /* Erases n pages of Flash memory */ #define CMD_EXTERASE 0x44 /* Erases n pages of Flash memory */ #define CMD_NO_STRETCH_ERASE 0x45 /* Erases while sending busy frame */ -#define CMD_WP 0x63 /* Enables write protect */ -#define CMD_WU 0x73 /* Disables write protect */ -#define CMD_RP 0x82 /* Enables the read protection */ -#define CMD_RU 0x92 /* Disables the read protection */ - -#define CMD_LOOKUP_ENTRY(COMMAND) {CMD_##COMMAND, #COMMAND} +#define CMD_WP 0x63 /* Enables write protect */ +#define CMD_WU 0x73 /* Disables write protect */ +#define CMD_RP 0x82 /* Enables the read protection */ +#define CMD_RU 0x92 /* Disables the read protection */ + +#define CMD_LOOKUP_ENTRY(COMMAND) \ + { \ + CMD_##COMMAND, #COMMAND \ + } const struct { const uint8_t cmd; const char *name; } cmd_lookup_table[] = { - CMD_LOOKUP_ENTRY(INIT), - CMD_LOOKUP_ENTRY(GETCMD), - CMD_LOOKUP_ENTRY(GETVER), - CMD_LOOKUP_ENTRY(GETID), - CMD_LOOKUP_ENTRY(READMEM), - CMD_LOOKUP_ENTRY(GO), - CMD_LOOKUP_ENTRY(WRITEMEM), - CMD_LOOKUP_ENTRY(ERASE), - CMD_LOOKUP_ENTRY(EXTERASE), - CMD_LOOKUP_ENTRY(NO_STRETCH_ERASE), - CMD_LOOKUP_ENTRY(WP), - CMD_LOOKUP_ENTRY(WU), - CMD_LOOKUP_ENTRY(RP), - CMD_LOOKUP_ENTRY(RU), + CMD_LOOKUP_ENTRY(INIT), CMD_LOOKUP_ENTRY(GETCMD), + CMD_LOOKUP_ENTRY(GETVER), CMD_LOOKUP_ENTRY(GETID), + CMD_LOOKUP_ENTRY(READMEM), CMD_LOOKUP_ENTRY(GO), + CMD_LOOKUP_ENTRY(WRITEMEM), CMD_LOOKUP_ENTRY(ERASE), + CMD_LOOKUP_ENTRY(EXTERASE), CMD_LOOKUP_ENTRY(NO_STRETCH_ERASE), + CMD_LOOKUP_ENTRY(WP), CMD_LOOKUP_ENTRY(WU), + CMD_LOOKUP_ENTRY(RP), CMD_LOOKUP_ENTRY(RU), }; const char *cmd_lookup_name(uint8_t cmd) @@ -98,27 +94,27 @@ const char *cmd_lookup_name(uint8_t cmd) return NULL; } -#define RESP_NACK 0x1f -#define RESP_ACK 0x79 /* 0b 0111 1001 */ -#define RESP_BUSY 0x76 +#define RESP_NACK 0x1f +#define RESP_ACK 0x79 /* 0b 0111 1001 */ +#define RESP_BUSY 0x76 #define RESP_DAMAGED_ACK 0xBC /* 0b 1011 1100, 1 bit shifted REST_ACK */ /* SPI Start of Frame */ -#define SOF 0x5A +#define SOF 0x5A /* Extended erase special parameters */ -#define ERASE_ALL 0xffff -#define ERASE_BANK1 0xfffe -#define ERASE_BANK2 0xfffd +#define ERASE_ALL 0xffff +#define ERASE_BANK1 0xfffe +#define ERASE_BANK2 0xfffd /* Upper bound of rebooting the monitor */ #define MAX_DELAY_REBOOT 100000 /* us */ /* Standard addresses common across various ST chips */ -#define STM32_MAIN_MEMORY_ADDR 0x08000000 -#define STM32_SYSTEM_MEMORY_ADDR 0x1FFF0000 +#define STM32_MAIN_MEMORY_ADDR 0x08000000 +#define STM32_SYSTEM_MEMORY_ADDR 0x1FFF0000 -#define STM32_UNIQUE_ID_SIZE_BYTES 12 +#define STM32_UNIQUE_ID_SIZE_BYTES 12 /* * Device electronic signature contains factory-programmed identification @@ -166,7 +162,7 @@ struct memory_layout { /* known STM32 SoC parameters */ struct stm32_def { - uint16_t id; + uint16_t id; const char *name; uint32_t flash_size; uint32_t page_size; @@ -285,8 +281,8 @@ struct stm32_def { #define DEFAULT_BAUDRATE B38400 #define PAGE_SIZE 256 #define INVALID_I2C_ADAPTER -1 -#define MAX_ACK_RETRY_COUNT (EXT_ERASE_TIMEOUT / DEFAULT_TIMEOUT) -#define MAX_RETRY_COUNT 3 +#define MAX_ACK_RETRY_COUNT (EXT_ERASE_TIMEOUT / DEFAULT_TIMEOUT) +#define MAX_RETRY_COUNT 3 enum interface_mode { MODE_SERIAL, @@ -315,24 +311,24 @@ int retry_on_damaged_ack; /* STM32MON function return values */ enum { - STM32_SUCCESS = 0, - STM32_EIO = -1, /* IO error */ - STM32_EINVAL = -2, /* Got a faulty response from device */ - STM32_ETIMEDOUT = -3, /* Device didn't respond in a time window. */ - STM32_ENOMEM = -4, /* Failed to allocate memory. */ - STM32_ENACK = -5, /* Got NACK. */ - STM32_EDACK = -6, /* Got a damanged ACK. */ + STM32_SUCCESS = 0, + STM32_EIO = -1, /* IO error */ + STM32_EINVAL = -2, /* Got a faulty response from device */ + STM32_ETIMEDOUT = -3, /* Device didn't respond in a time window. */ + STM32_ENOMEM = -4, /* Failed to allocate memory. */ + STM32_ENACK = -5, /* Got NACK. */ + STM32_EDACK = -6, /* Got a damanged ACK. */ }; BUILD_ASSERT(STM32_SUCCESS == 0); -#define IS_STM32_ERROR(res) ((res) < STM32_SUCCESS) +#define IS_STM32_ERROR(res) ((res) < STM32_SUCCESS) /* optional command flags */ enum { - FLAG_UNPROTECT = 0x01, - FLAG_ERASE = 0x02, - FLAG_GO = 0x04, + FLAG_UNPROTECT = 0x01, + FLAG_ERASE = 0x02, + FLAG_GO = 0x04, FLAG_READ_UNPROTECT = 0x08, - FLAG_CR50_MODE = 0x10, + FLAG_CR50_MODE = 0x10, }; typedef struct { @@ -357,14 +353,11 @@ static FILE *log_file; /* Statistic data structure for response kind. */ struct { - const char * const event_name; + const char *const event_name; uint32_t event_count; } stat_resp[] = { - { "RESP_ACK", 0 }, - { "RESP_NACK", 0 }, - { "RESP_BUSY", 0 }, - { "RESP_DAMAGED_ACK", 0 }, - { "JUNK", 0 }, + { "RESP_ACK", 0 }, { "RESP_NACK", 0 }, { "RESP_BUSY", 0 }, + { "RESP_DAMAGED_ACK", 0 }, { "JUNK", 0 }, }; enum { @@ -389,7 +382,7 @@ static void dump_log(const char *prefix, const void *data, size_t count) fprintf(log_file, "%s: ", prefix); for (i = 0; i < count; i++) { - if (i && !(i % 16)) + if (i && !(i % 16)) fprintf(log_file, "\n "); fprintf(log_file, " %02x", ((uint8_t *)data)[i]); } @@ -560,7 +553,6 @@ static void discard_input(int fd) do { res = read_wrapper(fd, buffer, sizeof(buffer)); if (res > 0) { - /* Discard zeros in the beginning of the buffer. */ for (i = 0; i < res; i++) if (buffer[i]) @@ -652,8 +644,8 @@ int wait_for_ack(int fd) return STM32_ETIMEDOUT; } -int send_command(int fd, uint8_t cmd, payload_t *loads, int cnt, - uint8_t *resp, int resp_size, int ack_requested) +int send_command(int fd, uint8_t cmd, payload_t *loads, int cnt, uint8_t *resp, + int resp_size, int ack_requested) { int res, i, c; payload_t *p; @@ -755,7 +747,8 @@ int send_command(int fd, uint8_t cmd, payload_t *loads, int cnt, } else if (IS_STM32_ERROR(res)) { fprintf(stderr, "Failed to get response to command" - " 0x%02x ACK\n", cmd); + " 0x%02x ACK\n", + cmd); return res; } } @@ -767,8 +760,8 @@ int send_command(int fd, uint8_t cmd, payload_t *loads, int cnt, return readcnt; } -int send_command_retry(int fd, uint8_t cmd, payload_t *loads, - int cnt, uint8_t *resp, int resp_size, int ack_requested) +int send_command_retry(int fd, uint8_t cmd, payload_t *loads, int cnt, + uint8_t *resp, int resp_size, int ack_requested) { int res; int retries = MAX_RETRY_COUNT; @@ -777,7 +770,7 @@ int send_command_retry(int fd, uint8_t cmd, payload_t *loads, int ack_tries = MAX_ACK_RETRY_COUNT; res = send_command(fd, cmd, loads, cnt, resp, resp_size, - ack_requested); + ack_requested); while (res == STM32_ETIMEDOUT && ack_tries--) { if (cmd == CMD_WRITEMEM) { @@ -807,8 +800,8 @@ struct stm32_def *command_get_id(int fd) res = send_command(fd, CMD_GETID, NULL, 0, id, sizeof(id), 1); if (res > 0) { if (id[0] != 1) { - fprintf(stderr, "unknown ID : %02x %02x %02x\n", - id[0], id[1], id[2]); + fprintf(stderr, "unknown ID : %02x %02x %02x\n", id[0], + id[1], id[2]); return NULL; } chipid = (id[1] << 8) | id[2]; @@ -891,8 +884,8 @@ int command_get_commands(int fd, struct stm32_def *chip) cmds[0]); return STM32_EINVAL; } - printf("Bootloader v%d.%d, commands : ", - cmds[1] >> 4, cmds[1] & 0xf); + printf("Bootloader v%d.%d, commands : ", cmds[1] >> 4, + cmds[1] & 0xf); boot_loader_version = cmds[1]; erase = command_erase; @@ -920,10 +913,10 @@ int command_get_commands(int fd, struct stm32_def *chip) static int use_progressbar; static int windex; -static const char wheel[] = {'|', '/', '-', '\\' }; +static const char wheel[] = { '|', '/', '-', '\\' }; static void draw_spinner(uint32_t remaining, uint32_t size) { - int percent = (size - remaining)*100/size; + int percent = (size - remaining) * 100 / size; if (use_progressbar) { int dots = percent / 4; @@ -944,15 +937,12 @@ int command_read_mem(int fd, uint32_t address, uint32_t size, uint8_t *buffer) uint32_t remaining = size; uint32_t addr_be; uint8_t cnt; - payload_t loads[2] = { - {4, (uint8_t *)&addr_be}, - {1, &cnt} - }; + payload_t loads[2] = { { 4, (uint8_t *)&addr_be }, { 1, &cnt } }; while (remaining) { uint32_t bytes = MIN(remaining, PAGE_SIZE); - cnt = (uint8_t) (bytes - 1); + cnt = (uint8_t)(bytes - 1); addr_be = htonl(address); draw_spinner(remaining, size); @@ -978,10 +968,8 @@ int command_write_mem(int fd, uint32_t address, uint32_t size, uint8_t *buffer) uint32_t addr_be; uint32_t cnt; uint8_t outbuf[257]; - payload_t loads[2] = { - {4, (uint8_t *)&addr_be}, - {sizeof(outbuf), outbuf} - }; + payload_t loads[2] = { { 4, (uint8_t *)&addr_be }, + { sizeof(outbuf), outbuf } }; while (remaining) { cnt = MIN(remaining, PAGE_SIZE); @@ -997,7 +985,7 @@ int command_write_mem(int fd, uint32_t address, uint32_t size, uint8_t *buffer) draw_spinner(remaining, size); res = send_command_retry(fd, CMD_WRITEMEM, loads, 2, - NULL, 0, 1); + NULL, 0, 1); if (IS_STM32_ERROR(res)) return STM32_EIO; } @@ -1026,7 +1014,7 @@ int command_ext_erase(int fd, uint16_t count, uint16_t start) load.data = (uint8_t *)pages; pages[0] = htons(count - 1); for (i = 0; i < count; i++) - pages[i+1] = htons(start + i); + pages[i + 1] = htons(start + i); } printf("Erasing...\n"); @@ -1045,8 +1033,8 @@ int command_erase_i2c(int fd, uint16_t count, uint16_t start) uint8_t erase_cmd; uint16_t count_be = htons(count); payload_t load[2] = { - { 2, (uint8_t *)&count_be}, - { 0, NULL}, + { 2, (uint8_t *)&count_be }, + { 0, NULL }, }; int load_cnt = 1; uint16_t *pages = NULL; @@ -1071,7 +1059,7 @@ int command_erase_i2c(int fd, uint16_t count, uint16_t start) } erase_cmd = (boot_loader_version == 0x10) ? CMD_EXTERASE : - CMD_NO_STRETCH_ERASE; + CMD_NO_STRETCH_ERASE; printf("Erasing...\n"); res = send_command(fd, erase_cmd, load, load_cnt, NULL, 0, 1); @@ -1083,7 +1071,6 @@ int command_erase_i2c(int fd, uint16_t count, uint16_t start) return res; } - int command_erase(int fd, uint16_t count, uint16_t start) { int res; @@ -1101,7 +1088,7 @@ int command_erase(int fd, uint16_t count, uint16_t start) load.data = (uint8_t *)pages; pages[0] = count - 1; for (i = 0; i < count; i++) - pages[i+1] = start + i; + pages[i + 1] = start + i; } printf("Erasing...\n"); @@ -1241,8 +1228,10 @@ int read_device_signature_register(int fd, const struct stm32_def *chip, } if (addr <= otp_end_addr) { - fprintf(stderr, "Attempting to read from invalid address: " - "%08X\n", addr); + fprintf(stderr, + "Attempting to read from invalid address: " + "%08X\n", + addr); return STM32_EINVAL; } @@ -1290,9 +1279,9 @@ int read_flash_size_register(int fd, struct stm32_def *chip, if (!flash_size_addr) return STM32_EINVAL; - res = read_device_signature_register(fd, chip, - flash_size_addr, sizeof(*flash_size_kbytes), - (uint8_t *)flash_size_kbytes); + res = read_device_signature_register(fd, chip, flash_size_addr, + sizeof(*flash_size_kbytes), + (uint8_t *)flash_size_kbytes); if (!IS_STM32_ERROR(res)) printf("Flash size: %" PRIu16 " KB\n", *flash_size_kbytes); @@ -1306,7 +1295,7 @@ int read_flash_size_register(int fd, struct stm32_def *chip, /* Return zero on success, a negative error value on failures. */ int read_unique_device_id_register(int fd, struct stm32_def *chip, - uint8_t device_id[STM32_UNIQUE_ID_SIZE_BYTES]) + uint8_t device_id[STM32_UNIQUE_ID_SIZE_BYTES]) { int i; int res; @@ -1317,7 +1306,8 @@ int read_unique_device_id_register(int fd, struct stm32_def *chip, return STM32_EINVAL; res = read_device_signature_register(fd, chip, unique_device_id_addr, - STM32_UNIQUE_ID_SIZE_BYTES, device_id); + STM32_UNIQUE_ID_SIZE_BYTES, + device_id); if (!IS_STM32_ERROR(res)) { printf("Unique Device ID: 0x"); @@ -1353,7 +1343,8 @@ int read_package_data_register(int fd, struct stm32_def *chip, else fprintf(stderr, "Failed to read package data register (0x%08X). " - "Ignoring non-critical failure.\n", package_data_addr); + "Ignoring non-critical failure.\n", + package_data_addr); return res; } @@ -1445,25 +1436,16 @@ int write_flash(int fd, struct stm32_def *chip, const char *filename, } static const struct option longopts[] = { - {"adapter", 1, 0, 'a'}, - {"baudrate", 1, 0, 'b'}, - {"cr50", 0, 0, 'c'}, - {"device", 1, 0, 'd'}, - {"erase", 0, 0, 'e'}, - {"go", 0, 0, 'g'}, - {"help", 0, 0, 'h'}, - {"length", 1, 0, 'n'}, - {"location", 1, 0, 'l'}, - {"logfile", 1, 0, 'L'}, - {"offset", 1, 0, 'o'}, - {"progressbar", 0, 0, 'p'}, - {"read", 1, 0, 'r'}, - {"retries", 1, 0, 'R'}, - {"spi", 1, 0, 's'}, - {"unprotect", 0, 0, 'u'}, - {"version", 0, 0, 'v'}, - {"write", 1, 0, 'w'}, - {NULL, 0, 0, 0} + { "adapter", 1, 0, 'a' }, { "baudrate", 1, 0, 'b' }, + { "cr50", 0, 0, 'c' }, { "device", 1, 0, 'd' }, + { "erase", 0, 0, 'e' }, { "go", 0, 0, 'g' }, + { "help", 0, 0, 'h' }, { "length", 1, 0, 'n' }, + { "location", 1, 0, 'l' }, { "logfile", 1, 0, 'L' }, + { "offset", 1, 0, 'o' }, { "progressbar", 0, 0, 'p' }, + { "read", 1, 0, 'r' }, { "retries", 1, 0, 'R' }, + { "spi", 1, 0, 's' }, { "unprotect", 0, 0, 'u' }, + { "version", 0, 0, 'v' }, { "write", 1, 0, 'w' }, + { NULL, 0, 0, 0 } }; void display_usage(char *program) @@ -1498,9 +1480,9 @@ void display_usage(char *program) "the spinner\n"); fprintf(stderr, "--R[etries] <num> : limit connect retries to num\n"); fprintf(stderr, "-L[ogfile] <file> : save all communications exchange " - "in a log file\n"); + "in a log file\n"); fprintf(stderr, "-c[r50_mode] : consider device to be a Cr50 interface," - " no need to set UART port attributes\n"); + " no need to set UART port attributes\n"); fprintf(stderr, "--v[ersion] : print version and exit\n"); exit(2); @@ -1509,7 +1491,7 @@ void display_usage(char *program) void display_version(const char *exe_name) { printf("%s version: %s %s %s\n", exe_name, CROS_STM32MON_VERSION, DATE, - BUILDER); + BUILDER); } speed_t parse_baudrate(const char *value) @@ -1528,8 +1510,8 @@ speed_t parse_baudrate(const char *value) case 115200: return B115200; default: - fprintf(stderr, "Invalid baudrate %s, using %d\n", - value, DEFAULT_BAUDRATE); + fprintf(stderr, "Invalid baudrate %s, using %d\n", value, + DEFAULT_BAUDRATE); return DEFAULT_BAUDRATE; } } @@ -1626,7 +1608,7 @@ static void display_stat_response(void) printf("--\n"); for (idx = 0; idx < total_events; ++idx) { printf("%-18s %d\n", stat_resp[idx].event_name, - stat_resp[idx].event_count); + stat_resp[idx].event_count); } printf("--\n"); } diff --git a/util/tagbranch.sh b/util/tagbranch.sh index e925ddf33a..850886e08c 100755 --- a/util/tagbranch.sh +++ b/util/tagbranch.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2017 The Chromium OS Authors. All rights reserved. +# Copyright 2017 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # diff --git a/util/temp_metrics.conf b/util/temp_metrics.conf index ccd3254beb..174571f72a 100644 --- a/util/temp_metrics.conf +++ b/util/temp_metrics.conf @@ -1,4 +1,4 @@ -# Copyright 2012 The Chromium OS Authors. All rights reserved. +# Copyright 2012 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/util/test-inject-keys.sh b/util/test-inject-keys.sh index 031452150e..44ba3324d3 100755 --- a/util/test-inject-keys.sh +++ b/util/test-inject-keys.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2016 The Chromium OS Authors. All rights reserved. +# Copyright 2016 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/util/test_kconfig_check.py b/util/test_kconfig_check.py index cd1b9bf098..3e459006b1 100644 --- a/util/test_kconfig_check.py +++ b/util/test_kconfig_check.py @@ -1,4 +1,4 @@ -# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Copyright 2021 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Test for Kconfig checker""" @@ -16,7 +16,8 @@ import kconfig_check # Prefix that we strip from each Kconfig option, when considering whether it is # equivalent to a CONFIG option with the same name -PREFIX = 'PLATFORM_EC_' +PREFIX = "PLATFORM_EC_" + @contextlib.contextmanager def capture_sys_output(): @@ -39,38 +40,50 @@ def capture_sys_output(): # directly from Python. You can still run this test with 'pytest' if you like. class KconfigCheck(unittest.TestCase): """Tests for the KconfigCheck class""" + def test_simple_check(self): """Check it detected a new ad-hoc CONFIG""" checker = kconfig_check.KconfigCheck() - self.assertEqual(['NEW_ONE'], checker.find_new_adhoc( - configs=['NEW_ONE', 'OLD_ONE', 'IN_KCONFIG'], - kconfigs=['IN_KCONFIG'], - allowed=['OLD_ONE'])) + self.assertEqual( + ["NEW_ONE"], + checker.find_new_adhoc( + configs=["NEW_ONE", "OLD_ONE", "IN_KCONFIG"], + kconfigs=["IN_KCONFIG"], + allowed=["OLD_ONE"], + ), + ) def test_sorted_check(self): """Check it sorts the results in order""" checker = kconfig_check.KconfigCheck() self.assertSequenceEqual( - ['ANOTHER_NEW_ONE', 'NEW_ONE'], + ["ANOTHER_NEW_ONE", "NEW_ONE"], checker.find_new_adhoc( - configs=['NEW_ONE', 'ANOTHER_NEW_ONE', 'OLD_ONE', 'IN_KCONFIG'], - kconfigs=['IN_KCONFIG'], - allowed=['OLD_ONE'])) + configs=["NEW_ONE", "ANOTHER_NEW_ONE", "OLD_ONE", "IN_KCONFIG"], + kconfigs=["IN_KCONFIG"], + allowed=["OLD_ONE"], + ), + ) def check_read_configs(self, use_defines): + """Check that kconfigs can be read.""" checker = kconfig_check.KconfigCheck() with tempfile.NamedTemporaryFile() as configs: - with open(configs.name, 'w') as out: - prefix = '#define ' if use_defines else '' - suffix = ' ' if use_defines else '=' - out.write(f'''{prefix}CONFIG_OLD_ONE{suffix}y + with open(configs.name, "w") as out: + prefix = "#define " if use_defines else "" + suffix = " " if use_defines else "=" + out.write( + f"""{prefix}CONFIG_OLD_ONE{suffix}y {prefix}NOT_A_CONFIG{suffix} {prefix}CONFIG_STRING{suffix}"something" {prefix}CONFIG_INT{suffix}123 {prefix}CONFIG_HEX{suffix}45ab -''') - self.assertEqual(['OLD_ONE', 'STRING', 'INT', 'HEX'], - checker.read_configs(configs.name, use_defines)) +""" + ) + self.assertEqual( + ["OLD_ONE", "STRING", "INT", "HEX"], + checker.read_configs(configs.name, use_defines), + ) def test_read_configs(self): """Test KconfigCheck.read_configs()""" @@ -87,22 +100,24 @@ class KconfigCheck(unittest.TestCase): Args: srctree: Directory to write to """ - with open(os.path.join(srctree, 'Kconfig'), 'w') as out: - out.write(f'''config {PREFIX}MY_KCONFIG + with open(os.path.join(srctree, "Kconfig"), "w") as out: + out.write( + f"""config {PREFIX}MY_KCONFIG \tbool "my kconfig" rsource "subdir/Kconfig.wibble" -''') - subdir = os.path.join(srctree, 'subdir') +""" + ) + subdir = os.path.join(srctree, "subdir") os.mkdir(subdir) - with open(os.path.join(subdir, 'Kconfig.wibble'), 'w') as out: - out.write('menuconfig %sMENU_KCONFIG\n' % PREFIX) + with open(os.path.join(subdir, "Kconfig.wibble"), "w") as out: + out.write("menuconfig %sMENU_KCONFIG\n" % PREFIX) # Add a directory which should be ignored - bad_subdir = os.path.join(subdir, 'Kconfig') + bad_subdir = os.path.join(subdir, "Kconfig") os.mkdir(bad_subdir) - with open(os.path.join(bad_subdir, 'Kconfig.bad'), 'w') as out: - out.write('menuconfig %sBAD_KCONFIG' % PREFIX) + with open(os.path.join(bad_subdir, "Kconfig.bad"), "w") as out: + out.write("menuconfig %sBAD_KCONFIG" % PREFIX) def test_find_kconfigs(self): """Test KconfigCheck.find_kconfigs()""" @@ -110,20 +125,23 @@ rsource "subdir/Kconfig.wibble" with tempfile.TemporaryDirectory() as srctree: self.setup_srctree(srctree) files = checker.find_kconfigs(srctree) - fnames = [fname[len(srctree):] for fname in files] - self.assertEqual(['/Kconfig', '/subdir/Kconfig.wibble'], fnames) + fnames = [fname[len(srctree) :] for fname in files] + self.assertEqual(["/Kconfig", "/subdir/Kconfig.wibble"], fnames) def test_scan_kconfigs(self): """Test KconfigCheck.scan_configs()""" checker = kconfig_check.KconfigCheck() with tempfile.TemporaryDirectory() as srctree: self.setup_srctree(srctree) - self.assertEqual(['MENU_KCONFIG', 'MY_KCONFIG'], - checker.scan_kconfigs(srctree, PREFIX)) + self.assertEqual( + ["MENU_KCONFIG", "MY_KCONFIG"], + checker.scan_kconfigs(srctree, PREFIX), + ) @classmethod - def setup_allowed_and_configs(cls, allowed_fname, configs_fname, - add_new_one=True): + def setup_allowed_and_configs( + cls, allowed_fname, configs_fname, add_new_one=True + ): """Set up the 'allowed' and 'configs' files for tests Args: @@ -131,14 +149,14 @@ rsource "subdir/Kconfig.wibble" configs_fname: Filename to which CONFIGs to check should be written add_new_one: True to add CONFIG_NEW_ONE to the configs_fname file """ - with open(allowed_fname, 'w') as out: - out.write('CONFIG_OLD_ONE\n') - out.write('CONFIG_MENU_KCONFIG\n') - with open(configs_fname, 'w') as out: - to_add = ['CONFIG_OLD_ONE', 'CONFIG_MY_KCONFIG'] + with open(allowed_fname, "w") as out: + out.write("CONFIG_OLD_ONE\n") + out.write("CONFIG_MENU_KCONFIG\n") + with open(configs_fname, "w") as out: + to_add = ["CONFIG_OLD_ONE", "CONFIG_MY_KCONFIG"] if add_new_one: - to_add.append('CONFIG_NEW_ONE') - out.write('\n'.join(to_add)) + to_add.append("CONFIG_NEW_ONE") + out.write("\n".join(to_add)) def test_check_adhoc_configs(self): """Test KconfigCheck.check_adhoc_configs()""" @@ -148,12 +166,16 @@ rsource "subdir/Kconfig.wibble" with tempfile.NamedTemporaryFile() as allowed: with tempfile.NamedTemporaryFile() as configs: self.setup_allowed_and_configs(allowed.name, configs.name) - new_adhoc, unneeded_adhoc, updated_adhoc = ( - checker.check_adhoc_configs( - configs.name, srctree, allowed.name, PREFIX)) - self.assertEqual(['NEW_ONE'], new_adhoc) - self.assertEqual(['MENU_KCONFIG'], unneeded_adhoc) - self.assertEqual(['OLD_ONE'], updated_adhoc) + ( + new_adhoc, + unneeded_adhoc, + updated_adhoc, + ) = checker.check_adhoc_configs( + configs.name, srctree, allowed.name, PREFIX + ) + self.assertEqual(["NEW_ONE"], new_adhoc) + self.assertEqual(["MENU_KCONFIG"], unneeded_adhoc) + self.assertEqual(["OLD_ONE"], updated_adhoc) def test_check(self): """Test running the 'check' subcommand""" @@ -162,45 +184,57 @@ rsource "subdir/Kconfig.wibble" self.setup_srctree(srctree) with tempfile.NamedTemporaryFile() as allowed: with tempfile.NamedTemporaryFile() as configs: - self.setup_allowed_and_configs(allowed.name, - configs.name) + self.setup_allowed_and_configs( + allowed.name, configs.name + ) ret_code = kconfig_check.main( - ['-c', configs.name, '-s', srctree, - '-a', allowed.name, '-p', PREFIX, 'check']) + [ + "-c", + configs.name, + "-s", + srctree, + "-a", + allowed.name, + "-p", + PREFIX, + "check", + ] + ) self.assertEqual(1, ret_code) - self.assertEqual('', stdout.getvalue()) - found = re.findall('(CONFIG_.*)', stderr.getvalue()) - self.assertEqual(['CONFIG_NEW_ONE'], found) + self.assertEqual("", stdout.getvalue()) + found = re.findall("(CONFIG_.*)", stderr.getvalue()) + self.assertEqual(["CONFIG_NEW_ONE"], found) def test_real_kconfig(self): """Same Kconfig should be returned for kconfiglib / adhoc""" if not kconfig_check.USE_KCONFIGLIB: - self.skipTest('No kconfiglib available') - zephyr_path = pathlib.Path('../../third_party/zephyr/main').resolve() + self.fail("No kconfiglib available") + zephyr_path = pathlib.Path( + "../../../src/third_party/zephyr/main" + ).resolve() if not zephyr_path.exists(): - self.skipTest('No zephyr tree available') + self.fail("No zephyr tree available") + os.environ["ZEPHYR_BASE"] = str(zephyr_path) checker = kconfig_check.KconfigCheck() - srcdir = 'zephyr' + srcdir = "zephyr" search_paths = [zephyr_path] kc_version = checker.scan_kconfigs( - srcdir, search_paths=search_paths, try_kconfiglib=True) + srcdir, search_paths=search_paths, try_kconfiglib=True + ) adhoc_version = checker.scan_kconfigs(srcdir, try_kconfiglib=False) # List of things missing from the Kconfig missing = sorted(list(set(adhoc_version) - set(kc_version))) - # The Kconfig is disjoint in some places, e.g. the boards have their - # own Kconfig files which are not included from the main Kconfig - missing = [item for item in missing - if not item.startswith('BOARD') and - not item.startswith('VARIANT')] - - # Similarly, some other items are defined in files that are not included + # Some items are defined in files that are not included # in all cases, only for particular values of $(ARCH) self.assertEqual( - ['FLASH_LOAD_OFFSET', 'NPCX_HEADER', 'SYS_CLOCK_HW_CYCLES_PER_SEC'], - missing) + [ + "TRAP_UNALIGNED_ACCESS", + ], + missing, + ) def test_check_unneeded(self): """Test running the 'check' subcommand with unneeded ad-hoc configs""" @@ -209,18 +243,29 @@ rsource "subdir/Kconfig.wibble" self.setup_srctree(srctree) with tempfile.NamedTemporaryFile() as allowed: with tempfile.NamedTemporaryFile() as configs: - self.setup_allowed_and_configs(allowed.name, - configs.name, False) + self.setup_allowed_and_configs( + allowed.name, configs.name, False + ) ret_code = kconfig_check.main( - ['-c', configs.name, '-s', srctree, - '-a', allowed.name, '-p', PREFIX, 'check']) + [ + "-c", + configs.name, + "-s", + srctree, + "-a", + allowed.name, + "-p", + PREFIX, + "check", + ] + ) self.assertEqual(1, ret_code) - self.assertEqual('', stderr.getvalue()) - found = re.findall('(CONFIG_.*)', stdout.getvalue()) - self.assertEqual(['CONFIG_MENU_KCONFIG'], found) + self.assertEqual("", stderr.getvalue()) + found = re.findall("(CONFIG_.*)", stdout.getvalue()) + self.assertEqual(["CONFIG_MENU_KCONFIG"], found) allowed = kconfig_check.NEW_ALLOWED_FNAME.read_text().splitlines() - self.assertEqual(['CONFIG_OLD_ONE'], allowed) + self.assertEqual(["CONFIG_OLD_ONE"], allowed) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/util/twister_launcher.py b/util/twister_launcher.py new file mode 100755 index 0000000000..d98768fed5 --- /dev/null +++ b/util/twister_launcher.py @@ -0,0 +1,317 @@ +#!/usr/bin/env vpython3 + +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" +This script is a wrapper for invoking Twister, the Zephyr test runner, using +default parameters for the ChromiumOS EC project. For an overview of CLI +parameters that may be used, please consult the Twister documentation. +""" + +# [VPYTHON:BEGIN] +# python_version: "3.8" +# wheel: < +# name: "infra/python/wheels/anytree-py2_py3" +# version: "version:2.8.0" +# > +# wheel: < +# name: "infra/python/wheels/colorama-py3" +# version: "version:0.4.1" +# > +# wheel: < +# name: "infra/python/wheels/docopt-py2_py3" +# version: "version:0.6.2" +# > +# wheel: < +# name: "infra/python/wheels/ply-py2_py3" +# version: "version:3.11" +# > +# wheel: < +# name: "infra/python/wheels/psutil/${vpython_platform}" +# version: "version:5.8.0.chromium.3" +# > +# wheel: < +# name: "infra/python/wheels/pykwalify-py2_py3" +# version: "version:1.8.0" +# > +# wheel: < +# name: "infra/python/wheels/pyserial-py2_py3" +# version: "version:3.4" +# > +# wheel: < +# name: "infra/python/wheels/python-dateutil-py2_py3" +# version: "version:2.8.1" +# > +# wheel: < +# name: "infra/python/wheels/pyyaml-py3" +# version: "version:5.3.1" +# > +# wheel: < +# name: "infra/python/wheels/ruamel_yaml_clib/${vpython_platform}" +# version: "version:0.2.6" +# > +# wheel: < +# name: "infra/python/wheels/ruamel_yaml-py3" +# version: "version:0.17.16" +# > +# wheel: < +# name: "infra/python/wheels/six-py2_py3" +# version: "version:1.16.0" +# > +# [VPYTHON:END] + +import argparse +import os +import re +import shlex +import subprocess +import sys +import time +from pathlib import Path +from shutil import which + + +def find_checkout() -> Path: + """Find the location of the source checkout or return None.""" + cros_checkout = os.environ.get("CROS_WORKON_SRCROOT") + if cros_checkout is not None: + return Path(cros_checkout) + + # Attempt to locate checkout location relatively if being run outside of chroot. + try: + cros_checkout = Path(__file__).resolve().parents[4] + assert (cros_checkout / "src").exists() + return cros_checkout + except (IndexError, AssertionError): + # Not in the chroot or matching directory structure + return None + + +def find_paths(): + """Find EC base, Zephyr base, and Zephyr modules paths and return as a 3-tuple.""" + + # Determine where the source tree is checked out. Will be None if operating outside + # of the chroot (e.g. Gitlab builds). In this case, additional paths need to be + # passed in through environment variables. + cros_checkout = find_checkout() + + if cros_checkout: + ec_base = cros_checkout / "src" / "platform" / "ec" + zephyr_base = cros_checkout / "src" / "third_party" / "zephyr" / "main" + zephyr_modules_dir = cros_checkout / "src" / "third_party" / "zephyr" + else: + try: + ec_base = Path(os.environ["EC_DIR"]).resolve() + except KeyError as err: + raise RuntimeError( + "EC_DIR unspecified. Please pass as env var or use chroot." + ) from err + + try: + zephyr_base = Path(os.environ["ZEPHYR_BASE"]).resolve() + except KeyError as err: + raise RuntimeError( + "ZEPHYR_BASE unspecified. Please pass as env var or use chroot." + ) from err + + try: + zephyr_modules_dir = Path(os.environ["MODULES_DIR"]).resolve() + except KeyError as err: + raise RuntimeError( + "MODULES_DIR unspecified. Please pass as env var or use chroot." + ) from err + + return (ec_base, zephyr_base, zephyr_modules_dir) + + +def find_modules(mod_dir: Path) -> list: + """Find Zephyr modules in the given directory `dir`.""" + + modules = [] + for child in mod_dir.iterdir(): + if child.is_dir() and (child / "zephyr" / "module.yml").exists(): + modules.append(child.resolve()) + return modules + + +def is_tool(name): + """Check if 'name' is on PATH and marked executable.""" + return which(name) is not None + + +def is_rdb_login(): + """Checks if user is logged into rdb""" + cmd = ["rdb", "auth-info"] + ret = subprocess.run(cmd, capture_output=True, text=True, check=False) + + if ret.returncode == 0: + print("\nrdb auth-info: " + ret.stdout.split("\n")[0]) + else: + print("\nrdb auth-info: " + ret.stderr) + + return ret.returncode == 0 + + +def upload_results(ec_base): + """Uploads Zephyr Test results to ResultDB""" + flag = False + + if is_rdb_login(): + json_path = ec_base / "twister-out" / "twister.json" + cmd = [ + "rdb", + "stream", + "-new", + "-realm", + "chromium:public", + "--", + str(ec_base / "util/zephyr_to_resultdb.py"), + "--result=" + str(json_path), + "--upload=True", + ] + + start_time = time.time() + ret = subprocess.run(cmd, capture_output=True, text=True, check=True) + end_time = time.time() + + # Extract URL to test report from captured output + rdb_url = re.search( + r"(?P<url>https?://[^\s]+)", ret.stderr.split("\n")[0] + ).group("url") + print(f"\nTEST RESULTS ({end_time - start_time:.3f}s): {rdb_url}\n") + flag = ret.returncode == 0 + else: + print("Unable to upload test results, please run 'rdb auth-login'\n") + + return flag + + +def main(): + """Run Twister using defaults for the EC project.""" + + # Get paths for the build. + ec_base, zephyr_base, zephyr_modules_dir = find_paths() + + zephyr_modules = find_modules(zephyr_modules_dir) + + # Add the EC dir as a module if not already included (resolve all paths to + # account for symlinked or relative paths) + if ec_base.resolve() not in zephyr_modules: + zephyr_modules.append(ec_base) + + # Prepare environment variables for export to Twister. Inherit the parent + # process's environment, but set some default values if not already set. + twister_env = dict(os.environ) + is_in_chroot = Path("/etc/cros_chroot_version").is_file() + extra_env_vars = { + "TOOLCHAIN_ROOT": os.environ.get( + "TOOLCHAIN_ROOT", + str(ec_base / "zephyr") if is_in_chroot else zephyr_base, + ), + "ZEPHYR_TOOLCHAIN_VARIANT": os.environ.get( + "ZEPHYR_TOOLCHAIN_VARIANT", "llvm" if is_in_chroot else "host" + ), + } + twister_env.update(extra_env_vars) + + # Twister CLI args + # TODO(b/239165779): Reduce or remove the usage of label properties + # Zephyr upstream has deprecated the label property. We need to allow + # warnings during twister runs until all the label properties are removed + # from all board and test overlays. + twister_cli = [ + sys.executable, + str(zephyr_base / "scripts" / "twister"), # Executable path + "--ninja", + "--disable-warnings-as-errors", + f"-x=DTS_ROOT={str( ec_base / 'zephyr')}", + f"-x=SYSCALL_INCLUDE_DIRS={str(ec_base / 'zephyr' / 'include' / 'drivers')}", + f"-x=ZEPHYR_BASE={zephyr_base}", + f"-x=ZEPHYR_MODULES={';'.join([str(p) for p in zephyr_modules])}", + ] + + # `-T` flags (used for specifying test directories to build and run) + # require special handling. When run without `-T` flags, Twister will + # search for tests in `zephyr_base`. This is undesirable and we want + # Twister to look in the EC tree by default, instead. Use argparse to + # intercept `-T` flags and pass in a new default if none are found. If + # user does pass their own `-T` flags, pass them through instead. Do the + # same with verbosity. Other arguments get passed straight through, + # including -h/--help so that Twister's own help text gets displayed. + parser = argparse.ArgumentParser(add_help=False, allow_abbrev=False) + parser.add_argument("-T", "--testsuite-root", action="append") + parser.add_argument("-p", "--platform", action="append") + parser.add_argument("-v", "--verbose", action="count", default=0) + parser.add_argument( + "--gcov-tool", default=str(ec_base / "util" / "llvm-gcov.sh") + ) + parser.add_argument( + "--no-upload-cros-rdb", dest="upload_cros_rdb", action="store_false" + ) + + intercepted_args, other_args = parser.parse_known_args() + + for _ in range(intercepted_args.verbose): + # Pass verbosity setting through to twister + twister_cli.append("-v") + + if intercepted_args.testsuite_root: + # Pass user-provided -T args when present. + for arg in intercepted_args.testsuite_root: + twister_cli.extend(["-T", arg]) + else: + # Use EC base dir when no -T args specified. This will cause all + # Twister-compatible EC tests to run. + twister_cli.extend(["-T", str(ec_base)]) + twister_cli.extend(["-T", str(zephyr_base / "tests/subsys/shell")]) + + # Pass through the chosen coverage tool, or fall back on the default choice + # (see add_argument above). + twister_cli.extend( + [ + "--gcov-tool", + intercepted_args.gcov_tool, + ] + ) + if intercepted_args.platform: + # Pass user-provided -p args when present. + for arg in intercepted_args.platform: + twister_cli.extend(["-p", arg]) + else: + # posix_native and unit_testing when nothing was requested by user. + twister_cli.extend(["-p", "native_posix"]) + twister_cli.extend(["-p", "unit_testing"]) + + # Append additional user-supplied args + twister_cli.extend(other_args) + + # Print exact CLI args and environment variables depending on verbosity. + if intercepted_args.verbose > 0: + print("Calling:", " ".join(shlex.quote(str(x)) for x in twister_cli)) + print( + "With environment overrides:", + " ".join( + f"{name}={shlex.quote(val)}" + for name, val in extra_env_vars.items() + ), + ) + sys.stdout.flush() + + # Invoke Twister and wait for it to exit. + result = subprocess.run(twister_cli, env=twister_env, check=False) + + if result.returncode == 0: + print("TEST EXECUTION SUCCESSFUL") + else: + print("TEST EXECUTION FAILED") + + if is_tool("rdb") and intercepted_args.upload_cros_rdb: + upload_results(ec_base) + + sys.exit(result.returncode) + + +if __name__ == "__main__": + main() diff --git a/util/uart_stress_tester.py b/util/uart_stress_tester.py index b3db60060e..d7b2341e93 100755 --- a/util/uart_stress_tester.py +++ b/util/uart_stress_tester.py @@ -1,12 +1,8 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# Copyright 2019 The Chromium OS Authors. All rights reserved. +# Copyright 2019 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -# -# Ignore indention messages, since legacy scripts use 2 spaces instead of 4. -# pylint: disable=bad-indentation,docstring-section-indent -# pylint: disable=docstring-trailing-quotes """ChromeOS Uart Stress Test @@ -21,9 +17,7 @@ Prerequisite: e.g. dut-control cr50_uart_timestamp:off """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function +from __future__ import absolute_import, division, print_function import argparse import atexit @@ -34,474 +28,518 @@ import sys import threading import time -import serial +import serial # pylint:disable=import-error -BAUDRATE = 115200 # Default baudrate setting for UART port -CROS_USERNAME = 'root' # Account name to login to ChromeOS -CROS_PASSWORD = 'test0000' # Password to login to ChromeOS -CHARGEN_TXT = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' - # The result of 'chargen 62 62' +BAUDRATE = 115200 # Default baudrate setting for UART port +CROS_USERNAME = "root" # Account name to login to ChromeOS +CROS_PASSWORD = "test0000" # Password to login to ChromeOS +CHARGEN_TXT = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +# The result of 'chargen 62 62' CHARGEN_TXT_LEN = len(CHARGEN_TXT) -CR = '\r' # Carriage Return -LF = '\n' # Line Feed +CR = "\r" # Carriage Return +LF = "\n" # Line Feed CRLF = CR + LF -FLAG_FILENAME = '/tmp/chargen_testing' -TPM_CMD = ('trunks_client --key_create --rsa=2048 --usage=sign' - ' --key_blob=/tmp/blob &> /dev/null') - # A ChromeOS TPM command for the cr50 stress - # purpose. -CR50_LOAD_GEN_CMD = ('while [[ -f %s ]]; do %s; done &' - % (FLAG_FILENAME, TPM_CMD)) - # A command line to run TPM_CMD in background - # infinitely. +FLAG_FILENAME = "/tmp/chargen_testing" +TPM_CMD = ( + "trunks_client --key_create --rsa=2048 --usage=sign" + " --key_blob=/tmp/blob &> /dev/null" +) +# A ChromeOS TPM command for the cr50 stress +# purpose. +CR50_LOAD_GEN_CMD = "while [[ -f %s ]]; do %s; done &" % ( + FLAG_FILENAME, + TPM_CMD, +) +# A command line to run TPM_CMD in background +# infinitely. class ChargenTestError(Exception): - """Exception for Uart Stress Test Error""" - pass + """Exception for Uart Stress Test Error""" + pass -class UartSerial(object): - """Test Object for a single UART serial device - - Attributes: - UART_DEV_PROFILES - char_loss_occurrences: Number that character loss happens - cleanup_cli: Command list to perform before the test exits - cr50_workload: True if cr50 should be stressed, or False otherwise - usb_output: True if output should be generated to USB channel - dev_prof: Dictionary of device profile - duration: Time to keep chargen running - eol: Characters to add at the end of input - logger: object that store the log - num_ch_exp: Expected number of characters in output - num_ch_cap: Number of captured characters in output - test_cli: Command list to run for chargen test - test_thread: Thread object that captures the UART output - serial: serial.Serial object - """ - UART_DEV_PROFILES = ( - # Kernel - { - 'prompt':'localhost login:', - 'device_type':'AP', - 'prepare_cmd':[ - CROS_USERNAME, # Login - CROS_PASSWORD, # Password - 'dmesg -D', # Disable console message - 'touch ' + FLAG_FILENAME, # Create a temp file - ], - 'cleanup_cmd':[ - 'rm -f ' + FLAG_FILENAME, # Remove the temp file - 'dmesg -E', # Enable console message - 'logout', # Logout - ], - 'end_of_input':LF, - }, - # EC - { - 'prompt':'> ', - 'device_type':'EC', - 'prepare_cmd':[ - 'chan save', - 'chan 0' # Disable console message - ], - 'cleanup_cmd':['', 'chan restore'], - 'end_of_input':CRLF, - }, - ) - - def __init__(self, port, duration, timeout=1, - baudrate=BAUDRATE, cr50_workload=False, - usb_output=False): - """Initialize UartSerial - - Args: - port: UART device path. e.g. /dev/ttyUSB0 - duration: Time to test, in seconds - timeout: Read timeout value. - baudrate: Baud rate such as 9600 or 115200. - cr50_workload: True if a workload should be generated on cr50 - usb_output: True if a workload should be generated to USB channel - """ - - # Initialize serial object - self.serial = serial.Serial() - self.serial.port = port - self.serial.timeout = timeout - self.serial.baudrate = baudrate - - self.duration = duration - self.cr50_workload = cr50_workload - self.usb_output = usb_output - - self.logger = logging.getLogger(type(self).__name__ + '| ' + port) - self.test_thread = threading.Thread(target=self.stress_test_thread) - self.dev_prof = {} - self.cleanup_cli = [] - self.test_cli = [] - self.eol = CRLF - self.num_ch_exp = 0 - self.num_ch_cap = 0 - self.char_loss_occurrences = 0 - atexit.register(self.cleanup) - - def run_command(self, command_lines, delay=0): - """Run command(s) at UART prompt - - Args: - command_lines: list of commands to run. - delay: delay after a command in second +class UartSerial(object): + """Test Object for a single UART serial device + + Attributes: + UART_DEV_PROFILES + char_loss_occurrences: Number that character loss happens + cleanup_cli: Command list to perform before the test exits + cr50_workload: True if cr50 should be stressed, or False otherwise + usb_output: True if output should be generated to USB channel + dev_prof: Dictionary of device profile + duration: Time to keep chargen running + eol: Characters to add at the end of input + logger: object that store the log + num_ch_exp: Expected number of characters in output + num_ch_cap: Number of captured characters in output + test_cli: Command list to run for chargen test + test_thread: Thread object that captures the UART output + serial: serial.Serial object """ - for cli in command_lines: - self.logger.debug('run %r', cli) - - self.serial.write((cli + self.eol).encode()) - self.serial.flush() - if delay: - time.sleep(delay) - - def cleanup(self): - """Before termination, clean up the UART device.""" - self.logger.debug('Closing...') - - self.serial.open() - self.run_command(self.cleanup_cli) # Run cleanup commands - self.serial.close() - self.logger.debug('Cleanup done') + UART_DEV_PROFILES = ( + # Kernel + { + "prompt": "localhost login:", + "device_type": "AP", + "prepare_cmd": [ + CROS_USERNAME, # Login + CROS_PASSWORD, # Password + "dmesg -D", # Disable console message + "touch " + FLAG_FILENAME, # Create a temp file + ], + "cleanup_cmd": [ + "rm -f " + FLAG_FILENAME, # Remove the temp file + "dmesg -E", # Enable console message + "logout", # Logout + ], + "end_of_input": LF, + }, + # EC + { + "prompt": "> ", + "device_type": "EC", + "prepare_cmd": ["chan save", "chan 0"], # Disable console message + "cleanup_cmd": ["", "chan restore"], + "end_of_input": CRLF, + }, + ) + + def __init__( + self, + port, + duration, + timeout=1, + baudrate=BAUDRATE, + cr50_workload=False, + usb_output=False, + ): + """Initialize UartSerial + + Args: + port: UART device path. e.g. /dev/ttyUSB0 + duration: Time to test, in seconds + timeout: Read timeout value. + baudrate: Baud rate such as 9600 or 115200. + cr50_workload: True if a workload should be generated on cr50 + usb_output: True if a workload should be generated to USB channel + """ + + # Initialize serial object + self.serial = serial.Serial() + self.serial.port = port + self.serial.timeout = timeout + self.serial.baudrate = baudrate + + self.duration = duration + self.cr50_workload = cr50_workload + self.usb_output = usb_output + + self.logger = logging.getLogger(type(self).__name__ + "| " + port) + self.test_thread = threading.Thread(target=self.stress_test_thread) + + self.dev_prof = {} + self.cleanup_cli = [] + self.test_cli = [] + self.eol = CRLF + self.num_ch_exp = 0 + self.num_ch_cap = 0 + self.char_loss_occurrences = 0 + atexit.register(self.cleanup) + + def run_command(self, command_lines, delay=0): + """Run command(s) at UART prompt + + Args: + command_lines: list of commands to run. + delay: delay after a command in second + """ + for cli in command_lines: + self.logger.debug("run %r", cli) + + self.serial.write((cli + self.eol).encode()) + self.serial.flush() + if delay: + time.sleep(delay) + + def cleanup(self): + """Before termination, clean up the UART device.""" + self.logger.debug("Closing...") + + self.serial.open() + self.run_command(self.cleanup_cli) # Run cleanup commands + self.serial.close() + + self.logger.debug("Cleanup done") + + def get_output(self): + """Capture the UART output + + Args: + stop_char: Read output buffer until it reads stop_char. + + Returns: + text from UART output. + """ + if self.serial.inWaiting() == 0: + time.sleep(1) + + return self.serial.read(self.serial.inWaiting()).decode() + + def prepare(self): + """Prepare the test: + + Identify the type of UART device (EC or Kernel?), then + decide what kind of commands to use to generate stress loads. + + Raises: + ChargenTestError if UART source can't be identified. + """ + try: + self.logger.info("Preparing...") + + self.serial.open() + + # Prepare the device for test + self.serial.flushInput() + self.serial.flushOutput() + + self.get_output() # drain data + + # Give a couple of line feeds, and capture the prompt text + self.run_command(["", ""]) + prompt_txt = self.get_output() + + # Detect the device source: EC or AP? + # Detect if the device is AP or EC console based on the captured. + for dev_prof in self.UART_DEV_PROFILES: + if dev_prof["prompt"] in prompt_txt: + self.dev_prof = dev_prof + break + else: + # No prompt patterns were found. UART seems not responding or in + # an undesirable status. + if prompt_txt: + raise ChargenTestError( + "%s: Got an unknown prompt text: %s\n" + "Check manually whether %s is available." + % (self.serial.port, prompt_txt, self.serial.port) + ) + else: + raise ChargenTestError( + "%s: Got no input. Close any other connections" + " to this port, and try it again." % self.serial.port + ) + + self.logger.info( + "Detected as %s UART", self.dev_prof["device_type"] + ) + # Log displays the UART type (AP|EC) instead of device filename. + self.logger = logging.getLogger( + type(self).__name__ + "| " + self.dev_prof["device_type"] + ) + + # Either login to AP or run some commands to prepare the device + # for test + self.eol = self.dev_prof["end_of_input"] + self.run_command(self.dev_prof["prepare_cmd"], delay=2) + self.cleanup_cli += self.dev_prof["cleanup_cmd"] + + # 'chargen' of AP does not have option for USB output. + # Force it work on UART. + if self.dev_prof["device_type"] == "AP": + self.usb_output = False + + # Check whether the command 'chargen' is available in the device. + # 'chargen 1 4' is supposed to print '0000' + self.get_output() # drain data + + chargen_cmd = "chargen 1 4" + if self.usb_output: + chargen_cmd += " usb" + self.run_command([chargen_cmd]) + tmp_txt = self.get_output() + + # Check whether chargen command is available. + if "0000" not in tmp_txt: + raise ChargenTestError( + "%s: Chargen got an unexpected result: %s" + % (self.dev_prof["device_type"], tmp_txt) + ) + + self.num_ch_exp = int(self.serial.baudrate * self.duration / 10) + chargen_cmd = ( + "chargen " + str(CHARGEN_TXT_LEN) + " " + str(self.num_ch_exp) + ) + if self.usb_output: + chargen_cmd += " usb" + self.test_cli = [chargen_cmd] + + self.logger.info("Ready to test") + finally: + self.serial.close() + + def stress_test_thread(self): + """Test thread + + Raises: + ChargenTestError: if broken character is found. + """ + try: + self.serial.open() + self.serial.flushInput() + self.serial.flushOutput() + + # Run TPM command in background to burden cr50. + if self.dev_prof["device_type"] == "AP" and self.cr50_workload: + self.run_command([CR50_LOAD_GEN_CMD]) + self.logger.debug("run TPM job while %s exists", FLAG_FILENAME) + + # Run the command 'chargen', one time + self.run_command([""]) # Give a line feed + self.get_output() # Drain the output + self.run_command(self.test_cli) + self.serial.readline() # Drain the echoed command line. + + err_msg = "%s: Expected %r but got %s after %d char received" + + # Keep capturing the output until the test timer is expired. + self.num_ch_cap = 0 + self.char_loss_occurrences = 0 + data_starve_count = 0 + + total_num_ch = ( + self.num_ch_exp + ) # Expected number of characters in total + ch_exp = CHARGEN_TXT[0] + ch_cap = ( + "z" # any character value is ok for loop initial condition. + ) + while self.num_ch_cap < total_num_ch: + captured = self.get_output() + + if captured: + # There is some output data. Reset the data starvation count. + data_starve_count = 0 + else: + data_starve_count += 1 + if data_starve_count > 1: + # If nothing was captured more than once, then terminate the test. + self.logger.debug("No more output") + break + + for ch_cap in captured: + if ch_cap not in CHARGEN_TXT: + # If it is not alpha-numeric, terminate the test. + if ch_cap not in CRLF: + # If it is neither a CR nor LF, then it is an error case. + self.logger.error( + "Whole captured characters: %r", captured + ) + raise ChargenTestError( + err_msg + % ( + "Broken char captured", + ch_exp, + hex(ord(ch_cap)), + self.num_ch_cap, + ) + ) + + # Set the loop termination condition true. + total_num_ch = self.num_ch_cap + + if self.num_ch_cap >= total_num_ch: + break + + if ch_exp != ch_cap: + # If it is alpha-numeric but not continuous, then some characters + # are lost. + self.logger.error( + err_msg, + "Char loss detected", + ch_exp, + repr(ch_cap), + self.num_ch_cap, + ) + self.char_loss_occurrences += 1 + + # Recalculate the expected number of characters to adjust + # termination condition. The loss might be bigger than this + # adjustment, but it is okay since it will terminates by either + # CR/LF detection or by data starvation. + idx_ch_exp = CHARGEN_TXT.find(ch_exp) + idx_ch_cap = CHARGEN_TXT.find(ch_cap) + if idx_ch_cap < idx_ch_exp: + idx_ch_cap += len(CHARGEN_TXT) + total_num_ch -= idx_ch_cap - idx_ch_exp + + self.num_ch_cap += 1 + + # Determine What character is expected next? + ch_exp = CHARGEN_TXT[ + (CHARGEN_TXT.find(ch_cap) + 1) % CHARGEN_TXT_LEN + ] + + finally: + self.serial.close() + + def start_test(self): + """Start the test thread""" + self.logger.info("Test thread starts") + self.test_thread.start() + + def wait_test_done(self): + """Wait until the test thread get done and join""" + self.test_thread.join() + self.logger.info("Test thread is done") + + def get_result(self): + """Display the result + + Returns: + Integer = the number of lost character + + Raises: + ChargenTestError: if the capture is corrupted. + """ + # If more characters than expected are captured, it means some messages + # from other than chargen are mixed. Stop processing further. + if self.num_ch_exp < self.num_ch_cap: + raise ChargenTestError( + "%s: UART output is corrupted." % self.dev_prof["device_type"] + ) + + # Get the count difference between the expected to the captured + # as the number of lost character. + char_lost = self.num_ch_exp - self.num_ch_cap + self.logger.info( + "%8d char lost / %10d (%.1f %%)", + char_lost, + self.num_ch_exp, + char_lost * 100.0 / self.num_ch_exp, + ) + + return char_lost, self.num_ch_exp, self.char_loss_occurrences - def get_output(self): - """Capture the UART output - Args: - stop_char: Read output buffer until it reads stop_char. +class ChargenTest(object): + """UART stress tester - Returns: - text from UART output. + Attributes: + logger: logging object + serials: Dictionary where key is filename of UART device, and the value is + UartSerial object """ - if self.serial.inWaiting() == 0: - time.sleep(1) - - return self.serial.read(self.serial.inWaiting()).decode() - def prepare(self): - """Prepare the test: - - Identify the type of UART device (EC or Kernel?), then - decide what kind of commands to use to generate stress loads. - - Raises: - ChargenTestError if UART source can't be identified. - """ - try: - self.logger.info('Preparing...') - - self.serial.open() - - # Prepare the device for test - self.serial.flushInput() - self.serial.flushOutput() - - self.get_output() # drain data - - # Give a couple of line feeds, and capture the prompt text - self.run_command(['', '']) - prompt_txt = self.get_output() - - # Detect the device source: EC or AP? - # Detect if the device is AP or EC console based on the captured. - for dev_prof in self.UART_DEV_PROFILES: - if dev_prof['prompt'] in prompt_txt: - self.dev_prof = dev_prof - break - else: - # No prompt patterns were found. UART seems not responding or in - # an undesirable status. - if prompt_txt: - raise ChargenTestError('%s: Got an unknown prompt text: %s\n' - 'Check manually whether %s is available.' % - (self.serial.port, prompt_txt, - self.serial.port)) - else: - raise ChargenTestError('%s: Got no input. Close any other connections' - ' to this port, and try it again.' % - self.serial.port) - - self.logger.info('Detected as %s UART', self.dev_prof['device_type']) - # Log displays the UART type (AP|EC) instead of device filename. - self.logger = logging.getLogger(type(self).__name__ + '| ' + - self.dev_prof['device_type']) - - # Either login to AP or run some commands to prepare the device - # for test - self.eol = self.dev_prof['end_of_input'] - self.run_command(self.dev_prof['prepare_cmd'], delay=2) - self.cleanup_cli += self.dev_prof['cleanup_cmd'] - - # 'chargen' of AP does not have option for USB output. - # Force it work on UART. - if self.dev_prof['device_type'] == 'AP': - self.usb_output = False - - # Check whether the command 'chargen' is available in the device. - # 'chargen 1 4' is supposed to print '0000' - self.get_output() # drain data - - chargen_cmd = 'chargen 1 4' - if self.usb_output: - chargen_cmd += ' usb' - self.run_command([chargen_cmd]) - tmp_txt = self.get_output() - - # Check whether chargen command is available. - if '0000' not in tmp_txt: - raise ChargenTestError('%s: Chargen got an unexpected result: %s' % - (self.dev_prof['device_type'], tmp_txt)) - - self.num_ch_exp = int(self.serial.baudrate * self.duration / 10) - chargen_cmd = 'chargen ' + str(CHARGEN_TXT_LEN) + ' ' + \ - str(self.num_ch_exp) - if self.usb_output: - chargen_cmd += ' usb' - self.test_cli = [chargen_cmd] - - self.logger.info('Ready to test') - finally: - self.serial.close() - - def stress_test_thread(self): - """Test thread - - Raises: - ChargenTestError: if broken character is found. - """ - try: - self.serial.open() - self.serial.flushInput() - self.serial.flushOutput() - - # Run TPM command in background to burden cr50. - if self.dev_prof['device_type'] == 'AP' and self.cr50_workload: - self.run_command([CR50_LOAD_GEN_CMD]) - self.logger.debug('run TPM job while %s exists', FLAG_FILENAME) - - # Run the command 'chargen', one time - self.run_command(['']) # Give a line feed - self.get_output() # Drain the output - self.run_command(self.test_cli) - self.serial.readline() # Drain the echoed command line. - - err_msg = '%s: Expected %r but got %s after %d char received' - - # Keep capturing the output until the test timer is expired. - self.num_ch_cap = 0 - self.char_loss_occurrences = 0 - data_starve_count = 0 - - total_num_ch = self.num_ch_exp # Expected number of characters in total - ch_exp = CHARGEN_TXT[0] - ch_cap = 'z' # any character value is ok for loop initial condition. - while self.num_ch_cap < total_num_ch: - captured = self.get_output() - - if captured: - # There is some output data. Reset the data starvation count. - data_starve_count = 0 + def __init__(self, ports, duration, cr50_workload=False, usb_output=False): + """Initialize UART stress tester + + Args: + ports: List of UART ports to test. + duration: Time to keep testing in seconds. + cr50_workload: True if a workload should be generated on cr50 + usb_output: True if a workload should be generated to USB channel + + Raises: + ChargenTestError: if any of ports is not a valid character device. + """ + + # Save the arguments + for port in ports: + try: + mode = os.stat(port).st_mode + except OSError as e: + raise ChargenTestError(e) + if not stat.S_ISCHR(mode): + raise ChargenTestError("%s is not a character device." % port) + + if duration <= 0: + raise ChargenTestError("Input error: duration is not positive.") + + # Initialize logging object + self.logger = logging.getLogger(type(self).__name__) + + # Create an UartSerial object per UART port + self.serials = {} # UartSerial objects + for port in ports: + self.serials[port] = UartSerial( + port=port, + duration=duration, + cr50_workload=cr50_workload, + usb_output=usb_output, + ) + + def prepare(self): + """Prepare the test for each UART port""" + self.logger.info("Prepare ports for test") + for _, ser in self.serials.items(): + ser.prepare() + self.logger.info("Ports are ready to test") + + def print_result(self): + """Display the test result for each UART port + + Returns: + char_lost: Total number of characters lost + """ + char_lost = 0 + for _, ser in self.serials.items(): + (tmp_lost, _, _) = ser.get_result() + char_lost += tmp_lost + + # If any characters are lost, then test fails. + msg = "lost %d character(s) from the test" % char_lost + if char_lost > 0: + self.logger.error("FAIL: %s", msg) else: - data_starve_count += 1 - if data_starve_count > 1: - # If nothing was captured more than once, then terminate the test. - self.logger.debug('No more output') - break - - for ch_cap in captured: - if ch_cap not in CHARGEN_TXT: - # If it is not alpha-numeric, terminate the test. - if ch_cap not in CRLF: - # If it is neither a CR nor LF, then it is an error case. - self.logger.error('Whole captured characters: %r', captured) - raise ChargenTestError(err_msg % ('Broken char captured', ch_exp, - hex(ord(ch_cap)), - self.num_ch_cap)) - - # Set the loop termination condition true. - total_num_ch = self.num_ch_cap - - if self.num_ch_cap >= total_num_ch: - break - - if ch_exp != ch_cap: - # If it is alpha-numeric but not continuous, then some characters - # are lost. - self.logger.error(err_msg, 'Char loss detected', - ch_exp, repr(ch_cap), self.num_ch_cap) - self.char_loss_occurrences += 1 - - # Recalculate the expected number of characters to adjust - # termination condition. The loss might be bigger than this - # adjustment, but it is okay since it will terminates by either - # CR/LF detection or by data starvation. - idx_ch_exp = CHARGEN_TXT.find(ch_exp) - idx_ch_cap = CHARGEN_TXT.find(ch_cap) - if idx_ch_cap < idx_ch_exp: - idx_ch_cap += len(CHARGEN_TXT) - total_num_ch -= (idx_ch_cap - idx_ch_exp) - - self.num_ch_cap += 1 - - # Determine What character is expected next? - ch_exp = CHARGEN_TXT[(CHARGEN_TXT.find(ch_cap) + 1) % CHARGEN_TXT_LEN] - - finally: - self.serial.close() - - def start_test(self): - """Start the test thread""" - self.logger.info('Test thread starts') - self.test_thread.start() - - def wait_test_done(self): - """Wait until the test thread get done and join""" - self.test_thread.join() - self.logger.info('Test thread is done') - - def get_result(self): - """Display the result + self.logger.info("PASS: %s", msg) - Returns: - Integer = the number of lost character + return char_lost - Raises: - ChargenTestError: if the capture is corrupted. - """ - # If more characters than expected are captured, it means some messages - # from other than chargen are mixed. Stop processing further. - if self.num_ch_exp < self.num_ch_cap: - raise ChargenTestError('%s: UART output is corrupted.' % - self.dev_prof['device_type']) + def run(self): + """Run the stress test on UART port(s) - # Get the count difference between the expected to the captured - # as the number of lost character. - char_lost = self.num_ch_exp - self.num_ch_cap - self.logger.info('%8d char lost / %10d (%.1f %%)', - char_lost, self.num_ch_exp, - char_lost * 100.0 / self.num_ch_exp) + Raises: + ChargenTestError: If any characters are lost. + """ - return char_lost, self.num_ch_exp, self.char_loss_occurrences + # Detect UART source type, and decide which command to test. + self.prepare() + # Run the test on each UART port in thread. + self.logger.info("Test starts") + for _, ser in self.serials.items(): + ser.start_test() -class ChargenTest(object): - """UART stress tester + # Wait all tests to finish. + for _, ser in self.serials.items(): + ser.wait_test_done() - Attributes: - logger: logging object - serials: Dictionary where key is filename of UART device, and the value is - UartSerial object - """ + # Print the result. + char_lost = self.print_result() + if char_lost: + raise ChargenTestError( + "Test failed: lost %d character(s)" % char_lost + ) - def __init__(self, ports, duration, cr50_workload=False, - usb_output=False): - """Initialize UART stress tester + self.logger.info("Test is done") - Args: - ports: List of UART ports to test. - duration: Time to keep testing in seconds. - cr50_workload: True if a workload should be generated on cr50 - usb_output: True if a workload should be generated to USB channel - Raises: - ChargenTestError: if any of ports is not a valid character device. - """ +def parse_args(cmdline): + """Parse command line arguments. - # Save the arguments - for port in ports: - try: - mode = os.stat(port).st_mode - except OSError as e: - raise ChargenTestError(e) - if not stat.S_ISCHR(mode): - raise ChargenTestError('%s is not a character device.' % port) - - if duration <= 0: - raise ChargenTestError('Input error: duration is not positive.') - - # Initialize logging object - self.logger = logging.getLogger(type(self).__name__) - - # Create an UartSerial object per UART port - self.serials = {} # UartSerial objects - for port in ports: - self.serials[port] = UartSerial(port=port, duration=duration, - cr50_workload=cr50_workload, - usb_output=usb_output) - - def prepare(self): - """Prepare the test for each UART port""" - self.logger.info('Prepare ports for test') - for _, ser in self.serials.items(): - ser.prepare() - self.logger.info('Ports are ready to test') - - def print_result(self): - """Display the test result for each UART port + Args: + cmdline: list to be parsed Returns: - char_lost: Total number of characters lost - """ - char_lost = 0 - for _, ser in self.serials.items(): - (tmp_lost, _, _) = ser.get_result() - char_lost += tmp_lost - - # If any characters are lost, then test fails. - msg = 'lost %d character(s) from the test' % char_lost - if char_lost > 0: - self.logger.error('FAIL: %s', msg) - else: - self.logger.info('PASS: %s', msg) - - return char_lost - - def run(self): - """Run the stress test on UART port(s) - - Raises: - ChargenTestError: If any characters are lost. + tuple (options, args) where args is a list of cmdline arguments that the + parser was unable to match i.e. they're servod controls, not options. """ - - # Detect UART source type, and decide which command to test. - self.prepare() - - # Run the test on each UART port in thread. - self.logger.info('Test starts') - for _, ser in self.serials.items(): - ser.start_test() - - # Wait all tests to finish. - for _, ser in self.serials.items(): - ser.wait_test_done() - - # Print the result. - char_lost = self.print_result() - if char_lost: - raise ChargenTestError('Test failed: lost %d character(s)' % - char_lost) - - self.logger.info('Test is done') - -def parse_args(cmdline): - """Parse command line arguments. - - Args: - cmdline: list to be parsed - - Returns: - tuple (options, args) where args is a list of cmdline arguments that the - parser was unable to match i.e. they're servod controls, not options. - """ - description = """%(prog)s repeats sending a uart console command + description = """%(prog)s repeats sending a uart console command to each UART device for a given time, and check if output has any missing characters. @@ -511,52 +549,74 @@ Examples: %(prog)s /dev/ttyUSB1 /dev/ttyUSB2 --cr50 """ - parser = argparse.ArgumentParser(description=description, - formatter_class=argparse.RawTextHelpFormatter - ) - parser.add_argument('port', type=str, nargs='*', - help='UART device path to test') - parser.add_argument('-c', '--cr50', action='store_true', default=False, - help='generate TPM workload on cr50') - parser.add_argument('-d', '--debug', action='store_true', default=False, - help='enable debug messages') - parser.add_argument('-t', '--time', type=int, - help='Test duration in second', default=300) - parser.add_argument('-u', '--usb', action='store_true', default=False, - help='Generate output to USB channel instead') - return parser.parse_known_args(cmdline) + parser = argparse.ArgumentParser( + description=description, formatter_class=argparse.RawTextHelpFormatter + ) + parser.add_argument( + "port", type=str, nargs="*", help="UART device path to test" + ) + parser.add_argument( + "-c", + "--cr50", + action="store_true", + default=False, + help="generate TPM workload on cr50", + ) + parser.add_argument( + "-d", + "--debug", + action="store_true", + default=False, + help="enable debug messages", + ) + parser.add_argument( + "-t", "--time", type=int, help="Test duration in second", default=300 + ) + parser.add_argument( + "-u", + "--usb", + action="store_true", + default=False, + help="Generate output to USB channel instead", + ) + return parser.parse_known_args(cmdline) def main(): - """Main function wrapper""" - try: - (options, _) = parse_args(sys.argv[1:]) - - # Set Log format - log_format = '%(asctime)s %(levelname)-6s | %(name)-25s' - date_format = '%Y-%m-%d %H:%M:%S' - if options.debug: - log_format += ' | %(filename)s:%(lineno)4d:%(funcName)-18s' - loglevel = logging.DEBUG - else: - loglevel = logging.INFO - log_format += ' | %(message)s' - - logging.basicConfig(level=loglevel, format=log_format, - datefmt=date_format) - - # Create a ChargenTest object - utest = ChargenTest(options.port, options.time, - cr50_workload=options.cr50, - usb_output=options.usb) - utest.run() # Run - - except KeyboardInterrupt: - sys.exit(0) - - except ChargenTestError as e: - logging.error(str(e)) - sys.exit(1) - -if __name__ == '__main__': - main() + """Main function wrapper""" + try: + (options, _) = parse_args(sys.argv[1:]) + + # Set Log format + log_format = "%(asctime)s %(levelname)-6s | %(name)-25s" + date_format = "%Y-%m-%d %H:%M:%S" + if options.debug: + log_format += " | %(filename)s:%(lineno)4d:%(funcName)-18s" + loglevel = logging.DEBUG + else: + loglevel = logging.INFO + log_format += " | %(message)s" + + logging.basicConfig( + level=loglevel, format=log_format, datefmt=date_format + ) + + # Create a ChargenTest object + utest = ChargenTest( + options.port, + options.time, + cr50_workload=options.cr50, + usb_output=options.usb, + ) + utest.run() # Run + + except KeyboardInterrupt: + sys.exit(0) + + except ChargenTestError as e: + logging.error(str(e)) + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/util/unpack_ftb.py b/util/unpack_ftb.py index 03127a7089..4873190fb3 100755 --- a/util/unpack_ftb.py +++ b/util/unpack_ftb.py @@ -1,35 +1,33 @@ #!/usr/bin/env python -# Copyright 2018 The Chromium OS Authors. All rights reserved. +# Copyright 2018 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -# -# Ignore indention messages, since legacy scripts use 2 spaces instead of 4. -# pylint: disable=bad-indentation,docstring-section-indent -# pylint: disable=docstring-trailing-quotes # Note: This is a py2/3 compatible file. from __future__ import print_function + import argparse import ctypes import os class Header(ctypes.Structure): - _pack_ = 1 - _fields_ = [ - ('signature', ctypes.c_uint32), - ('ftb_ver', ctypes.c_uint32), - ('chip_id', ctypes.c_uint32), - ('svn_ver', ctypes.c_uint32), - ('fw_ver', ctypes.c_uint32), - ('config_id', ctypes.c_uint32), - ('config_ver', ctypes.c_uint32), - ('reserved', ctypes.c_uint8 * 8), - ('release_info', ctypes.c_ulonglong), - ('sec_size', ctypes.c_uint32 * 4), - ('crc', ctypes.c_uint32), - ] + _pack_ = 1 + _fields_ = [ + ("signature", ctypes.c_uint32), + ("ftb_ver", ctypes.c_uint32), + ("chip_id", ctypes.c_uint32), + ("svn_ver", ctypes.c_uint32), + ("fw_ver", ctypes.c_uint32), + ("config_id", ctypes.c_uint32), + ("config_ver", ctypes.c_uint32), + ("reserved", ctypes.c_uint8 * 8), + ("release_info", ctypes.c_ulonglong), + ("sec_size", ctypes.c_uint32 * 4), + ("crc", ctypes.c_uint32), + ] + FW_HEADER_SIZE = 64 FW_HEADER_SIGNATURE = 0xAA55AA55 @@ -44,7 +42,7 @@ FLASH_SEC_ADDR = [ 0x0000 * 4, # CODE 0x7C00 * 4, # CONFIG 0x7000 * 4, # CX - None # This section shouldn't exist + None, # This section shouldn't exist ] UPDATE_PDU_SIZE = 4096 @@ -59,64 +57,66 @@ OUTPUT_FILE_SIZE = UPDATE_PDU_SIZE + 128 * 1024 def main(): - parser = argparse.ArgumentParser() - parser.add_argument('--input', '-i', required=True) - parser.add_argument('--output', '-o', required=True) - args = parser.parse_args() + parser = argparse.ArgumentParser() + parser.add_argument("--input", "-i", required=True) + parser.add_argument("--output", "-o", required=True) + args = parser.parse_args() - with open(args.input, 'rb') as f: - bs = f.read() + with open(args.input, "rb") as f: + bs = f.read() - size = len(bs) - if size < FW_HEADER_SIZE + FW_BYTES_ALIGN: - raise Exception('FW size too small') + size = len(bs) + if size < FW_HEADER_SIZE + FW_BYTES_ALIGN: + raise Exception("FW size too small") - print('FTB file size:', size) + print("FTB file size:", size) - header = Header() - assert ctypes.sizeof(header) == FW_HEADER_SIZE + header = Header() + assert ctypes.sizeof(header) == FW_HEADER_SIZE - ctypes.memmove(ctypes.addressof(header), bs, ctypes.sizeof(header)) - if (header.signature != FW_HEADER_SIGNATURE or - header.ftb_ver != FW_FTB_VER or - header.chip_id != FW_CHIP_ID): - raise Exception('Invalid header') + ctypes.memmove(ctypes.addressof(header), bs, ctypes.sizeof(header)) + if ( + header.signature != FW_HEADER_SIGNATURE + or header.ftb_ver != FW_FTB_VER + or header.chip_id != FW_CHIP_ID + ): + raise Exception("Invalid header") - for key, _ in header._fields_: - v = getattr(header, key) - if isinstance(v, ctypes.Array): - print(key, list(map(hex, v))) - else: - print(key, hex(v)) + for key, _ in header._fields_: + v = getattr(header, key) + if isinstance(v, ctypes.Array): + print(key, list(map(hex, v))) + else: + print(key, hex(v)) - dimension = sum(header.sec_size) + dimension = sum(header.sec_size) - assert dimension + FW_HEADER_SIZE + FW_BYTES_ALIGN == size - data = bs[FW_HEADER_SIZE:FW_HEADER_SIZE + dimension] + assert dimension + FW_HEADER_SIZE + FW_BYTES_ALIGN == size + data = bs[FW_HEADER_SIZE : FW_HEADER_SIZE + dimension] - with open(args.output, 'wb') as f: - # ensure the file size - f.seek(OUTPUT_FILE_SIZE - 1, os.SEEK_SET) - f.write(b'\x00') + with open(args.output, "wb") as f: + # ensure the file size + f.seek(OUTPUT_FILE_SIZE - 1, os.SEEK_SET) + f.write(b"\x00") - f.seek(0, os.SEEK_SET) - f.write(bs[0 : ctypes.sizeof(header)]) + f.seek(0, os.SEEK_SET) + f.write(bs[0 : ctypes.sizeof(header)]) - offset = 0 - # write each sections - for i, addr in enumerate(FLASH_SEC_ADDR): - size = header.sec_size[i] - assert addr is not None or size == 0 + offset = 0 + # write each sections + for i, addr in enumerate(FLASH_SEC_ADDR): + size = header.sec_size[i] + assert addr is not None or size == 0 - if size == 0: - continue + if size == 0: + continue - f.seek(UPDATE_PDU_SIZE + addr, os.SEEK_SET) - f.write(data[offset : offset + size]) - offset += size + f.seek(UPDATE_PDU_SIZE + addr, os.SEEK_SET) + f.write(data[offset : offset + size]) + offset += size - f.flush() + f.flush() -if __name__ == '__main__': - main() +if __name__ == "__main__": + main() diff --git a/util/update_release_branch.py b/util/update_release_branch.py index b9063d4970..0a871724fe 100755 --- a/util/update_release_branch.py +++ b/util/update_release_branch.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Copyright 2021 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Release branch updater tool. @@ -19,11 +19,10 @@ import subprocess import sys import textwrap +BUG_NONE_PATTERN = re.compile("none", flags=re.IGNORECASE) -BUG_NONE_PATTERN = re.compile('none', flags=re.IGNORECASE) - -def git_commit_msg(branch, head, merge_head, rel_paths, cmd): +def git_commit_msg(cros_main, branch, head, merge_head, rel_paths, cmd): """Generates a merge commit message based off of relevant changes. This function obtains the relevant commits from the given relative paths in @@ -31,6 +30,7 @@ def git_commit_msg(branch, head, merge_head, rel_paths, cmd): showing the command used to find the relevant commits. Args: + cros_main: String indicating the origin branch name branch: String indicating the release branch name head: String indicating the HEAD refspec merge_head: String indicating the merge branch refspec. @@ -42,18 +42,17 @@ def git_commit_msg(branch, head, merge_head, rel_paths, cmd): A String containing the git commit message with the exception of the Signed-Off-By field and Change-ID field. """ - relevant_commits_cmd, relevant_commits = get_relevant_commits(head, - merge_head, - '--oneline', - rel_paths) + relevant_commits_cmd, relevant_commits = get_relevant_commits( + head, merge_head, "--oneline", rel_paths + ) - _, relevant_bugs = get_relevant_commits(head, merge_head, '', rel_paths) - relevant_bugs = set(re.findall('BUG=(.*)', relevant_bugs)) + _, relevant_bugs = get_relevant_commits(head, merge_head, "", rel_paths) + relevant_bugs = set(re.findall("BUG=(.*)", relevant_bugs)) # Filter out "none" from set of bugs filtered = [] for bug_line in relevant_bugs: - bug_line = bug_line.replace(',', ' ') - bugs = bug_line.split(' ') + bug_line = bug_line.replace(",", " ") + bugs = bug_line.split(" ") for bug in bugs: if bug and not BUG_NONE_PATTERN.match(bug): filtered.append(bug) @@ -61,8 +60,8 @@ def git_commit_msg(branch, head, merge_head, rel_paths, cmd): # TODO(b/179509333): remove Cq-Include-Trybots line when regular CQ and # firmware CQ do not behave differently. - COMMIT_MSG_TEMPLATE = """ -Merge remote-tracking branch cros/main into {BRANCH} + commit_msg_template = """ +Merge remote-tracking branch {CROS_MAIN} into {BRANCH} Generated by: {COMMAND_LINE} @@ -76,24 +75,27 @@ BRANCH=None {BUG_FIELD} TEST=`make -j buildall` -Cq-Include-Trybots: chromeos/cq:cq-orchestrator +Force-Relevant-Builds: all """ - # Wrap the relevant commits command and bug field such that we don't exceed - # 72 cols. + # Wrap the commands and bug field such that we don't exceed 72 cols. relevant_commits_cmd = textwrap.fill(relevant_commits_cmd, width=72) + cmd = textwrap.fill(cmd, width=72) # Wrap at 68 cols to save room for 'BUG=' - bugs = textwrap.wrap(' '.join(relevant_bugs), width=68) - bug_field = '' + bugs = textwrap.wrap(" ".join(relevant_bugs), width=68) + bug_field = "" for line in bugs: - bug_field += 'BUG=' + line + '\n' + bug_field += "BUG=" + line + "\n" # Remove the final newline since the template adds it for us. bug_field = bug_field[:-1] - return COMMIT_MSG_TEMPLATE.format(BRANCH=branch, - RELEVANT_COMMITS_CMD=relevant_commits_cmd, - RELEVANT_COMMITS=relevant_commits, - BUG_FIELD=bug_field, - COMMAND_LINE=cmd) + return commit_msg_template.format( + CROS_MAIN=cros_main, + BRANCH=branch, + RELEVANT_COMMITS_CMD=relevant_commits_cmd, + RELEVANT_COMMITS=relevant_commits, + BUG_FIELD=bug_field, + COMMAND_LINE=cmd, + ) def get_relevant_boards(baseboard): @@ -105,15 +107,16 @@ def get_relevant_boards(baseboard): Returns: A list of strings containing the boards based off of the baseboard. """ - proc = subprocess.run(['git', 'grep', 'BASEBOARD:=' + baseboard, '--', - 'board/'], - stdout=subprocess.PIPE, - encoding='utf-8', - check=True) + proc = subprocess.run( + ["git", "grep", "BASEBOARD:=" + baseboard, "--", "board/"], + stdout=subprocess.PIPE, + encoding="utf-8", + check=True, + ) boards = [] res = proc.stdout.splitlines() for line in res: - boards.append(line.split('/')[1]) + boards.append(line.split("/")[1]) return boards @@ -135,21 +138,25 @@ def get_relevant_commits(head, merge_head, fmt, relevant_paths): stdout. """ if fmt: - cmd = ['git', 'log', fmt, head + '..' + merge_head, '--', - relevant_paths] + cmd = [ + "git", + "log", + fmt, + head + ".." + merge_head, + "--", + relevant_paths, + ] else: - cmd = ['git', 'log', head + '..' + merge_head, '--', relevant_paths] + cmd = ["git", "log", head + ".." + merge_head, "--", relevant_paths] # Pass cmd as a string to subprocess.run() since we need to run with shell # equal to True. The reason we are using shell equal to True is to take # advantage of the glob expansion for the relevant paths. - cmd = ' '.join(cmd) - proc = subprocess.run(cmd, - stdout=subprocess.PIPE, - encoding='utf-8', - check=True, - shell=True) - return ''.join(proc.args), proc.stdout + cmd = " ".join(cmd) + proc = subprocess.run( + cmd, stdout=subprocess.PIPE, encoding="utf-8", check=True, shell=True + ) + return "".join(proc.args), proc.stdout def main(argv): @@ -165,112 +172,235 @@ def main(argv): argv: A list of the command line arguments passed to this script. """ # Set up argument parser. - parser = argparse.ArgumentParser(description=('A script that generates a ' - 'merge commit from cros/main' - ' to a desired release ' - 'branch. By default, the ' - '"recursive" merge strategy ' - 'with the "theirs" strategy ' - 'option is used.')) - parser.add_argument('--baseboard') - parser.add_argument('--board') - parser.add_argument('release_branch', help=('The name of the target release' - ' branch')) - parser.add_argument('--relevant_paths_file', - help=('A path to a text file which includes other ' - 'relevant paths of interest for this board ' - 'or baseboard')) - parser.add_argument('--merge_strategy', '-s', default='recursive', - help='The merge strategy to pass to `git merge -s`') - parser.add_argument('--strategy_option', '-X', - help=('The strategy option for the chosen merge ' - 'strategy')) + parser = argparse.ArgumentParser( + description=( + "A script that generates a " + "merge commit from cros/main" + " to a desired release " + "branch. By default, the " + '"recursive" merge strategy ' + 'with the "theirs" strategy ' + "option is used." + ) + ) + parser.add_argument("--baseboard") + parser.add_argument("--board") + parser.add_argument( + "release_branch", help=("The name of the target release" " branch") + ) + parser.add_argument( + "--remote_prefix", + help=( + "The name of the remote branch prefix (default cros). " + "Private repos typically use cros-internal instead." + ), + default="cros", + ) + parser.add_argument( + "--relevant_paths_file", + help=( + "A path to a text file which includes other " + "relevant paths of interest for this board " + "or baseboard" + ), + ) + parser.add_argument( + "--merge_strategy", + "-s", + default="recursive", + help="The merge strategy to pass to `git merge -s`", + ) + parser.add_argument( + "--strategy_option", + "-X", + help=("The strategy option for the chosen merge " "strategy"), + ) + parser.add_argument( + "--remove_owners", + "-r", + action=("store_true"), + help=("Remove non-root OWNERS level files if present"), + ) opts = parser.parse_args(argv[1:]) - baseboard_dir = '' - board_dir = '' + baseboard_dir = "" + board_dir = "" if opts.baseboard: # Dereference symlinks so "git log" works as expected. - baseboard_dir = os.path.relpath('baseboard/' + opts.baseboard) + baseboard_dir = os.path.relpath("baseboard/" + opts.baseboard) baseboard_dir = os.path.relpath(os.path.realpath(baseboard_dir)) boards = get_relevant_boards(opts.baseboard) elif opts.board: - board_dir = os.path.relpath('board/' + opts.board) + board_dir = os.path.relpath("board/" + opts.board) board_dir = os.path.relpath(os.path.realpath(board_dir)) boards = [opts.board] else: - parser.error('You must specify a board OR a baseboard') + boards = [] - print('Gathering relevant paths...') + print("Gathering relevant paths...") relevant_paths = [] if opts.baseboard: relevant_paths.append(baseboard_dir) - else: + elif opts.board: relevant_paths.append(board_dir) for board in boards: - relevant_paths.append('board/' + board) + relevant_paths.append("board/" + board) # Check for the existence of a file that has other paths of interest. if opts.relevant_paths_file and os.path.exists(opts.relevant_paths_file): - with open(opts.relevant_paths_file, 'r') as relevant_paths_file: + with open(opts.relevant_paths_file, "r") as relevant_paths_file: for line in relevant_paths_file: - if not line.startswith('#'): + if not line.startswith("#"): relevant_paths.append(line.rstrip()) - relevant_paths.append('util/getversion.sh') - relevant_paths = ' '.join(relevant_paths) + if os.path.exists("util/getversion.sh"): + relevant_paths.append("util/getversion.sh") + relevant_paths = " ".join(relevant_paths) # Check if we are already in merge process - result = subprocess.run(['git', 'rev-parse', '--quiet', '--verify', - 'MERGE_HEAD'], stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL, check=False) + result = subprocess.run( + ["git", "rev-parse", "--quiet", "--verify", "MERGE_HEAD"], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + check=False, + ) + + # Prune OWNERS files if desired + if opts.remove_owners: + prunelist = [] + for root, dirs, files in os.walk("."): + for name in dirs: + if "build" in name: + continue + for name in files: + if "OWNERS" in name: + path = os.path.join(root, name) + prunelist.append(path[2:]) # Strip the "./" + + # Remove the top level OWNERS file from the prunelist. + try: + prunelist.remove("OWNERS") + except ValueError: + pass + + if prunelist: + print("Not merging the following OWNERS files:") + for path in prunelist: + print(" " + path) + if result.returncode: # Let's perform the merge - print('Updating remote...') - subprocess.run(['git', 'remote', 'update'], check=True) - subprocess.run(['git', 'checkout', '-B', opts.release_branch, 'cros/' + - opts.release_branch], check=True) - print('Attempting git merge...') - if opts.merge_strategy == 'recursive' and not opts.strategy_option: - opts.strategy_option = 'theirs' - print('Using "%s" merge strategy' % opts.merge_strategy, - ("with strategy option '%s'" % opts.strategy_option - if opts.strategy_option else '')) - arglist = ['git', 'merge', '--no-ff', '--no-commit', 'cros/main', '-s', - opts.merge_strategy] + print("Updating remote...") + subprocess.run(["git", "remote", "update"], check=True) + subprocess.run( + [ + "git", + "checkout", + "-B", + opts.release_branch, + opts.remote_prefix + "/" + opts.release_branch, + ], + check=True, + ) + print("Attempting git merge...") + if opts.merge_strategy == "recursive" and not opts.strategy_option: + opts.strategy_option = "theirs" + print( + 'Using "%s" merge strategy' % opts.merge_strategy, + ( + "with strategy option '%s'" % opts.strategy_option + if opts.strategy_option + else "" + ), + ) + cros_main = opts.remote_prefix + "/" + "main" + arglist = [ + "git", + "merge", + "--no-ff", + "--no-commit", + cros_main, + "-s", + opts.merge_strategy, + ] if opts.strategy_option: - arglist.append('-X' + opts.strategy_option) - subprocess.run(arglist, check=True) + arglist.append("-X" + opts.strategy_option) + try: + subprocess.run(arglist, check=True) + except: + # We've likely encountered a merge conflict due to new OWNERS file + # modifications. If we're removing the owners, we'll delete them. + if opts.remove_owners and prunelist: + # Find the unmerged files + unmerged = ( + subprocess.run( + ["git", "diff", "--name-only", "--diff-filter=U"], + stdout=subprocess.PIPE, + encoding="utf-8", + check=True, + ) + .stdout.rstrip() + .split() + ) + + # Prune OWNERS files + for file in unmerged: + if file in prunelist: + subprocess.run(["git", "rm", file], check=False) + unmerged.remove(file) + + print("Removed non-root OWNERS files.") + if unmerged: + print( + "Unmerged files still exist! You need to manually resolve this." + ) + print("\n".join(unmerged)) + sys.exit(1) + else: + raise else: - print('We have already started merge process.', - 'Attempt to generate commit.') - - print('Generating commit message...') - branch = subprocess.run(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], - stdout=subprocess.PIPE, - encoding='utf-8', - check=True).stdout.rstrip() - head = subprocess.run(['git', 'rev-parse', '--short', 'HEAD'], - stdout=subprocess.PIPE, - encoding='utf-8', - check=True).stdout.rstrip() - merge_head = subprocess.run(['git', 'rev-parse', '--short', - 'MERGE_HEAD'], - stdout=subprocess.PIPE, - encoding='utf-8', - check=True).stdout.rstrip() - - cmd = ' '.join(argv) - print('Typing as fast as I can...') - commit_msg = git_commit_msg(branch, head, merge_head, relevant_paths, cmd) - subprocess.run(['git', 'commit', '--signoff', '-m', commit_msg], check=True) - subprocess.run(['git', 'commit', '--amend'], check=True) - print(("Finished! **Please review the commit to see if it's to your " - 'liking.**')) - - -if __name__ == '__main__': + print( + "We have already started merge process.", + "Attempt to generate commit.", + ) + + print("Generating commit message...") + branch = subprocess.run( + ["git", "rev-parse", "--abbrev-ref", "HEAD"], + stdout=subprocess.PIPE, + encoding="utf-8", + check=True, + ).stdout.rstrip() + head = subprocess.run( + ["git", "rev-parse", "--short", "HEAD"], + stdout=subprocess.PIPE, + encoding="utf-8", + check=True, + ).stdout.rstrip() + merge_head = subprocess.run( + ["git", "rev-parse", "--short", "MERGE_HEAD"], + stdout=subprocess.PIPE, + encoding="utf-8", + check=True, + ).stdout.rstrip() + + cmd = " ".join(argv) + print("Typing as fast as I can...") + commit_msg = git_commit_msg( + cros_main, branch, head, merge_head, relevant_paths, cmd + ) + subprocess.run(["git", "commit", "--signoff", "-m", commit_msg], check=True) + subprocess.run(["git", "commit", "--amend"], check=True) + print( + ( + "Finished! **Please review the commit to see if it's to your " + "liking.**" + ) + ) + + +if __name__ == "__main__": main(sys.argv) diff --git a/util/usb_if.c b/util/usb_if.c index f8aa6bfd7e..0cd642834a 100644 --- a/util/usb_if.c +++ b/util/usb_if.c @@ -1,5 +1,5 @@ /* - * Copyright 2018 The Chromium OS Authors. All rights reserved. + * Copyright 2018 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -12,16 +12,14 @@ /* Return 0 on error, since it's never gonna be EP 0 */ static int find_endpoint(const struct libusb_interface_descriptor *iface, - uint16_t subclass, - uint16_t protocol, + uint16_t subclass, uint16_t protocol, struct usb_endpoint *uep) { const struct libusb_endpoint_descriptor *ep; if (iface->bInterfaceClass == 255 && iface->bInterfaceSubClass == subclass && - iface->bInterfaceProtocol == protocol && - iface->bNumEndpoints) { + iface->bInterfaceProtocol == protocol && iface->bNumEndpoints) { ep = &iface->endpoint[0]; uep->ep_num = ep->bEndpointAddress & 0x7f; uep->chunk_len = ep->wMaxPacketSize; @@ -32,8 +30,7 @@ static int find_endpoint(const struct libusb_interface_descriptor *iface, } /* Return -1 on error */ -static int find_interface(uint16_t subclass, - uint16_t protocol, +static int find_interface(uint16_t subclass, uint16_t protocol, struct usb_endpoint *uep) { int iface_num = -1; @@ -66,8 +63,8 @@ out: return iface_num; } -static libusb_device_handle *check_device(libusb_device *dev, - uint16_t vid, uint16_t pid, const char *serial) +static libusb_device_handle *check_device(libusb_device *dev, uint16_t vid, + uint16_t pid, const char *serial) { struct libusb_device_descriptor desc; libusb_device_handle *handle = NULL; @@ -81,18 +78,17 @@ static libusb_device_handle *check_device(libusb_device *dev, return NULL; if (desc.iSerialNumber && serial) { - sn_size = libusb_get_string_descriptor_ascii(handle, - desc.iSerialNumber, (unsigned char *)sn, - sizeof(sn)); + sn_size = libusb_get_string_descriptor_ascii( + handle, desc.iSerialNumber, (unsigned char *)sn, + sizeof(sn)); } /* * If the VID, PID, and serial number don't match, then it's not the * correct device. Close the handle and return NULL. */ - if ((vid && vid != desc.idVendor) || - (pid && pid != desc.idProduct) || - (serial && ((sn_size != strlen(serial)) || - memcmp(sn, serial, sn_size)))) { + if ((vid && vid != desc.idVendor) || (pid && pid != desc.idProduct) || + (serial && + ((sn_size != strlen(serial)) || memcmp(sn, serial, sn_size)))) { libusb_close(handle); return NULL; } @@ -156,8 +152,8 @@ int usb_findit(const char *serial, uint16_t vid, uint16_t pid, goto terminate_usb_findit; } - printf("found interface %d endpoint %d, chunk_len %d\n", - iface_num, uep->ep_num, uep->chunk_len); + printf("found interface %d endpoint %d, chunk_len %d\n", iface_num, + uep->ep_num, uep->chunk_len); libusb_set_auto_detach_kernel_driver(uep->devh, 1); r = libusb_claim_interface(uep->devh, iface_num); @@ -175,17 +171,15 @@ terminate_usb_findit: return -1; } -int usb_trx(struct usb_endpoint *uep, void *outbuf, int outlen, - void *inbuf, int inlen, int allow_less, size_t *rxed_count) +int usb_trx(struct usb_endpoint *uep, void *outbuf, int outlen, void *inbuf, + int inlen, int allow_less, size_t *rxed_count) { - int r, actual; /* Send data out */ if (outbuf && outlen) { actual = 0; - r = libusb_bulk_transfer(uep->devh, uep->ep_num, - outbuf, outlen, + r = libusb_bulk_transfer(uep->devh, uep->ep_num, outbuf, outlen, &actual, 1000); if (r < 0) { USB_ERROR("libusb_bulk_transfer", r); @@ -200,11 +194,9 @@ int usb_trx(struct usb_endpoint *uep, void *outbuf, int outlen, /* Read reply back */ if (inbuf && inlen) { - actual = 0; - r = libusb_bulk_transfer(uep->devh, uep->ep_num | 0x80, - inbuf, inlen, - &actual, 1000); + r = libusb_bulk_transfer(uep->devh, uep->ep_num | 0x80, inbuf, + inlen, &actual, 1000); if (r < 0) { USB_ERROR("libusb_bulk_transfer", r); return -1; diff --git a/util/usb_if.h b/util/usb_if.h index 8cc1088c6e..37a33f6287 100644 --- a/util/usb_if.h +++ b/util/usb_if.h @@ -1,5 +1,5 @@ /* - * Copyright 2018 The Chromium OS Authors. All rights reserved. + * Copyright 2018 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -13,7 +13,7 @@ struct usb_endpoint { struct libusb_device_handle *devh; uint8_t ep_num; - int chunk_len; + int chunk_len; }; /* @@ -34,9 +34,8 @@ int usb_findit(const char *serialno, uint16_t vid, uint16_t pid, * pointer, if provided along with 'allow_less', lets the caller know how many * bytes were received. */ -int usb_trx(struct usb_endpoint *uep, void *outbuf, int outlen, - void *inbuf, int inlen, int allow_less, - size_t *rxed_count); +int usb_trx(struct usb_endpoint *uep, void *outbuf, int outlen, void *inbuf, + int inlen, int allow_less, size_t *rxed_count); /* * This function should be called for graceful tear down of the USB interface @@ -46,8 +45,8 @@ int usb_trx(struct usb_endpoint *uep, void *outbuf, int outlen, */ void usb_shut_down(struct usb_endpoint *uep); -#define USB_ERROR(m, r) \ - fprintf(stderr, "%s:%d, %s returned %d (%s)\n", __FILE__, __LINE__, \ - m, r, libusb_strerror(r)) +#define USB_ERROR(m, r) \ + fprintf(stderr, "%s:%d, %s returned %d (%s)\n", __FILE__, __LINE__, m, \ + r, libusb_strerror(r)) -#endif /* ! __EC_EXTRA_USB_UPDATER_USB_IF_H */ +#endif /* ! __EC_EXTRA_USB_UPDATER_USB_IF_H */ diff --git a/util/uut/cmd.c b/util/uut/cmd.c index 57cf75a29e..02810b686a 100644 --- a/util/uut/cmd.c +++ b/util/uut/cmd.c @@ -1,5 +1,5 @@ /* - * Copyright 2018 The Chromium OS Authors. All rights reserved. + * Copyright 2018 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -14,7 +14,7 @@ #include "lib_crc.h" #include "main.h" - /* Extracting Byte - 8 bit: MSB, LSB */ +/* Extracting Byte - 8 bit: MSB, LSB */ #define MSB(u16) ((uint8_t)((uint16_t)(u16) >> 8)) #define LSB(u16) ((uint8_t)(u16)) @@ -85,7 +85,7 @@ void cmd_create_sync(uint8_t *cmd_info, uint32_t *cmd_len) *--------------------------------------------------------------------------- */ void cmd_create_write(uint32_t addr, uint32_t size, uint8_t *data_buf, - uint8_t *cmd_info, uint32_t *cmd_len) + uint8_t *cmd_info, uint32_t *cmd_len) { uint32_t i; union cmd_addr adr_tr; @@ -136,7 +136,7 @@ void cmd_create_write(uint32_t addr, uint32_t size, uint8_t *data_buf, *--------------------------------------------------------------------------- */ void cmd_create_read(uint32_t addr, uint8_t size, uint8_t *cmd_info, - uint32_t *cmd_len) + uint32_t *cmd_len) { uint32_t i; union cmd_addr adr_tr; @@ -251,7 +251,7 @@ void cmd_build_sync(struct command_node *cmd_buf, uint32_t *cmd_num) *--------------------------------------------------------------------------- */ void cmd_build_exec_exit(uint32_t addr, struct command_node *cmd_buf, - uint32_t *cmd_num) + uint32_t *cmd_num) { uint32_t cmd = 0; @@ -280,7 +280,7 @@ void cmd_build_exec_exit(uint32_t addr, struct command_node *cmd_buf, *--------------------------------------------------------------------------- */ void cmd_build_exec_ret(uint32_t addr, struct command_node *cmd_buf, - uint32_t *cmd_num) + uint32_t *cmd_num) { uint32_t cmd = 0; @@ -325,10 +325,11 @@ bool cmd_disp_sync(uint8_t *resp_buf) *--------------------------------------------------------------------------- */ bool cmd_disp_write(uint8_t *resp_buf, uint32_t resp_size, uint32_t resp_num, - uint32_t total_size) + uint32_t total_size) { if (resp_buf[0] == (uint8_t)(UFPP_WRITE_CMD)) { - display_color_msg(SUCCESS, + display_color_msg( + SUCCESS, "\rTransmitted packet of size %u bytes, packet " "[%u]out of [%u]", resp_size, resp_num, total_size); @@ -352,10 +353,11 @@ bool cmd_disp_write(uint8_t *resp_buf, uint32_t resp_size, uint32_t resp_num, *--------------------------------------------------------------------------- */ bool cmd_disp_read(uint8_t *resp_buf, uint32_t resp_size, uint32_t resp_num, - uint32_t total_size) + uint32_t total_size) { if (resp_buf[0] == (uint8_t)(UFPP_READ_CMD)) { - display_color_msg(SUCCESS, + display_color_msg( + SUCCESS, "\rReceived packet of size %u bytes, packet [%u] out " "of [%u]", resp_size, resp_num, total_size); @@ -412,10 +414,11 @@ void cmd_disp_flash_erase_dev(uint8_t *resp_buf, uint32_t dev_num) { if (resp_buf[0] == (uint8_t)(UFPP_WRITE_CMD)) { display_color_msg(SUCCESS, - "Flash Erase of device [%u] Passed\n", dev_num); + "Flash Erase of device [%u] Passed\n", + dev_num); } else { - display_color_msg( - FAIL, "Flash Erase of device [%u] Failed\n", dev_num); + display_color_msg(FAIL, "Flash Erase of device [%u] Failed\n", + dev_num); } } @@ -433,10 +436,11 @@ void cmd_disp_flash_erase_sect(uint8_t *resp_buf, uint32_t dev_num) { if (resp_buf[0] == (uint8_t)(UFPP_WRITE_CMD)) { display_color_msg(SUCCESS, - "Sector Erase of device [%lu] Passed\n", dev_num); + "Sector Erase of device [%lu] Passed\n", + dev_num); } else { - display_color_msg( - FAIL, "Sector Erase of device [%lu] Failed\n", dev_num); + display_color_msg(FAIL, "Sector Erase of device [%lu] Failed\n", + dev_num); } } @@ -471,11 +475,13 @@ void cmd_disp_exec_exit(uint8_t *resp_buf) void cmd_disp_exec_ret(uint8_t *resp_buf) { if (resp_buf[1] == (uint8_t)(UFPP_FCALL_RSLT_CMD)) { - display_color_msg(SUCCESS, + display_color_msg( + SUCCESS, "Execute Command Passed, execution result is [0x%X]\n", resp_buf[2]); } else { - display_color_msg(FAIL, + display_color_msg( + FAIL, "Execute Command Failed [0x%X] [0x%X], rslt=[0x%X]\n", resp_buf[0], resp_buf[1], resp_buf[2]); } diff --git a/util/uut/cmd.h b/util/uut/cmd.h index 44cebbe989..cf8457000b 100644 --- a/util/uut/cmd.h +++ b/util/uut/cmd.h @@ -1,5 +1,5 @@ /* - * Copyright 2018 The Chromium OS Authors. All rights reserved. + * Copyright 2018 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -18,17 +18,17 @@ #define MAX_RESP_BUF_SIZE 512 enum uart_protocol_cmd { - UFPP_H2D_SYNC_CMD = 0x55, /* Single-Byte Host to Device */ - /* synchronization command */ - UFPP_D2H_SYNC_CMD = 0x5A, /* Single-Byte Device to Host */ - /* synchronization response */ - UFPP_WRITE_CMD = 0x07, /* Write command and response */ - UFPP_READ_CMD = 0x1C, /* Read command and response */ - UFPP_READ_CRC_CMD = 0x89, /* Read CRC command and response */ - UFPP_FCALL_CMD = 0x70, /* Call function command */ + UFPP_H2D_SYNC_CMD = 0x55, /* Single-Byte Host to Device */ + /* synchronization command */ + UFPP_D2H_SYNC_CMD = 0x5A, /* Single-Byte Device to Host */ + /* synchronization response */ + UFPP_WRITE_CMD = 0x07, /* Write command and response */ + UFPP_READ_CMD = 0x1C, /* Read command and response */ + UFPP_READ_CRC_CMD = 0x89, /* Read CRC command and response */ + UFPP_FCALL_CMD = 0x70, /* Call function command */ UFPP_FCALL_RSLT_CMD = 0x73, /* Call function response */ - UFPP_SPI_CMD = 0x92, /* SPI specific command */ - UFPP_ERROR_CMD = 0xFF /* Error response */ + UFPP_SPI_CMD = 0x92, /* SPI specific command */ + UFPP_ERROR_CMD = 0xFF /* Error response */ }; struct command_node { @@ -44,22 +44,22 @@ struct command_node { void cmd_create_sync(uint8_t *cmd_info, uint32_t *cmd_len); void cmd_create_write(uint32_t addr, uint32_t size, uint8_t *data_buf, - uint8_t *cmd_info, uint32_t *cmd_len); + uint8_t *cmd_info, uint32_t *cmd_len); void cmd_create_read(uint32_t addr, uint8_t size, uint8_t *cmd_info, - uint32_t *cmd_len); + uint32_t *cmd_len); void cmd_create_exec(uint32_t addr, uint8_t *cmd_info, uint32_t *cmd_len); void cmd_build_sync(struct command_node *cmd_buf, uint32_t *cmd_num); void cmd_build_exec_exit(uint32_t addr, struct command_node *cmd_buf, - uint32_t *cmd_num); + uint32_t *cmd_num); void cmd_build_exec_ret(uint32_t addr, struct command_node *cmd_buf, - uint32_t *cmd_num); + uint32_t *cmd_num); bool cmd_disp_sync(uint8_t *resp_buf); bool cmd_disp_write(uint8_t *resp_buf, uint32_t resp_size, uint32_t resp_num, - uint32_t total_size); + uint32_t total_size); bool cmd_disp_read(uint8_t *resp_buf, uint32_t resp_size, uint32_t resp_num, - uint32_t total_size); + uint32_t total_size); void cmd_disp_data(uint8_t *resp_buf, uint32_t resp_size); void cmd_disp_flash_erase_dev(uint8_t *resp_buf, uint32_t dev_num); void cmd_disp_flash_erase_sect(uint8_t *resp_buf, uint32_t dev_num); diff --git a/util/uut/com_port.h b/util/uut/com_port.h index 36331f2fb6..ca52bdd234 100644 --- a/util/uut/com_port.h +++ b/util/uut/com_port.h @@ -1,5 +1,5 @@ /* - * Copyright 2018 The Chromium OS Authors. All rights reserved. + * Copyright 2018 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -35,10 +35,10 @@ extern "C" { #define COMP_PORT_PREFIX_3 "pts" struct comport_fields { - uint32_t baudrate; /* Baudrate at which running */ - tcflag_t byte_size; /* Number of bits/byte, 4-8 */ - tcflag_t parity; /* 0-4=None,Odd,Even,Mark,Space */ - uint8_t stop_bits; /* 0,1,2 = 1, 1.5, 2 */ + uint32_t baudrate; /* Baudrate at which running */ + tcflag_t byte_size; /* Number of bits/byte, 4-8 */ + tcflag_t parity; /* 0-4=None,Odd,Even,Mark,Space */ + uint8_t stop_bits; /* 0,1,2 = 1, 1.5, 2 */ uint8_t flow_control; /* 0-none, 1-SwFlowControl,2-HwFlowControl */ }; @@ -60,7 +60,7 @@ struct comport_fields { *--------------------------------------------------------------------------- */ int com_port_open(const char *com_port_dev_name, - struct comport_fields com_port_fields); + struct comport_fields com_port_fields); /*--------------------------------------------------------------------------- * Function: int com_config_uart() @@ -110,7 +110,7 @@ bool com_port_close(int device_id); *--------------------------------------------------------------------------- */ bool com_port_write_bin(int device_id, const uint8_t *buffer, - uint32_t buf_size); + uint32_t buf_size); /*--------------------------------------------------------------------------- * Function: uint32_t com_port_read_bin() diff --git a/util/uut/l_com_port.c b/util/uut/l_com_port.c index 018dec9950..e774743160 100644 --- a/util/uut/l_com_port.c +++ b/util/uut/l_com_port.c @@ -1,5 +1,5 @@ /* - * Copyright 2018 The Chromium OS Authors. All rights reserved. + * Copyright 2018 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -100,7 +100,8 @@ void set_read_blocking(int dev_drv, bool block) memset(&tty, 0, sizeof(tty)); if (tcgetattr(dev_drv, &tty) != 0) { - display_color_msg(FAIL, + display_color_msg( + FAIL, "set_read_blocking Error: %d Fail to get attribute " "from Device number %d.\n", errno, dev_drv); @@ -111,7 +112,8 @@ void set_read_blocking(int dev_drv, bool block) tty.c_cc[VTIME] = 5; /* 0.5 seconds read timeout */ if (tcsetattr(dev_drv, TCSANOW, &tty) != 0) { - display_color_msg(FAIL, + display_color_msg( + FAIL, "set_read_blocking Error: %d Fail to set attribute to " "Device number %d.\n", errno, dev_drv); @@ -145,7 +147,8 @@ bool com_config_uart(int h_dev_drv, struct comport_fields com_port_fields) memset(&tty, 0, sizeof(tty)); if (tcgetattr(h_dev_drv, &tty) != 0) { - display_color_msg(FAIL, + display_color_msg( + FAIL, "com_config_uart Error: Fail to get attribute from " "Device number %d.\n", h_dev_drv); @@ -171,12 +174,13 @@ bool com_config_uart(int h_dev_drv, struct comport_fields com_port_fields) tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); tty.c_oflag = ~OPOST; - tty.c_cc[VMIN] = 0; /* read doesn't block */ + tty.c_cc[VMIN] = 0; /* read doesn't block */ tty.c_cc[VTIME] = 5; /* 0.5 seconds read timeout */ - tty.c_iflag |= (com_port_fields.flow_control == 0x01) - ? (IXON | IXOFF) - : 0x00; /* xon/xoff ctrl */ + tty.c_iflag |= (com_port_fields.flow_control == 0x01) ? + (IXON | IXOFF) : + 0x00; /* xon/xoff + ctrl */ tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */ /* enable reading */ @@ -191,7 +195,8 @@ bool com_config_uart(int h_dev_drv, struct comport_fields com_port_fields) tcflush(h_dev_drv, TCIFLUSH); if (tcsetattr(h_dev_drv, TCSANOW, &tty) != 0) { - display_color_msg(FAIL, + display_color_msg( + FAIL, "com_config_uart Error: %d setting port handle %d: %s.\n", errno, h_dev_drv, strerror(errno)); return false; @@ -221,7 +226,6 @@ static void discard_input(int fd) do { res = read(fd, buffer, sizeof(buffer)); if (res > 0) { - /* Discard zeros in the beginning of the buffer. */ for (i = 0; i < res; i++) if (buffer[i]) @@ -250,7 +254,6 @@ static void discard_input(int fd) printf("%d zeros ignored\n", count_of_zeros); } - /****************************************************************************** * Function: int com_port_open() * @@ -268,7 +271,7 @@ static void discard_input(int fd) ***************************************************************************** */ int com_port_open(const char *com_port_dev_name, - struct comport_fields com_port_fields) + struct comport_fields com_port_fields) { int port_handler; @@ -276,15 +279,16 @@ int com_port_open(const char *com_port_dev_name, if (port_handler < 0) { display_color_msg(FAIL, - "com_port_open Error %d opening %s: %s\n", - errno, com_port_dev_name, strerror(errno)); + "com_port_open Error %d opening %s: %s\n", + errno, com_port_dev_name, strerror(errno)); return INVALID_HANDLE_VALUE; } tcgetattr(port_handler, &savetty); if (!com_config_uart(port_handler, com_port_fields)) { - display_color_msg(FAIL, + display_color_msg( + FAIL, "com_port_open() Error %d, Failed on com_config_uart() %s, " "%s\n", errno, com_port_dev_name, strerror(errno)); @@ -318,7 +322,8 @@ bool com_port_close(int device_id) tcsetattr(device_id, TCSANOW, &savetty); if (close(device_id) == INVALID_HANDLE_VALUE) { - display_color_msg(FAIL, + display_color_msg( + FAIL, "com_port_close() Error: %d Device com%u was not opened, " "%s.\n", errno, (uint32_t)device_id, strerror(errno)); @@ -345,14 +350,14 @@ bool com_port_close(int device_id) * ***************************************************************************** */ -bool com_port_write_bin(int device_id, const uint8_t *buffer, - uint32_t buf_size) +bool com_port_write_bin(int device_id, const uint8_t *buffer, uint32_t buf_size) { uint32_t bytes_written; bytes_written = write(device_id, buffer, buf_size); if (bytes_written != buf_size) { - display_color_msg(FAIL, + display_color_msg( + FAIL, "com_port_write_bin() Error: %d Failed to write data to " "Uart Port %d, %s.\n", errno, (uint32_t)device_id, strerror(errno)); @@ -389,9 +394,10 @@ uint32_t com_port_read_bin(int device_id, uint8_t *buffer, uint32_t buf_size) if (read_bytes == -1) { display_color_msg(FAIL, - "%s() Error: %d Device number %u was not " - "opened, %s.\n", - __func__, errno, (uint32_t)device_id, strerror(errno)); + "%s() Error: %d Device number %u was not " + "opened, %s.\n", + __func__, errno, (uint32_t)device_id, + strerror(errno)); } return read_bytes; @@ -422,9 +428,9 @@ uint32_t com_port_wait_read(int device_id) fds.events = POLLIN; ret_val = poll(&fds, 1, COMMAND_TIMEOUT); if (ret_val < 0) { - display_color_msg(FAIL, - "%s() Error: %d Device number %u %s\n", - __func__, errno, (uint32_t)device_id, strerror(errno)); + display_color_msg(FAIL, "%s() Error: %d Device number %u %s\n", + __func__, errno, (uint32_t)device_id, + strerror(errno)); return 0; } @@ -434,7 +440,8 @@ uint32_t com_port_wait_read(int device_id) if (ret_val > 0) { /* Get number of bytes that are ready to be read. */ if (ioctl(device_id, FIONREAD, &bytes) < 0) { - display_color_msg(FAIL, + display_color_msg( + FAIL, "com_port_wait_for_read() Error: %d Device number " "%u %s\n", errno, (uint32_t)device_id, strerror(errno)); diff --git a/util/uut/lib_crc.c b/util/uut/lib_crc.c index 176e91327c..ae83581063 100644 --- a/util/uut/lib_crc.c +++ b/util/uut/lib_crc.c @@ -1,5 +1,5 @@ /* - * Copyright 2018 The Chromium OS Authors. All rights reserved. + * Copyright 2018 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -54,38 +54,35 @@ /* CRC16 lookup table for polynom 0xA001 */ static const unsigned short crc16_tab[256] = { - 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, - 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, - 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, - 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, - 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, - 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, - 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, - 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, - 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, - 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, - 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, - 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, - 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, - 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, - 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, - 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, - 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, - 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, - 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, - 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, - 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, - 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, - 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, - 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, - 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, - 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, - 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, - 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, - 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, - 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, - 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, - 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, + 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, + 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, + 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, + 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, + 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, + 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, + 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, + 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, + 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, + 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, + 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, + 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, + 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, + 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, + 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, + 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, + 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, + 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, + 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, + 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, + 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, + 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, + 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, + 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, + 0x4100, 0x81C1, 0x8081, 0x4040 }; /********************************************************************* diff --git a/util/uut/lib_crc.h b/util/uut/lib_crc.h index 58db81c4e5..7d75c9b501 100644 --- a/util/uut/lib_crc.h +++ b/util/uut/lib_crc.h @@ -1,5 +1,5 @@ /* - * Copyright 2018 The Chromium OS Authors. All rights reserved. + * Copyright 2018 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ diff --git a/util/uut/main.c b/util/uut/main.c index 146ddc0275..915bff34d6 100644 --- a/util/uut/main.c +++ b/util/uut/main.c @@ -1,5 +1,5 @@ /* - * Copyright 2018 The Chromium OS Authors. All rights reserved. + * Copyright 2018 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -36,20 +36,20 @@ #define DEFAULT_FLASH_OFFSET 0 /* The magic number in monitor header */ -#define MONITOR_HDR_TAG 0xA5075001 +#define MONITOR_HDR_TAG 0xA5075001 /* The location of monitor header */ -#define MONITOR_HDR_ADDR 0x200C3000 +#define MONITOR_HDR_ADDR 0x200C3000 /* The start address of the monitor little firmware to execute */ -#define MONITOR_ADDR 0x200C3020 +#define MONITOR_ADDR 0x200C3020 /* The start address to store the firmware segment to be programmed */ -#define FIRMWARE_START_ADDR 0x10090000 +#define FIRMWARE_START_ADDR 0x10090000 /* Divide the ec firmware image into 4K byte */ -#define FIRMWARE_SEGMENT 0x1000 +#define FIRMWARE_SEGMENT 0x1000 /* Register address for chip ID */ -#define NPCX_SRID_CR 0x400C101C +#define NPCX_SRID_CR 0x400C101C /* Register address for device ID */ -#define NPCX_DEVICE_ID_CR 0x400C1022 -#define NPCX_FLASH_BASE_ADDR 0x64000000 +#define NPCX_DEVICE_ID_CR 0x400C1022 +#define NPCX_FLASH_BASE_ADDR 0x64000000 /*--------------------------------------------------------------------------- * Global variables @@ -64,8 +64,8 @@ struct comport_fields port_cfg; *--------------------------------------------------------------------------- */ -static const char tool_name[] = {"LINUX UART Update Tool"}; -static const char tool_version[] = {"2.0.1"}; +static const char tool_name[] = { "LINUX UART Update Tool" }; +static const char tool_version[] = { "2.0.1" }; static char port_name[MAX_PARAM_SIZE]; static char opr_name[MAX_PARAM_SIZE]; @@ -185,7 +185,7 @@ enum EXIT_CODE { *--------------------------------------------------------------------------- */ static bool image_auto_write(uint32_t offset, uint8_t *buffer, - uint32_t file_size) + uint32_t file_size) { uint32_t data_buf[4]; uint32_t addr, chunk_remain, file_seg, flash_index, seg; @@ -199,8 +199,8 @@ static bool image_auto_write(uint32_t offset, uint8_t *buffer, file_seg = file_size; total = 0; while (file_seg) { - seg = (file_seg > FIRMWARE_SEGMENT) ? - FIRMWARE_SEGMENT : file_seg; + seg = (file_seg > FIRMWARE_SEGMENT) ? FIRMWARE_SEGMENT : + file_seg; /* * Check if the content of the segment is all 0xff. * If yes, there is no need to write. @@ -218,7 +218,7 @@ static bool image_auto_write(uint32_t offset, uint8_t *buffer, data_buf[2] = 0; data_buf[3] = flash_index; opr_write_chunk((uint8_t *)data_buf, MONITOR_HDR_ADDR, - sizeof(data_buf)); + sizeof(data_buf)); if (opr_execute_return(MONITOR_ADDR) != true) return false; file_seg -= seg; @@ -242,10 +242,11 @@ static bool image_auto_write(uint32_t offset, uint8_t *buffer, data_buf[3] = flash_index; /* Write the monitor header to RAM */ opr_write_chunk((uint8_t *)data_buf, MONITOR_HDR_ADDR, - sizeof(data_buf)); + sizeof(data_buf)); while (chunk_remain) { count = (chunk_remain > MAX_RW_DATA_SIZE) ? - MAX_RW_DATA_SIZE : chunk_remain; + MAX_RW_DATA_SIZE : + chunk_remain; if (opr_write_chunk(buffer, addr, count) != true) return false; @@ -281,13 +282,13 @@ static bool get_flash_size(uint32_t *flash_size) for (i = 0; i < ARRAY_SIZE(chip_info); i++) { if (chip_info[i].device_id == dev_id && - chip_info[i].chip_id == chip_id) { + chip_info[i].chip_id == chip_id) { *flash_size = chip_info[i].flash_size; return true; } } - printf("Unknown NPCX device ID:0x%02x chip ID:0x%02x\n", - dev_id, chip_id); + printf("Unknown NPCX device ID:0x%02x chip ID:0x%02x\n", dev_id, + chip_id); return false; } @@ -315,8 +316,8 @@ static uint8_t *read_input_file(uint32_t size, const char *file_name) } input_fp = fopen(file_name, "r"); if (!input_fp) { - display_color_msg(FAIL, - "ERROR: cannot open file %s\n", file_name); + display_color_msg(FAIL, "ERROR: cannot open file %s\n", + file_name); free(buffer); return NULL; } @@ -396,9 +397,11 @@ int main(int argc, char *argv[]) * It might fail for garbage data drainage from H1, or * for timeout due to unstable data transfer yet. */ - display_color_msg(FAIL, + display_color_msg( + FAIL, "Host/Device synchronization failed, error = %d," - " fail count = %d\n", sr, sync_cnt); + " fail count = %d\n", + sr, sync_cnt); } if (sync_cnt > MAX_SYNC_RETRIES) exit_uart_app(EC_SYNC_ERR); @@ -412,8 +415,8 @@ int main(int argc, char *argv[]) if (!buffer) exit_uart_app(EC_FILE_ERR); - printf("Write file %s at %d with %d bytes\n", - file_name, flash_offset, size); + printf("Write file %s at %d with %d bytes\n", file_name, + flash_offset, size); if (image_auto_write(flash_offset, buffer, size)) { printf("Flash Done.\n"); free(buffer); @@ -429,7 +432,7 @@ int main(int argc, char *argv[]) if (get_flash_size(&flash_size)) { printf("Read %d bytes from flash...\n", flash_size); opr_read_mem(file_name, NPCX_FLASH_BASE_ADDR, - flash_size); + flash_size); exit_uart_app(EC_OK); } @@ -506,20 +509,13 @@ int main(int argc, char *argv[]) */ static const struct option long_opts[] = { - {"version", 0, 0, 'v'}, - {"help", 0, 0, 'h'}, - {"quiet", 0, 0, 'q'}, - {"console", 0, 0, 'c'}, - {"auto", 0, 0, 'A'}, - {"read-flash", 0, 0, 'r'}, - {"baudrate", 1, 0, 'b'}, - {"opr", 1, 0, 'o'}, - {"port", 1, 0, 'p'}, - {"file", 1, 0, 'f'}, - {"addr", 1, 0, 'a'}, - {"size", 1, 0, 's'}, - {"offset", 1, 0, 'O'}, - {NULL, 0, 0, 0} + { "version", 0, 0, 'v' }, { "help", 0, 0, 'h' }, + { "quiet", 0, 0, 'q' }, { "console", 0, 0, 'c' }, + { "auto", 0, 0, 'A' }, { "read-flash", 0, 0, 'r' }, + { "baudrate", 1, 0, 'b' }, { "opr", 1, 0, 'o' }, + { "port", 1, 0, 'p' }, { "file", 1, 0, 'f' }, + { "addr", 1, 0, 'a' }, { "size", 1, 0, 's' }, + { "offset", 1, 0, 'O' }, { NULL, 0, 0, 0 } }; static const char *short_opts = "vhqcArb:o:p:f:a:s:O:?"; @@ -528,9 +524,8 @@ static void param_parse_cmd_line(int argc, char *argv[]) { int opt, idx; - while ((opt = getopt_long(argc, argv, short_opts, - long_opts, &idx)) != -1) { - + while ((opt = getopt_long(argc, argv, short_opts, long_opts, &idx)) != + -1) { switch (opt) { case 'v': main_print_version(); @@ -558,23 +553,23 @@ static void param_parse_cmd_line(int argc, char *argv[]) break; case 'o': strncpy(opr_name, optarg, sizeof(opr_name)); - opr_name[sizeof(opr_name)-1] = '\0'; + opr_name[sizeof(opr_name) - 1] = '\0'; break; case 'p': strncpy(port_name, optarg, sizeof(port_name)); - port_name[sizeof(port_name)-1] = '\0'; + port_name[sizeof(port_name) - 1] = '\0'; break; case 'f': strncpy(file_name, optarg, sizeof(file_name)); - file_name[sizeof(file_name)-1] = '\0'; + file_name[sizeof(file_name) - 1] = '\0'; break; case 'a': strncpy(addr_str, optarg, sizeof(addr_str)); - addr_str[sizeof(addr_str)-1] = '\0'; + addr_str[sizeof(addr_str) - 1] = '\0'; break; case 's': strncpy(size_str, optarg, sizeof(size_str)); - size_str[sizeof(size_str)-1] = '\0'; + size_str[sizeof(size_str) - 1] = '\0'; break; case 'O': flash_offset = strtol(optarg, NULL, 0); @@ -595,12 +590,12 @@ static void param_parse_cmd_line(int argc, char *argv[]) */ static void param_check_opr_num(const char *opr) { - if ((strcasecmp(opr, OPR_WRITE_MEM) != 0) && - (strcasecmp(opr, OPR_READ_MEM) != 0) && - (strcasecmp(opr, OPR_EXECUTE_EXIT) != 0) && - (strcasecmp(opr, OPR_EXECUTE_CONT) != 0)) { - display_color_msg(FAIL, + (strcasecmp(opr, OPR_READ_MEM) != 0) && + (strcasecmp(opr, OPR_EXECUTE_EXIT) != 0) && + (strcasecmp(opr, OPR_EXECUTE_CONT) != 0)) { + display_color_msg( + FAIL, "ERROR: Operation %s not supported, Supported " "operations are %s, %s, %s & %s\n", opr, OPR_WRITE_MEM, OPR_READ_MEM, OPR_EXECUTE_EXIT, @@ -624,12 +619,11 @@ static uint32_t param_get_file_size(const char *file_name) struct stat fst; if (stat(file_name, &fst)) { - display_color_msg(FAIL, - "ERROR: Could not stat file [%s]\n", file_name); + display_color_msg(FAIL, "ERROR: Could not stat file [%s]\n", + file_name); return 0; } return fst.st_size; - } /*--------------------------------------------------------------------------- @@ -653,7 +647,7 @@ static uint32_t param_get_str_size(char *string) /* Verify string is non-NULL */ if ((string == NULL) || (strlen(string) == 0)) { display_color_msg(FAIL, - "ERROR: Zero length input string provided\n"); + "ERROR: Zero length input string provided\n"); return 0; } @@ -692,14 +686,14 @@ static void tool_usage(void) printf(" -c, --console - Print data to console (default is " "print to file)\n"); printf(" -p, --port <name> - Serial port name (default is %s)\n", - DEFAULT_PORT_NAME); + DEFAULT_PORT_NAME); printf(" -b, --baudrate <num> - COM Port baud-rate (default is %d)\n", - DEFAULT_BAUD_RATE); + DEFAULT_BAUD_RATE); printf(" -A, --auto - Enable auto mode. (default is off)\n"); printf(" -O, --offset <num> - With --auto, assign the offset of"); printf(" flash where the image to be written.\n"); printf(" -r, --read-flash - With --file=<file>, Read the whole" - " flash content and write it to <file>.\n"); + " flash content and write it to <file>.\n"); printf("\n"); printf("Operation specific switches:\n"); printf(" -o, --opr <name> - Operation number (see list below)\n"); diff --git a/util/uut/main.h b/util/uut/main.h index 2885e7368a..43c80dddae 100644 --- a/util/uut/main.h +++ b/util/uut/main.h @@ -1,5 +1,5 @@ /* - * Copyright 2018 The Chromium OS Authors. All rights reserved. + * Copyright 2018 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -21,11 +21,11 @@ #define BASE_HEXADECIMAL 16 /* Verbose control messages display */ -#define DISPLAY_MSG(msg) \ -{ \ - if (verbose) \ - printf msg; \ -} +#define DISPLAY_MSG(msg) \ + { \ + if (verbose) \ + printf msg; \ + } #define SUCCESS true #define FAIL false diff --git a/util/uut/opr.c b/util/uut/opr.c index 5c979afb16..8ad60bd3d4 100644 --- a/util/uut/opr.c +++ b/util/uut/opr.c @@ -1,5 +1,5 @@ /* - * Copyright 2018 The Chromium OS Authors. All rights reserved. + * Copyright 2018 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -34,7 +34,7 @@ int port_handle = INVALID_HANDLE_VALUE; *--------------------------------------------------------------------------- */ #define MAX_PORT_NAME_SIZE 32 -#define OPR_TIMEOUT 10L /* 10 seconds */ +#define OPR_TIMEOUT 10L /* 10 seconds */ #define FLASH_ERASE_TIMEOUT 120L /* 120 seconds */ #define STS_MSG_MIN_SIZE 8 @@ -119,9 +119,8 @@ bool opr_open_port(const char *port_name, struct comport_fields port_cfg) if (port_handle <= 0) { display_color_msg(FAIL, "\nERROR: COM Port failed to open.\n"); - DISPLAY_MSG( - ("Please select the right serial port or check if " - "other serial\n")); + DISPLAY_MSG(("Please select the right serial port or check if " + "other serial\n")); DISPLAY_MSG(("communication applications are opened.\n")); return false; } @@ -150,13 +149,13 @@ bool opr_write_chunk(uint8_t *buffer, uint32_t addr, uint32_t size) struct command_node wr_cmd_buf; if (size > MAX_RW_DATA_SIZE) { - display_color_msg(FAIL, - "ERROR: Block cannot exceed %d\n", MAX_RW_DATA_SIZE); + display_color_msg(FAIL, "ERROR: Block cannot exceed %d\n", + MAX_RW_DATA_SIZE); } /* Initialize response size */ wr_cmd_buf.resp_size = 1; - cmd_create_write(addr, size, buffer, - wr_cmd_buf.cmd, &wr_cmd_buf.cmd_size); + cmd_create_write(addr, size, buffer, wr_cmd_buf.cmd, + &wr_cmd_buf.cmd_size); return opr_send_cmds(&wr_cmd_buf, 1); } @@ -179,13 +178,13 @@ bool opr_read_chunk(uint8_t *buffer, uint32_t addr, uint32_t size) struct command_node rd_cmd_buf; if (size > MAX_RW_DATA_SIZE) { - display_color_msg(FAIL, - "ERROR: Block cannot exceed %d\n", MAX_RW_DATA_SIZE); + display_color_msg(FAIL, "ERROR: Block cannot exceed %d\n", + MAX_RW_DATA_SIZE); return false; } - cmd_create_read(addr, ((uint8_t)size - 1), - rd_cmd_buf.cmd, &rd_cmd_buf.cmd_size); + cmd_create_read(addr, ((uint8_t)size - 1), rd_cmd_buf.cmd, + &rd_cmd_buf.cmd_size); rd_cmd_buf.resp_size = size + 3; if (opr_send_cmds(&rd_cmd_buf, 1)) { if (resp_buf[0] == (uint8_t)(UFPP_READ_CMD)) { @@ -228,7 +227,7 @@ void opr_write_mem(uint8_t *buffer, uint32_t addr, uint32_t size) wr_cmd_buf.resp_size = 1; DISPLAY_MSG(("Writing [%d] bytes in [%d] packets\n", size, - ((size + (block_size - 1)) / block_size))); + ((size + (block_size - 1)) / block_size))); /* Read first token from string */ if (console) @@ -248,21 +247,21 @@ void opr_write_mem(uint8_t *buffer, uint32_t addr, uint32_t size) /* Prepare the next iteration */ token = strtok(NULL, seps); } - write_size = (size_remain > block_size) ? - block_size : size_remain; + write_size = (size_remain > block_size) ? block_size : + size_remain; if (console) { cmd_create_write(cur_addr, write_size, data_buf, - wr_cmd_buf.cmd, &wr_cmd_buf.cmd_size); + wr_cmd_buf.cmd, &wr_cmd_buf.cmd_size); } else { cmd_create_write(cur_addr, write_size, buffer, - wr_cmd_buf.cmd, &wr_cmd_buf.cmd_size); + wr_cmd_buf.cmd, &wr_cmd_buf.cmd_size); buffer += write_size; } if (opr_send_cmds(&wr_cmd_buf, 1) != true) break; cmd_disp_write(resp_buf, write_size, cmd_idx, - ((size + (block_size - 1)) / block_size)); + ((size + (block_size - 1)) / block_size)); cur_addr += write_size; size_remain -= write_size; cmd_idx++; @@ -302,7 +301,8 @@ void opr_read_mem(char *output, uint32_t addr, uint32_t size) output_file_id = fopen(output, "w+b"); if (output_file_id == NULL) { - display_color_msg(FAIL, + display_color_msg( + FAIL, "ERROR: could not open output file [%s]\n", output); return; @@ -310,21 +310,22 @@ void opr_read_mem(char *output, uint32_t addr, uint32_t size) } DISPLAY_MSG(("Reading [%d] bytes in [%d] packets\n", size, - ((size + (MAX_RW_DATA_SIZE - 1)) / MAX_RW_DATA_SIZE))); + ((size + (MAX_RW_DATA_SIZE - 1)) / MAX_RW_DATA_SIZE))); for (cur_addr = addr; cur_addr < (addr + size); - cur_addr += MAX_RW_DATA_SIZE) { + cur_addr += MAX_RW_DATA_SIZE) { bytes_left = (uint32_t)(addr + size - cur_addr); read_size = MIN(bytes_left, MAX_RW_DATA_SIZE); cmd_create_read(cur_addr, ((uint8_t)read_size - 1), - rd_cmd_buf.cmd, &rd_cmd_buf.cmd_size); + rd_cmd_buf.cmd, &rd_cmd_buf.cmd_size); rd_cmd_buf.resp_size = read_size + 3; if (opr_send_cmds(&rd_cmd_buf, 1) != true) break; - cmd_disp_read(resp_buf, read_size, cmd_idx, + cmd_disp_read( + resp_buf, read_size, cmd_idx, ((size + (MAX_RW_DATA_SIZE - 1)) / MAX_RW_DATA_SIZE)); if (console) @@ -386,8 +387,8 @@ bool opr_execute_return(uint32_t addr) * Check the response command code is UFPP_FCALL_RSLT_CMD and * the return value from monitor is 0x03. (program finish and verify ok) */ - if (resp_buf[1] != (uint8_t)(UFPP_FCALL_RSLT_CMD) - || resp_buf[2] != 0x03) + if (resp_buf[1] != (uint8_t)(UFPP_FCALL_RSLT_CMD) || + resp_buf[2] != 0x03) return false; return true; } @@ -473,29 +474,31 @@ bool opr_scan_baudrate(void) sr = opr_check_sync(baud); step = (baud * BR_BIG_STEP) / 100; if (sr == SR_OK) { - printf("SR_OK: Baud rate - %d, resp_buf - 0x%x\n", - baud, resp_buf[0]); + printf("SR_OK: Baud rate - %d, resp_buf - 0x%x\n", baud, + resp_buf[0]); synched = true; step = (baud * BR_SMALL_STEP) / 100; } else if (sr == SR_WRONG_DATA) { printf("SR_WRONG_DATA: Baud rate - %d, resp_buf - " - "0x%x\n", baud, resp_buf[0]); + "0x%x\n", + baud, resp_buf[0]); data_received = true; step = (baud * BR_MEDIUM_STEP) / 100; } else if (sr == SR_TIMEOUT) { printf("SR_TIMEOUT: Baud rate - %d, resp_buf - 0x%x\n", - baud, resp_buf[0]); + baud, resp_buf[0]); if (synched || data_received) break; } else if (sr == SR_ERROR) { printf("SR_ERROR: Baud rate - %d, resp_buf - 0x%x\n", - baud, resp_buf[0]); + baud, resp_buf[0]); if (synched || data_received) break; } else printf("Unknown error code: Baud rate - %d, resp_buf - " - "0x%x\n", baud, resp_buf[0]); + "0x%x\n", + baud, resp_buf[0]); } return true; @@ -524,7 +527,7 @@ static bool opr_send_cmds(struct command_node *cmd_buf, uint32_t cmd_num) for (cmd = 0; cmd < cmd_num; cmd++, cur_cmd++) { if (com_port_write_bin(port_handle, cur_cmd->cmd, - cur_cmd->cmd_size) == true) { + cur_cmd->cmd_size) == true) { time(&start); do { @@ -533,15 +536,17 @@ static bool opr_send_cmds(struct command_node *cmd_buf, uint32_t cmd_num) } while ((read < cur_cmd->resp_size) && (elapsed_time <= OPR_TIMEOUT)); com_port_read_bin(port_handle, resp_buf, - cur_cmd->resp_size); + cur_cmd->resp_size); if (elapsed_time > OPR_TIMEOUT) - display_color_msg(FAIL, + display_color_msg( + FAIL, "ERROR: [%d] bytes received for read, " "[%d] bytes are expected\n", read, cur_cmd->resp_size); } else { - display_color_msg(FAIL, + display_color_msg( + FAIL, "ERROR: Failed to send Command number %d\n", cmd); return false; diff --git a/util/uut/opr.h b/util/uut/opr.h index 3b166f0c7e..820639d6a1 100644 --- a/util/uut/opr.h +++ b/util/uut/opr.h @@ -1,5 +1,5 @@ /* - * Copyright 2018 The Chromium OS Authors. All rights reserved. + * Copyright 2018 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -15,16 +15,16 @@ */ /* Baud rate scan steps: */ -#define BR_BIG_STEP 20 /* in percents from current baud rate */ -#define BR_MEDIUM_STEP 10 /* in percents from current baud rate */ -#define BR_SMALL_STEP 1 /* in percents from current baud rate */ -#define BR_MIN_STEP 5 /* in absolute baud rate units */ -#define BR_LOW_LIMIT 400 /* Automatic BR detection starts at this value */ +#define BR_BIG_STEP 20 /* in percents from current baud rate */ +#define BR_MEDIUM_STEP 10 /* in percents from current baud rate */ +#define BR_SMALL_STEP 1 /* in percents from current baud rate */ +#define BR_MIN_STEP 5 /* in absolute baud rate units */ +#define BR_LOW_LIMIT 400 /* Automatic BR detection starts at this value */ #define BR_HIGH_LIMIT 150000 /* Automatic BR detection ends at this value */ -#define OPR_WRITE_MEM "wr" /* Write To Memory/Flash */ -#define OPR_READ_MEM "rd" /* Read From Memory/Flash */ -#define OPR_EXECUTE_EXIT "go" /* Execute a non-return code */ +#define OPR_WRITE_MEM "wr" /* Write To Memory/Flash */ +#define OPR_READ_MEM "rd" /* Read From Memory/Flash */ +#define OPR_EXECUTE_EXIT "go" /* Execute a non-return code */ #define OPR_EXECUTE_CONT "call" /* Execute returnable code */ enum sync_result { diff --git a/util/zephyr_to_resultdb.py b/util/zephyr_to_resultdb.py new file mode 100755 index 0000000000..48bfe151e4 --- /dev/null +++ b/util/zephyr_to_resultdb.py @@ -0,0 +1,173 @@ +#!/usr/bin/env python3 +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +""" Upload twister results to ResultDB + + Usage: + $ rdb stream -new -realm chromium:public -- ./util/zephyr_to_resultdb.py + --results=twister-out/twister.json --upload=True +""" + +import argparse +import base64 +import json +import os + +import requests # pylint: disable=import-error + + +def translate_status(status): + """Translates ZTEST status to ResultDB status""" + ret_status = "SKIP" + + if status == "passed": + ret_status = "PASS" + elif status == "failed": + ret_status = "FAIL" + elif status in ["skipped", "filtered"]: + ret_status = "SKIP" + + return ret_status + + +def translate_expected(status): + """Translates ZTEST status to ResultDB expected""" + flag = False + + if status in ["passed", "filtered"]: + flag = True + + return flag + + +def translate_duration(testcase): + """Translates ZTEST execution_time to ResultDB duration""" + time = testcase.get("execution_time") + if not time: + return None + + return f"{time}ms" + + +def testcase_summary(testcase): + """Translates ZTEST testcase to ResultDB summaryHtml""" + html = "<p>None</p>" + + if ( + "log" in testcase + or "reason" in testcase + or translate_status(testcase["status"]) == "SKIP" + ): + html = ( + '<p><text-artifact artifact-id="artifact-content-in-request"></p>' + ) + + return html + + +def testcase_artifact(testcase): + """Translates ZTEST testcase to ResultDB artifact""" + artifact = "Unknown" + + if "log" in testcase and testcase["log"]: + artifact = testcase["log"] + elif "reason" in testcase and testcase["reason"]: + artifact = testcase["reason"] + elif testcase["status"] == "filtered": + artifact = "filtered" + elif testcase["status"] == "skipped": + artifact = "skipped" + + return base64.b64encode(artifact.encode()) + + +def testcase_to_result(testsuite, testcase): + """Translates ZTEST testcase to ResultDB format""" + result = { + "testId": testcase["identifier"], + "status": translate_status(testcase["status"]), + "expected": translate_expected(testcase["status"]), + "summaryHtml": testcase_summary(testcase), + "artifacts": { + "artifact-content-in-request": { + "contents": testcase_artifact(testcase), + } + }, + # TODO(b/239952573) Add all test configs as tags + "tags": [ + {"key": "category", "value": "ChromeOS/EC"}, + {"key": "platform", "value": testsuite["platform"]}, + ], + "duration": translate_duration(testcase), + "testMetadata": {"name": testcase["identifier"]}, + } + + return result + + +def json_to_resultdb(result_file): + """Translates Twister json test report to ResultDB format""" + with open(result_file) as file: + data = json.load(file) + results = [] + + for testsuite in data["testsuites"]: + for testcase in testsuite["testcases"]: + if testcase["status"]: + results.append(testcase_to_result(testsuite, testcase)) + + file.close() + + return results + + +class BytesEncoder(json.JSONEncoder): + """Encoder for ResultDB format""" + + def default(self, obj): + if isinstance(obj, bytes): + return obj.decode("utf-8") + return json.JSONEncoder.default(self, obj) + + +def upload_results(results): + """Upload results to ResultDB""" + with open(os.environ["LUCI_CONTEXT"]) as file: + sink = json.load(file)["result_sink"] + + # Uploads all test results at once. + res = requests.post( + url="http://%s/prpc/luci.resultsink.v1.Sink/ReportTestResults" + % sink["address"], + headers={ + "Content-Type": "application/json", + "Accept": "application/json", + "Authorization": "ResultSink %s" % sink["auth_token"], + }, + data=json.dumps({"testResults": results}, cls=BytesEncoder), + ) + res.raise_for_status() + + +def main(): + """main""" + # Set up argument parser. + parser = argparse.ArgumentParser( + description=("Upload Zephyr Twister test results to ResultDB") + ) + parser.add_argument("--results") + parser.add_argument("--upload", default=False) + args = parser.parse_args() + + if args.results: + print("Converting:", args.results) + rdb_results = json_to_resultdb(args.results) + if args.upload: + upload_results(rdb_results) + else: + raise Exception("Missing test result file for conversion") + + +if __name__ == "__main__": + main() diff --git a/util/zephyr_to_resultdb.py.vpython3 b/util/zephyr_to_resultdb.py.vpython3 new file mode 100644 index 0000000000..9a086bffdf --- /dev/null +++ b/util/zephyr_to_resultdb.py.vpython3 @@ -0,0 +1,18 @@ +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# vpython VirtualEnv protobuf for "zephyr_to_resultdb.py". +# +# Dependencies needed to run zephyr_to_resultdb.py in +# infra/recipes/recipes/build_firmware.py +# +# For info on this file, see: +# https://chromium.googlesource.com/infra/infra/+/HEAD/doc/users/vpython.md#available-wheels +# + +python_version: "3.8" +wheel: < + name: "infra/python/wheels/requests-py2_py3" + version: "version:2.13.0" +> |