[PATCH] drivers: net: fsl-mc: add a command which dumps the MC log

2021-10-07 Thread Cosmin-Florin Aluchenesei
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

2021-10-07 Thread Ioana Ciornei
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

2021-10-01 Thread Cosmin-Florin Aluchenesei
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