diff options
Diffstat (limited to 'util')
-rw-r--r-- | util/build.mk | 4 | ||||
-rw-r--r-- | util/ec3po/OWNERS | 3 | ||||
-rw-r--r-- | util/ec_panicinfo.cc | 246 | ||||
-rw-r--r-- | util/ec_panicinfo.h | 30 | ||||
-rw-r--r-- | util/ec_panicinfo_fuzzer.cc | 2 | ||||
-rw-r--r-- | util/ec_parse_panicinfo.cc | 27 | ||||
-rw-r--r-- | util/ectool.cc | 222 |
7 files changed, 402 insertions, 132 deletions
diff --git a/util/build.mk b/util/build.mk index 1b692ccb9f..286d70cf16 100644 --- a/util/build.mk +++ b/util/build.mk @@ -30,7 +30,7 @@ comm-objs=$(util-lock-objs:%=lock/%) comm-host.o comm-dev.o comm-objs+=comm-lpc.o comm-i2c.o misc_util.o comm-usb.o iteflash-objs = iteflash.o usb_if.o -ectool-objs=ectool.o ectool_keyscan.o ec_flash.o $(comm-objs) +ectool-objs=ectool.o ectool_keyscan.o ec_flash.o ec_panicinfo.o $(comm-objs) ectool-objs+=ectool_i2c.o ectool-objs+=../common/crc.o ectool_servo-objs=$(ectool-objs) comm-servo-spi.o @@ -38,7 +38,7 @@ lbplay-objs=lbplay.o $(comm-objs) util/ectool.cc: $(out)/ec_version.h -ec_parse_panicinfo-objs=ec_parse_panicinfo.o +ec_parse_panicinfo-objs=ec_parse_panicinfo.o ec_panicinfo.o # USB type-C Vendor Information File generation ifeq ($(CONFIG_USB_POWER_DELIVERY),y) diff --git a/util/ec3po/OWNERS b/util/ec3po/OWNERS deleted file mode 100644 index 5d4c97339d..0000000000 --- a/util/ec3po/OWNERS +++ /dev/null @@ -1,3 +0,0 @@ -aaboagye@chromium.org -coconutruben@chromium.org -matthewb@chromium.org diff --git a/util/ec_panicinfo.cc b/util/ec_panicinfo.cc new file mode 100644 index 0000000000..308cd0e641 --- /dev/null +++ b/util/ec_panicinfo.cc @@ -0,0 +1,246 @@ +/* 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. + */ + +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#include <cstddef> + +/* Helpers from ec/include/compile_time_macros.h */ +#ifndef CONFIG_ZEPHYR +#define BIT(nr) (1U << (nr)) +#endif + +#include "ec_panicinfo.h" + +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 " }; + + printf("%s:", regname[regnum]); + if (regs) + printf("%08x", regs[index]); + else + printf(" "); + printf((regnum & 3) == 3 ? "\n" : " "); +} + +static void panic_show_extra_cm(const struct panic_data *pdata) +{ + enum { + CPU_NVIC_CFSR_BFARVALID = BIT(15), + CPU_NVIC_CFSR_MFARVALID = BIT(7), + }; + + printf("\n"); + if (pdata->cm.cfsr & CPU_NVIC_CFSR_BFARVALID) + printf("bfar=%08x, ", pdata->cm.bfar); + if (pdata->cm.cfsr & CPU_NVIC_CFSR_MFARVALID) + printf("mfar=%08x, ", pdata->cm.mfar); + printf("cfsr=%08x, ", pdata->cm.cfsr); + printf("shcsr=%08x, ", pdata->cm.shcsr); + printf("hfsr=%08x, ", pdata->cm.hfsr); + printf("dfsr=%08x, ", pdata->cm.dfsr); + printf("ipsr=%08x", pdata->cm.regs[CORTEX_PANIC_REGISTER_IPSR]); + printf("\n"); +} + +static int parse_panic_info_cm(const struct panic_data *pdata) +{ + const uint32_t *lregs = pdata->cm.regs; + const uint32_t *sregs = NULL; + enum { + ORIG_UNKNOWN = 0, + ORIG_PROCESS, + ORIG_HANDLER + } origin = ORIG_UNKNOWN; + int i; + 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; + + /* + * In pdata struct, 'regs', which is allocated before 'frame', has + * one less elements in version 1. Therefore, if the data is from + * version 1, shift 'sregs' by one element to align with 'frame' in + * version 1. + */ + if (pdata->flags & PANIC_DATA_FLAG_FRAME_VALID) + 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); + for (i = 0; i < 4; ++i) + print_panic_reg(i, sregs, i); + for (i = 4; i < 10; ++i) + print_panic_reg(i, lregs, i - 1); + print_panic_reg(10, lregs, 9); + print_panic_reg(11, lregs, 10); + print_panic_reg(12, sregs, 4); + print_panic_reg(13, lregs, origin == ORIG_HANDLER ? 2 : 0); + print_panic_reg(14, sregs, 5); + print_panic_reg(15, sregs, 6); + + panic_show_extra_cm(pdata); + + return 0; +} + +static int parse_panic_info_nds32(const struct panic_data *pdata) +{ + const uint32_t *regs = pdata->nds_n8.regs; + uint32_t itype = pdata->nds_n8.itype; + uint32_t ipc = pdata->nds_n8.ipc; + uint32_t ipsw = pdata->nds_n8.ipsw; + + printf("Saved panic data:%s\n", + (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("IPC %08x IPSW %05x\n", ipc, ipsw); + printf("SWID of ITYPE: %x\n", ((itype >> 16) & 0x7fff)); + + return 0; +} + +static int parse_panic_info_rv32i(const struct panic_data *pdata) +{ + uint32_t *regs, mcause, mepc; + + regs = (uint32_t *)pdata->riscv.regs; + mcause = pdata->riscv.mcause; + 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); + + return 0; +} + +int get_panic_input(char *data, size_t max_size) +{ + size_t size = 0; + size_t read; + + while (1) { + read = fread(&data[size], 1, max_size - size, stdin); + if (read < 0) { + fprintf(stderr, "Cannot read panicinfo from stdin.\n"); + return -1; + } + if (read == 0) + break; + + size += read; + if (size >= max_size) { + fprintf(stderr, "Too much panicinfo data in stdin.\n"); + return -1; + } + } + + return size; +} + +int parse_panic_info(const char *data, size_t size) +{ + /* Size of the panic information "header". */ + 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); + + struct panic_data pdata = { 0 }; + size_t copy_size; + + if (size < (header_size + trailer_size)) { + fprintf(stderr, "ERROR: Panic data too short (%zd).\n", size); + return -1; + } + + if (size > sizeof(pdata)) { + fprintf(stderr, + "WARNING: Panic data too large (%zd > %zd). " + "Following data may be incorrect!\n", + size, sizeof(pdata)); + copy_size = sizeof(pdata); + } else { + copy_size = size; + } + /* Copy the data into pdata, as the struct size may have changed. */ + 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); + + /* + * 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). " + "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). " + "Following data may be incorrect!\n", + pdata.magic); + + if (pdata.struct_size != size) + fprintf(stderr, + "WARNING: Panic struct size inconsistent (%u vs %zd). " + "Following data may be incorrect!\n", + pdata.struct_size, size); + + switch (pdata.arch) { + case PANIC_ARCH_CORTEX_M: + return parse_panic_info_cm(&pdata); + case PANIC_ARCH_NDS32_N8: + return parse_panic_info_nds32(&pdata); + case PANIC_ARCH_RISCV_RV32I: + return parse_panic_info_rv32i(&pdata); + default: + fprintf(stderr, "ERROR: Unknown architecture (%d).\n", + pdata.arch); + break; + } + return -1; +} diff --git a/util/ec_panicinfo.h b/util/ec_panicinfo.h new file mode 100644 index 0000000000..cb968b968f --- /dev/null +++ b/util/ec_panicinfo.h @@ -0,0 +1,30 @@ +/* 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. + */ + +#ifndef EC_PANICINFO_H +#define EC_PANICINFO_H + +#include "panic_defs.h" + +#include <stdio.h> + +/** + * Prints panic information to stdout. + * + * @param pdata Panic information to print + * @return 0 if success or non-zero error code if error. + */ +int parse_panic_info(const char *data, size_t size); + +/** + * Read stdin to data. + * + * @param data Raw information to store. + * @param max_size Maximum size can be stored to data. + * @return data length if success or -1 on error. + */ +int get_panic_input(char *data, size_t max_size); + +#endif /* EC_PANICINFO_H */ diff --git a/util/ec_panicinfo_fuzzer.cc b/util/ec_panicinfo_fuzzer.cc index 7767afa2e2..95f1871837 100644 --- a/util/ec_panicinfo_fuzzer.cc +++ b/util/ec_panicinfo_fuzzer.cc @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -#include <libec/ec_panicinfo.h> +#include "ec_panicinfo.h" /* Fuzzing Build command: * $ clang++ ec_panicinfo_fuzzer.cc ec_panicinfo.cc -g -fsanitize=address,fuzzer diff --git a/util/ec_parse_panicinfo.cc b/util/ec_parse_panicinfo.cc index eb8ab2a24c..c278b3c4f1 100644 --- a/util/ec_parse_panicinfo.cc +++ b/util/ec_parse_panicinfo.cc @@ -5,12 +5,10 @@ * Standalone utility to parse EC panicinfo. */ -#include "compile_time_macros.h" - #include <stdint.h> #include <stdio.h> - -#include <libec/ec_panicinfo.h> +#include "compile_time_macros.h" +#include "ec_panicinfo.h" int main(int argc, char *argv[]) { @@ -18,9 +16,10 @@ int main(int argc, char *argv[]) * panic_data size could change with time, as new architecture are * added (or, less likely, removed). */ - const size_t max_size = 4096; + char pdata[4096]; + size_t size = 0; - BUILD_ASSERT(max_size > sizeof(struct panic_data) * 2); + BUILD_ASSERT(sizeof(pdata) > sizeof(struct panic_data) * 2); /* * Provide a minimal help message. @@ -35,19 +34,9 @@ int main(int argc, char *argv[]) return 1; } - auto data = ec::GetPanicInput(4096); - if (!data.has_value()) { - fprintf(stderr, "%s", data.error().c_str()); + size = get_panic_input(pdata, sizeof(pdata)); + if (size < 0) return 1; - } - - auto result = ec::ParsePanicInfo(data.value()); - - if (!result.has_value()) { - fprintf(stderr, "%s", result.error().c_str()); - return 1; - } - printf("%s", result.value().c_str()); - return 0; + return parse_panic_info(pdata, size) ? 1 : 0; } diff --git a/util/ectool.cc b/util/ectool.cc index b3ccaf49c3..a5f1c57257 100644 --- a/util/ectool.cc +++ b/util/ectool.cc @@ -3,13 +3,28 @@ * found in the LICENSE file. */ +#include <assert.h> +#include <ctype.h> +#include <errno.h> +#include <getopt.h> +#include <inttypes.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <signal.h> +#include <stdbool.h> + #include "battery.h" -#include "chipset.h" #include "comm-host.h" #include "comm-usb.h" +#include "chipset.h" #include "compile_time_macros.h" #include "crc.h" #include "cros_ec_dev.h" +#include "ec_panicinfo.h" #include "ec_flash.h" #include "ec_version.h" #include "ectool.h" @@ -21,26 +36,7 @@ #include "tablet_mode.h" #include "usb_pd.h" -#include <assert.h> -#include <ctype.h> -#include <errno.h> -#include <inttypes.h> -#include <signal.h> -#include <stdbool.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#include <getopt.h> #include <libec/add_entropy_command.h> -#include <libec/ec_panicinfo.h> -#include <libec/fingerprint/fp_encryption_status_command.h> -#include <libec/flash_protect_command.h> -#include <libec/rand_num_command.h> -#include <unistd.h> -#include <vector> /* Maximum flash size (16 MB, conservative) */ #define MAX_FLASH_SIZE 0x1000000 @@ -1556,6 +1552,9 @@ int cmd_flash_info(int argc, char *argv[]) int cmd_rand(int argc, char *argv[]) { + struct ec_params_rand_num p; + struct ec_response_rand_num *r; + size_t r_size; int64_t num_bytes; int64_t i; char *e; @@ -1572,23 +1571,24 @@ int cmd_rand(int argc, char *argv[]) return -1; } + r = (struct ec_response_rand_num *)(ec_inbuf); + for (i = 0; i < num_bytes; i += ec_max_insize) { - uint16_t num_rand_bytes = ec_max_insize; - if (num_bytes - i < num_rand_bytes) - num_rand_bytes = num_bytes - i; - - ec::RandNumCommand rand_num_command(num_rand_bytes); - if (!rand_num_command.Run(comm_get_fd())) { - int rv = -EECRESULT - rand_num_command.Result(); - fprintf(stderr, "Rand Num returned with errors: %d\n", - rv); - return rv; + p.num_rand_bytes = ec_max_insize; + if (num_bytes - i < p.num_rand_bytes) + p.num_rand_bytes = num_bytes - i; + + r_size = p.num_rand_bytes; + + rv = ec_command(EC_CMD_RAND_NUM, EC_VER_RAND_NUM, &p, sizeof(p), + r, r_size); + if (rv < 0) { + fprintf(stderr, "Random number command failed\n"); + return -1; } - rv = write(STDOUT_FILENO, - rand_num_command.GetRandNumData().data(), - num_rand_bytes); - if (rv != num_rand_bytes) { + rv = write(STDOUT_FILENO, r->rand, r_size); + if (rv != r_size) { fprintf(stderr, "Failed to write stdout\n"); return -1; } @@ -1746,63 +1746,83 @@ 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); + if (flags & EC_FLASH_PROTECT_GPIO_ASSERTED) + printf(" wp_gpio_asserted"); + if (flags & EC_FLASH_PROTECT_RO_AT_BOOT) + printf(" ro_at_boot"); + if (flags & EC_FLASH_PROTECT_RW_AT_BOOT) + printf(" rw_at_boot"); + if (flags & EC_FLASH_PROTECT_ROLLBACK_AT_BOOT) + printf(" rollback_at_boot"); + if (flags & EC_FLASH_PROTECT_ALL_AT_BOOT) + printf(" all_at_boot"); + if (flags & EC_FLASH_PROTECT_RO_NOW) + printf(" ro_now"); + if (flags & EC_FLASH_PROTECT_RW_NOW) + printf(" rw_now"); + if (flags & EC_FLASH_PROTECT_ROLLBACK_NOW) + printf(" rollback_now"); + if (flags & EC_FLASH_PROTECT_ALL_NOW) + printf(" all_now"); + if (flags & EC_FLASH_PROTECT_ERROR_STUCK) + printf(" STUCK"); + if (flags & EC_FLASH_PROTECT_ERROR_INCONSISTENT) + printf(" INCONSISTENT"); + if (flags & EC_FLASH_PROTECT_ERROR_UNKNOWN) + printf(" UNKNOWN_ERROR"); + printf("\n"); +} + int cmd_flash_protect(int argc, char *argv[]) { + struct ec_params_flash_protect p; + struct ec_response_flash_protect r; + int rv, i; + /* - * Set up requested flags. If no flags were specified, mask will - * be flash_protect::Flags::kNone and nothing will change. + * Set up requested flags. If no flags were specified, p.mask will + * be 0 and nothing will change. */ - ec::flash_protect::Flags flags = ec::flash_protect::Flags::kNone; - ec::flash_protect::Flags mask = ec::flash_protect::Flags::kNone; - - for (int i = 1; i < argc; i++) { + p.mask = p.flags = 0; + for (i = 1; i < argc; i++) { if (!strcasecmp(argv[i], "now")) { - mask |= ec::flash_protect::Flags::kAllNow; - flags |= ec::flash_protect::Flags::kAllNow; + p.mask |= EC_FLASH_PROTECT_ALL_NOW; + p.flags |= EC_FLASH_PROTECT_ALL_NOW; } else if (!strcasecmp(argv[i], "enable")) { - mask |= ec::flash_protect::Flags::kRoAtBoot; - flags |= ec::flash_protect::Flags::kRoAtBoot; + p.mask |= EC_FLASH_PROTECT_RO_AT_BOOT; + p.flags |= EC_FLASH_PROTECT_RO_AT_BOOT; } else if (!strcasecmp(argv[i], "disable")) - mask |= ec::flash_protect::Flags::kRoAtBoot; + p.mask |= EC_FLASH_PROTECT_RO_AT_BOOT; } - ec::FlashProtectCommand flash_protect_command(flags, mask); - if (!flash_protect_command.Run(comm_get_fd())) { - int rv = -EECRESULT - flash_protect_command.Result(); - fprintf(stderr, "Flash protect returned with errors: %d\n", rv); + 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)) { + fprintf(stderr, "Too little data returned.\n"); + return -1; } /* Print returned flags */ - printf("Flash protect flags: 0x%08x%s\n", - flash_protect_command.GetFlags(), - (ec::FlashProtectCommand::ParseFlags( - flash_protect_command.GetFlags())) - .c_str()); - printf("Valid flags: 0x%08x%s\n", - flash_protect_command.GetValidFlags(), - (ec::FlashProtectCommand::ParseFlags( - flash_protect_command.GetValidFlags())) - .c_str()); - printf("Writable flags: 0x%08x%s\n", - flash_protect_command.GetWritableFlags(), - - (ec::FlashProtectCommand::ParseFlags( - flash_protect_command.GetWritableFlags())) - .c_str()); + print_flash_protect_flags("Flash protect flags:", r.flags); + print_flash_protect_flags("Valid flags: ", r.valid_flags); + print_flash_protect_flags("Writable flags: ", r.writable_flags); /* Check if we got all the flags we asked for */ - if ((flash_protect_command.GetFlags() & mask) != (flags & mask)) { + if ((r.flags & p.mask) != (p.flags & p.mask)) { fprintf(stderr, "Unable to set requested flags " "(wanted mask 0x%08x flags 0x%08x)\n", - mask, flags); - if ((mask & ~flash_protect_command.GetWritableFlags()) != - ec::flash_protect::Flags::kNone) + p.mask, p.flags); + if (p.mask & ~r.writable_flags) fprintf(stderr, "Which is expected, because writable " "mask is 0x%08x.\n", - flash_protect_command.GetWritableFlags()); + r.writable_flags); return -1; } @@ -2379,6 +2399,14 @@ int cmd_fp_info(int argc, char *argv[]) return 0; } +static void print_fp_enc_flags(const char *desc, uint32_t flags) +{ + printf("%s 0x%08x", desc, flags); + if (flags & FP_ENC_STATUS_SEED_SET) + printf(" FPTPM_seed_set"); + printf("\n"); +} + static int cmd_fp_context(int argc, char *argv[]) { struct ec_params_fp_context_v1 p; @@ -2434,28 +2462,17 @@ out: int cmd_fp_enc_status(int argc, char *argv[]) { int rv; + struct ec_response_fp_encryption_status resp = { 0 }; - ec::FpEncryptionStatusCommand fp_encryptionstatus_command; - - if (!fp_encryptionstatus_command.Run(comm_get_fd())) { - int rv = -EECRESULT - fp_encryptionstatus_command.Result(); - fprintf(stderr, - "FP Encryption Status returned with errors: %d\n", rv); - return rv; + rv = ec_command(EC_CMD_FP_ENC_STATUS, 0, NULL, 0, &resp, sizeof(resp)); + if (rv < 0) { + printf("Get FP sensor encryption status failed.\n"); + } else { + print_fp_enc_flags("FPMCU encryption status:", resp.status); + print_fp_enc_flags("Valid flags: ", + resp.valid_flags); + rv = 0; } - printf("FPMCU encryption status: 0x%08x%s", - fp_encryptionstatus_command.GetStatus(), - (ec::FpEncryptionStatusCommand::ParseFlags( - fp_encryptionstatus_command.GetStatus())) - .c_str()); - printf("Valid flags: 0x%08x%s", - fp_encryptionstatus_command.GetValidFlags(), - (ec::FpEncryptionStatusCommand::ParseFlags( - fp_encryptionstatus_command.GetValidFlags())) - .c_str()); - - rv = 0; - return rv; } @@ -3228,7 +3245,7 @@ static int cmd_temperature_print(int id, int mtemp) printf("%-20s %d K (= %d C)", temp_r.sensor_name, temp, K_TO_C(temp)); - if (rc >= 0) + if(rc >= 0) /* * Check for fan_off == fan_max when their * values are either zero or non-zero @@ -6863,17 +6880,7 @@ int cmd_panic_info(int argc, char *argv[]) return 0; } - std::vector<uint8_t> data(static_cast<uint8_t *>(ec_inbuf), - static_cast<uint8_t *>(ec_inbuf) + rv); - auto result = ec::ParsePanicInfo(data); - - if (!result.has_value()) { - fprintf(stderr, "%s", result.error().c_str()); - return 1; - } - printf("%s", result.value().c_str()); - - return 0; + return parse_panic_info((char *)(ec_inbuf), rv); } int cmd_power_info(int argc, char *argv[]) @@ -7619,21 +7626,22 @@ int cmd_charge_current_limit(int argc, char *argv[]) struct ec_params_current_limit p0; p0.limit = limit; - return ec_command(EC_CMD_CHARGE_CURRENT_LIMIT, 0, &p0, - sizeof(p0), NULL, 0); + return ec_command(EC_CMD_CHARGE_CURRENT_LIMIT, 0, + &p0, sizeof(p0), NULL, 0); } /* argc==3 for battery_soc */ battery_soc = strtol(argv[2], &e, 0); if (e && *e) { - fprintf(stderr, "ERROR: Bad battery SoC value: %s\n", argv[2]); + fprintf(stderr, "ERROR: Bad battery SoC value: %s\n", + argv[2]); return -1; } p1.limit = limit; p1.battery_soc = battery_soc; - return ec_command(EC_CMD_CHARGE_CURRENT_LIMIT, 1, &p1, sizeof(p1), NULL, - 0); + return ec_command(EC_CMD_CHARGE_CURRENT_LIMIT, 1, + &p1, sizeof(p1), NULL, 0); } static void cmd_charge_control_help(const char *cmd, const char *msg) |