// SPDX-License-Identifier: GPL-2.0 // // Microchip MCP251xFD Family CAN controller debug tool // // Copyright (c) 2020, 2021 Pengutronix, // Marc Kleine-Budde // #include #include #include #include #include #include #include "mcp251xfd-dump-userspace.h" static void print_usage(char *prg) { fprintf(stderr, "%s - decode chip and driver state of mcp251xfd.\n" "\n" "Usage: %s [options] \n" "\n" " path to dev coredump file\n" " ('/var/log/devcoredump-19700101-234200.dump')\n" " path to regmap register file\n" " ('/sys/kernel/debug/regmap/spi1.0-crc/registers')\n" " shortcut to regmap register file\n" " ('spi0.0')\n" "\n" "Options:\n" " -h, --help this help\n" "\n", prg, prg); } int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, size_t val_count) { memcpy(val, map->mem->buf + reg, val_count * sizeof(uint32_t)); return 0; } void mcp251xfd_dump_ring_init(struct mcp251xfd_ring *ring) { memset(ring, 0x0, sizeof(*ring)); ring->type = MCP251XFD_DUMP_UNKNOWN; ring->head = MCP251XFD_DUMP_UNKNOWN; ring->tail = MCP251XFD_DUMP_UNKNOWN; ring->nr = (uint8_t)MCP251XFD_DUMP_UNKNOWN; ring->fifo_nr = (uint8_t)MCP251XFD_DUMP_UNKNOWN; } int main(int argc, char *argv[]) { struct mcp251xfd_mem mem = { }; struct regmap map = { .mem = &mem, }; struct mcp251xfd_priv priv = { .map = &map, }; const char *file_path; unsigned int i; int opt, err; struct option long_options[] = { { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 }, }; while ((opt = getopt_long(argc, argv, "ei:pq::rvh", long_options, NULL)) != -1) { switch (opt) { case 'h': print_usage(basename(argv[0])); exit(EXIT_SUCCESS); break; default: print_usage(basename(argv[0])); exit(EXIT_FAILURE); break; } } file_path = argv[optind]; if (!file_path) { print_usage(basename(argv[0])); exit(EXIT_FAILURE); } for (i = 0; i < ARRAY_SIZE(priv.ring); i++) mcp251xfd_dump_ring_init(&priv.ring[i]); err = mcp251xfd_dev_coredump_read(&priv, &mem, file_path); if (err) err = mcp251xfd_regmap_read(&priv, &mem, file_path); if (err) { fprintf(stderr, "Unable to read file: '%s'\n", file_path); exit(EXIT_FAILURE); } mcp251xfd_dump(&priv); exit(EXIT_SUCCESS); }