There's no reason to restrict mmuinfo to ARMv7 or ARM at all for that matter. Prepare extending it for ARMv8 support by splitting off the 32-bit parts. While at it, make the output available for debuggin by exporting a mmuinfo() function. Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> --- arch/arm/cpu/Makefile | 2 +- arch/arm/cpu/mmuinfo.c | 79 ++++++--------------------------- arch/arm/cpu/mmuinfo_32.c | 80 ++++++++++++++++++++++++++++++++++ arch/arm/include/asm/mmuinfo.h | 8 ++++ commands/Kconfig | 1 + common/Kconfig | 3 ++ include/mmu.h | 10 +++++ 7 files changed, 117 insertions(+), 66 deletions(-) create mode 100644 arch/arm/cpu/mmuinfo_32.c create mode 100644 arch/arm/include/asm/mmuinfo.h diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile index 0e4fa69229a6..a271de2c1f38 100644 --- a/arch/arm/cpu/Makefile +++ b/arch/arm/cpu/Makefile @@ -27,7 +27,7 @@ obj-$(CONFIG_ARM_PSCI_CLIENT) += psci-client.o # Any variants can be called as start-armxyz.S # obj-$(CONFIG_CMD_ARM_CPUINFO) += cpuinfo.o -obj-$(CONFIG_CMD_ARM_MMUINFO) += mmuinfo.o +obj-$(CONFIG_MMUINFO) += mmuinfo.o mmuinfo_32.o obj-$(CONFIG_OFDEVICE) += dtb.o ifeq ($(CONFIG_MMU),) diff --git a/arch/arm/cpu/mmuinfo.c b/arch/arm/cpu/mmuinfo.c index 1147c0a305b3..49e393149b69 100644 --- a/arch/arm/cpu/mmuinfo.c +++ b/arch/arm/cpu/mmuinfo.c @@ -1,91 +1,40 @@ // SPDX-License-Identifier: GPL-2.0-only // SPDX-FileCopyrightText: 2012 Jan Luebbe <j.luebbe@xxxxxxxxxxxxxx>, Pengutronix /* - * mmuinfo.c - Show MMU/cache information from cp15 registers + * mmuinfo.c - Show MMU/cache information */ #include <common.h> #include <command.h> +#include <asm/mmuinfo.h> +#include <asm/system_info.h> +#include <mmu.h> -static char *inner_attr[] = { - "0b000 Non-cacheable", - "0b001 Strongly-ordered", - "0b010 (reserved)", - "0b011 Device", - "0b100 (reserved)", - "0b101 Write-Back, Write-Allocate", - "0b110 Write-Through", - "0b111 Write-Back, no Write-Allocate", -}; - -static char *outer_attr[] = { - "0b00 Non-cacheable", - "0b01 Write-Back, Write-Allocate", - "0b10 Write-Through, no Write-Allocate", - "0b11 Write-Back, no Write-Allocate", -}; - -static void decode_par(unsigned long par) +int mmuinfo(void *addr) { - printf(" Physical Address [31:12]: 0x%08lx\n", par & 0xFFFFF000); - printf(" Reserved [11]: 0x%lx\n", (par >> 11) & 0x1); - printf(" Not Outer Shareable [10]: 0x%lx\n", (par >> 10) & 0x1); - printf(" Non-Secure [9]: 0x%lx\n", (par >> 9) & 0x1); - printf(" Impl. def. [8]: 0x%lx\n", (par >> 8) & 0x1); - printf(" Shareable [7]: 0x%lx\n", (par >> 7) & 0x1); - printf(" Inner mem. attr. [6:4]: 0x%lx (%s)\n", (par >> 4) & 0x7, - inner_attr[(par >> 4) & 0x7]); - printf(" Outer mem. attr. [3:2]: 0x%lx (%s)\n", (par >> 2) & 0x3, - outer_attr[(par >> 2) & 0x3]); - printf(" SuperSection [1]: 0x%lx\n", (par >> 1) & 0x1); - printf(" Failure [0]: 0x%lx\n", (par >> 0) & 0x1); + if (IS_ENABLED(CONFIG_CPU_V7) && cpu_architecture() == CPU_ARCH_ARMv7) + return mmuinfo_v7(addr); + + return -ENOSYS; } -static int do_mmuinfo(int argc, char *argv[]) +static __maybe_unused int do_mmuinfo(int argc, char *argv[]) { - unsigned long addr = 0, priv_read, priv_write; + unsigned long addr; if (argc < 2) return COMMAND_ERROR_USAGE; addr = strtoul_suffix(argv[1], NULL, 0); - __asm__ __volatile__( - "mcr p15, 0, %0, c7, c8, 0 @ write VA to PA translation (priv read)\n" - : - : "r" (addr) - : "memory"); - - __asm__ __volatile__( - "mrc p15, 0, %0, c7, c4, 0 @ read PAR\n" - : "=r" (priv_read) - : - : "memory"); - - __asm__ __volatile__( - "mcr p15, 0, %0, c7, c8, 1 @ write VA to PA translation (priv write)\n" - : - : "r" (addr) - : "memory"); - - __asm__ __volatile__( - "mrc p15, 0, %0, c7, c4, 0 @ read PAR\n" - : "=r" (priv_write) - : - : "memory"); - - printf("PAR result for 0x%08lx: \n", addr); - printf(" privileged read: 0x%08lx\n", priv_read); - decode_par(priv_read); - printf(" privileged write: 0x%08lx\n", priv_write); - decode_par(priv_write); - - return 0; + return mmuinfo((void *)addr); } +#ifdef CONFIG_COMMAND_SUPPORT BAREBOX_CMD_START(mmuinfo) .cmd = do_mmuinfo, BAREBOX_CMD_DESC("show MMU/cache information of an address") BAREBOX_CMD_OPTS("ADDRESS") BAREBOX_CMD_GROUP(CMD_GRP_INFO) BAREBOX_CMD_END +#endif diff --git a/arch/arm/cpu/mmuinfo_32.c b/arch/arm/cpu/mmuinfo_32.c new file mode 100644 index 000000000000..e26dabc9b3d9 --- /dev/null +++ b/arch/arm/cpu/mmuinfo_32.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: 2012 Jan Luebbe <j.luebbe@xxxxxxxxxxxxxx>, Pengutronix +/* + * mmuinfo_32.c - Show MMU/cache information from cp15 registers + */ + +#include <common.h> +#include <asm/mmuinfo.h> + +static char *inner_attr[] = { + "0b000 Non-cacheable", + "0b001 Strongly-ordered", + "0b010 (reserved)", + "0b011 Device", + "0b100 (reserved)", + "0b101 Write-Back, Write-Allocate", + "0b110 Write-Through", + "0b111 Write-Back, no Write-Allocate", +}; + +static char *outer_attr[] = { + "0b00 Non-cacheable", + "0b01 Write-Back, Write-Allocate", + "0b10 Write-Through, no Write-Allocate", + "0b11 Write-Back, no Write-Allocate", +}; + +static void decode_par(unsigned long par) +{ + printf(" Physical Address [31:12]: 0x%08lx\n", par & 0xFFFFF000); + printf(" Reserved [11]: 0x%lx\n", (par >> 11) & 0x1); + printf(" Not Outer Shareable [10]: 0x%lx\n", (par >> 10) & 0x1); + printf(" Non-Secure [9]: 0x%lx\n", (par >> 9) & 0x1); + printf(" Impl. def. [8]: 0x%lx\n", (par >> 8) & 0x1); + printf(" Shareable [7]: 0x%lx\n", (par >> 7) & 0x1); + printf(" Inner mem. attr. [6:4]: 0x%lx (%s)\n", (par >> 4) & 0x7, + inner_attr[(par >> 4) & 0x7]); + printf(" Outer mem. attr. [3:2]: 0x%lx (%s)\n", (par >> 2) & 0x3, + outer_attr[(par >> 2) & 0x3]); + printf(" SuperSection [1]: 0x%lx\n", (par >> 1) & 0x1); + printf(" Failure [0]: 0x%lx\n", (par >> 0) & 0x1); +} + +int mmuinfo_v7(void *_addr) +{ + unsigned long addr = (unsigned long)_addr; + unsigned long priv_read, priv_write; + + __asm__ __volatile__( + "mcr p15, 0, %0, c7, c8, 0 @ write VA to PA translation (priv read)\n" + : + : "r" (addr) + : "memory"); + + __asm__ __volatile__( + "mrc p15, 0, %0, c7, c4, 0 @ read PAR\n" + : "=r" (priv_read) + : + : "memory"); + + __asm__ __volatile__( + "mcr p15, 0, %0, c7, c8, 1 @ write VA to PA translation (priv write)\n" + : + : "r" (addr) + : "memory"); + + __asm__ __volatile__( + "mrc p15, 0, %0, c7, c4, 0 @ read PAR\n" + : "=r" (priv_write) + : + : "memory"); + + printf("PAR result for 0x%08lx: \n", addr); + printf(" privileged read: 0x%08lx\n", priv_read); + decode_par(priv_read); + printf(" privileged write: 0x%08lx\n", priv_write); + decode_par(priv_write); + + return 0; +} diff --git a/arch/arm/include/asm/mmuinfo.h b/arch/arm/include/asm/mmuinfo.h new file mode 100644 index 000000000000..bc17bf8982ab --- /dev/null +++ b/arch/arm/include/asm/mmuinfo.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __ARM_ASM_MMUINFO_H__ +#define __ARM_ASM_MMUINFO_H__ + +int mmuinfo_v7(void *addr); + +#endif diff --git a/commands/Kconfig b/commands/Kconfig index c72c2b7758a2..bc697d52b730 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -202,6 +202,7 @@ config CMD_MEMINFO config CMD_ARM_MMUINFO bool "mmuinfo command" depends on CPU_V7 + select MMUINFO help Say yes here to get a mmuinfo command to show some MMU and cache information using the cp15 registers. diff --git a/common/Kconfig b/common/Kconfig index b9e175045608..bd1df889e69a 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -185,6 +185,9 @@ config MMU to enable the data cache which depends on the MMU. See Documentation/mmu.txt for further information. +config MMUINFO + bool + config HAVE_CONFIGURABLE_TEXT_BASE bool diff --git a/include/mmu.h b/include/mmu.h index fd6dbc51ac03..84ec6c5efb3e 100644 --- a/include/mmu.h +++ b/include/mmu.h @@ -3,6 +3,7 @@ #define __MMU_H #include <linux/types.h> +#include <errno.h> #define MAP_UNCACHED 0 #define MAP_CACHED 1 @@ -43,4 +44,13 @@ static inline int remap_range(void *start, size_t size, unsigned flags) return arch_remap_range(start, virt_to_phys(start), size, flags); } +#ifdef CONFIG_MMUINFO +int mmuinfo(void *addr); +#else +static inline int mmuinfo(void *addr) +{ + return -ENOSYS; +} +#endif + #endif -- 2.39.2