[PATCH] drivers: net: fsl-mc: add a command which dumps the MC log
Extended fsl_mc command adding an extra option dump_log Signed-off-by: Cosmin-Florin Aluchenesei --- drivers/net/fsl-mc/mc.c | 89 - include/fsl-mc/fsl_mc.h | 9 + 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index 914ec001ec..edf9f7224d 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,16 @@ #define MC_BOOT_ENV_VAR"mcinitcmd" #define MC_DRAM_BLOCK_DEFAULT_SIZE (512UL * 1024 * 1024) +#define MC_BUFFER_SIZE (1024 * 1024 * 16) +#define MAGIC_MC 0x4d430100 +#define MC_FW_ADDR_MASK_LOW 0xE000 +#define MC_FW_ADDR_MASK_HIGH 0X1 +#define MC_STRUCT_BUFFER_OFFSET 0x0100 +#define MC_OFFSET_DELTA MC_STRUCT_BUFFER_OFFSET + +#define LOG_HEADER_FLAG_BUFFER_WRAPAROUND 0x8000 +#define LAST_BYTE(a) ((a) & ~(LOG_HEADER_FLAG_BUFFER_WRAPAROUND)) + DECLARE_GLOBAL_DATA_PTR; static int mc_memset_resv_ram; static struct mc_version mc_ver_info; @@ -1774,11 +1785,78 @@ err: return err; } +static void print_k_bytes(const void *buf, ssize_t *size) +{ + while (*size > 0) { + int count = printf("%s", (char *)buf); + + buf += count; + *size -= count; + } +} + +static void mc_dump_log(void) +{ + struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; + u64 high = in_le64(_ccsr_regs->reg_mcfbahr) & MC_FW_ADDR_MASK_HIGH; + u64 low = in_le64(_ccsr_regs->reg_mcfbalr) & MC_FW_ADDR_MASK_LOW; + u64 mc_addr = (high << 32) | low | MC_STRUCT_BUFFER_OFFSET; + u32 buf_len, wrapped, last_byte, magic, buf_start; + struct log_header *header; + ssize_t size, bytes_end; + const void *end_of_data; + const void *map_addr; + const void *end_addr; + const void *cur_ptr; + const void *buf; + + map_addr = map_sysmem(mc_addr + MC_STRUCT_BUFFER_OFFSET, + MC_BUFFER_SIZE); + header = (struct log_header *)map_addr; + last_byte = in_le32(>last_byte); + buf_len = in_le32(>buf_length); + magic = in_le32(>magic_word); + buf_start = in_le32(>buf_start); + buf = map_addr + buf_start - MC_OFFSET_DELTA; + end_addr = buf + buf_len; + wrapped = last_byte & LOG_HEADER_FLAG_BUFFER_WRAPAROUND; + end_of_data = buf + LAST_BYTE(last_byte); + + if (magic != MAGIC_MC) { + puts("Magic number is not valid\n"); + printf("expected = %08x, received = %08x\n", MAGIC_MC, magic); + goto err_magic; + } + + if (wrapped && end_of_data != end_addr) + cur_ptr = end_of_data + 1; + else + cur_ptr = buf; + + if (cur_ptr <= end_of_data) + size = end_of_data - cur_ptr; + else + size = (end_addr - cur_ptr) + (end_of_data - buf); + + bytes_end = end_addr - cur_ptr; + if (size > bytes_end) { + print_k_bytes(cur_ptr, _end); + + cur_ptr = buf; + size -= bytes_end; + } + + print_k_bytes(buf, ); + +err_magic: + unmap_sysmem(map_addr); +} + static int do_fsl_mc(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { int err = 0; - if (argc < 3) + if (argc < 2) goto usage; switch (argv[1][0]) { @@ -1788,6 +1866,8 @@ static int do_fsl_mc(struct cmd_tbl *cmdtp, int flag, int argc, #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET u64 aiop_fw_addr; #endif + if (argc < 3) + goto usage; sub_cmd = argv[2][0]; @@ -1919,6 +1999,12 @@ static int do_fsl_mc(struct cmd_tbl *cmdtp, int flag, int argc, } break; } + case 'd': + if (argc > 2) + goto usage; + + mc_dump_log(); + break; default: printf("Invalid option: %s\n", argv[1]); goto usage; @@ -1937,6 +2023,7 @@ U_BOOT_CMD( "fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n" "fsl_mc apply spb [spb_addr] - Apply SPB Soft Parser Blob\n" "fsl_mc start aiop [FW_addr] - Start AIOP\n" + "fsl_mc dump_log - Dump MC Log\n" ); void mc_env_boot(void) diff --git a/include/fsl-mc/fsl_mc.h b/include/fsl-mc/fsl_mc.h index a8b072ad7c..07a46a4a1b 100644 --- a/include/fsl-mc/fsl_mc.h +++ b/include/fsl-mc/fsl_mc.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2014 Freescale Semiconductor + * Copyright 2021 NXP */ #ifndef __FSL_MC_H__ @@ -52,6 +53,14 @@ struct mc_ccsr_registers { u32 reg_error[]; }; +struct log_header { + u32 magic_word; + char
Re: [PATCH] drivers: net: fsl-mc: add a command which dumps the MC log
On Fri, Oct 01, 2021 at 12:01:07PM +0300, Cosmin-Florin Aluchenesei wrote: > +static void mc_dump_log(void) > +{ > + struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; > + u64 high = in_le64(_ccsr_regs->reg_mcfbahr) & MC_FW_ADDR_MASK_HIGH; > + u64 low = in_le64(_ccsr_regs->reg_mcfbalr) & MC_FW_ADDR_MASK_LOW; > + u64 mc_addr = (high << 32) | low | MC_STRUCT_BUFFER_OFFSET; > + u32 buf_len, wrapped, last_byte, magic, buf_start; > + struct log_header *header; > + ssize_t size, bytes_end; > + const void *end_of_data; > + const void *map_addr; > + const void *end_addr; > + const void *cur_ptr; > + const void *buf; > + > + map_addr = map_sysmem(mc_addr + MC_STRUCT_BUFFER_OFFSET, > + MC_BUFFER_SIZE); This does not work as it is. You are adding the MC_STRUCT_BUFFER_OFFSET twice to the base address of the MC - mc_addr. This means that the magic check below will fail always. A diff like the following fixes the issue. --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -1799,7 +1799,7 @@ static void mc_dump_log(void) struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; u64 high = in_le64(_ccsr_regs->reg_mcfbahr) & MC_FW_ADDR_MASK_HIGH; u64 low = in_le64(_ccsr_regs->reg_mcfbalr) & MC_FW_ADDR_MASK_LOW; - u64 mc_addr = (high << 32) | low | MC_STRUCT_BUFFER_OFFSET; + u64 mc_addr = (high << 32) | low; u32 buf_len, wrapped, last_byte, magic, buf_start; struct log_header *header; ssize_t size, bytes_end; Please fix this and send a v2. Ioana
[PATCH] drivers: net: fsl-mc: add a command which dumps the MC log
Extended fsl_mc command adding an extra option dump_log Signed-off-by: Cosmin-Florin Aluchenesei --- drivers/net/fsl-mc/mc.c | 89 - include/fsl-mc/fsl_mc.h | 9 + 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index 914ec001ec..edf9f7224d 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,16 @@ #define MC_BOOT_ENV_VAR"mcinitcmd" #define MC_DRAM_BLOCK_DEFAULT_SIZE (512UL * 1024 * 1024) +#define MC_BUFFER_SIZE (1024 * 1024 * 16) +#define MAGIC_MC 0x4d430100 +#define MC_FW_ADDR_MASK_LOW 0xE000 +#define MC_FW_ADDR_MASK_HIGH 0X1 +#define MC_STRUCT_BUFFER_OFFSET 0x0100 +#define MC_OFFSET_DELTA MC_STRUCT_BUFFER_OFFSET + +#define LOG_HEADER_FLAG_BUFFER_WRAPAROUND 0x8000 +#define LAST_BYTE(a) ((a) & ~(LOG_HEADER_FLAG_BUFFER_WRAPAROUND)) + DECLARE_GLOBAL_DATA_PTR; static int mc_memset_resv_ram; static struct mc_version mc_ver_info; @@ -1774,11 +1785,78 @@ err: return err; } +static void print_k_bytes(const void *buf, ssize_t *size) +{ + while (*size > 0) { + int count = printf("%s", (char *)buf); + + buf += count; + *size -= count; + } +} + +static void mc_dump_log(void) +{ + struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; + u64 high = in_le64(_ccsr_regs->reg_mcfbahr) & MC_FW_ADDR_MASK_HIGH; + u64 low = in_le64(_ccsr_regs->reg_mcfbalr) & MC_FW_ADDR_MASK_LOW; + u64 mc_addr = (high << 32) | low | MC_STRUCT_BUFFER_OFFSET; + u32 buf_len, wrapped, last_byte, magic, buf_start; + struct log_header *header; + ssize_t size, bytes_end; + const void *end_of_data; + const void *map_addr; + const void *end_addr; + const void *cur_ptr; + const void *buf; + + map_addr = map_sysmem(mc_addr + MC_STRUCT_BUFFER_OFFSET, + MC_BUFFER_SIZE); + header = (struct log_header *)map_addr; + last_byte = in_le32(>last_byte); + buf_len = in_le32(>buf_length); + magic = in_le32(>magic_word); + buf_start = in_le32(>buf_start); + buf = map_addr + buf_start - MC_OFFSET_DELTA; + end_addr = buf + buf_len; + wrapped = last_byte & LOG_HEADER_FLAG_BUFFER_WRAPAROUND; + end_of_data = buf + LAST_BYTE(last_byte); + + if (magic != MAGIC_MC) { + puts("Magic number is not valid\n"); + printf("expected = %08x, received = %08x\n", MAGIC_MC, magic); + goto err_magic; + } + + if (wrapped && end_of_data != end_addr) + cur_ptr = end_of_data + 1; + else + cur_ptr = buf; + + if (cur_ptr <= end_of_data) + size = end_of_data - cur_ptr; + else + size = (end_addr - cur_ptr) + (end_of_data - buf); + + bytes_end = end_addr - cur_ptr; + if (size > bytes_end) { + print_k_bytes(cur_ptr, _end); + + cur_ptr = buf; + size -= bytes_end; + } + + print_k_bytes(buf, ); + +err_magic: + unmap_sysmem(map_addr); +} + static int do_fsl_mc(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { int err = 0; - if (argc < 3) + if (argc < 2) goto usage; switch (argv[1][0]) { @@ -1788,6 +1866,8 @@ static int do_fsl_mc(struct cmd_tbl *cmdtp, int flag, int argc, #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET u64 aiop_fw_addr; #endif + if (argc < 3) + goto usage; sub_cmd = argv[2][0]; @@ -1919,6 +1999,12 @@ static int do_fsl_mc(struct cmd_tbl *cmdtp, int flag, int argc, } break; } + case 'd': + if (argc > 2) + goto usage; + + mc_dump_log(); + break; default: printf("Invalid option: %s\n", argv[1]); goto usage; @@ -1937,6 +2023,7 @@ U_BOOT_CMD( "fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n" "fsl_mc apply spb [spb_addr] - Apply SPB Soft Parser Blob\n" "fsl_mc start aiop [FW_addr] - Start AIOP\n" + "fsl_mc dump_log - Dump MC Log\n" ); void mc_env_boot(void) diff --git a/include/fsl-mc/fsl_mc.h b/include/fsl-mc/fsl_mc.h index a8b072ad7c..07a46a4a1b 100644 --- a/include/fsl-mc/fsl_mc.h +++ b/include/fsl-mc/fsl_mc.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2014 Freescale Semiconductor + * Copyright 2021 NXP */ #ifndef __FSL_MC_H__ @@ -52,6 +53,14 @@ struct mc_ccsr_registers { u32 reg_error[]; }; +struct log_header { + u32 magic_word; + char