[PATCH 02/38] x86: Allow listing MTRRs in SPL

Heinrich Schuchardt xypron.glpk at gmx.de
Fri Mar 31 00:10:23 CEST 2023



Am 30. März 2023 23:31:51 MESZ schrieb Simon Glass <sjg at chromium.org>:
>When using video in SPL it is useful to see the values of the MTRR
>registers. Move this code into a shared file, so it can be called from
>SPL easily.
>
>Signed-off-by: Simon Glass <sjg at chromium.org>
>---
>
> arch/x86/cpu/mtrr.c         | 61 +++++++++++++++++++++++++++++++++++++
> arch/x86/include/asm/mtrr.h | 20 ++++++++++++
> cmd/x86/mtrr.c              | 60 +++---------------------------------
> 3 files changed, 85 insertions(+), 56 deletions(-)
>
>diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c
>index e69dfb552b16..1b5f24aab317 100644
>--- a/arch/x86/cpu/mtrr.c
>+++ b/arch/x86/cpu/mtrr.c
>@@ -30,6 +30,16 @@
> 
> DECLARE_GLOBAL_DATA_PTR;
> 
>+const char *const mtrr_type_name[MTRR_TYPE_COUNT] = {
>+	"Uncacheable",
>+	"Combine",
>+	"2",
>+	"3",
>+	"Through",
>+	"Protect",
>+	"Back",
>+};
>+
> /* Prepare to adjust MTRRs */
> void mtrr_open(struct mtrr_state *state, bool do_caches)
> {
>@@ -320,3 +330,54 @@ int mtrr_set(int cpu_select, int reg, u64 base, u64 mask)
> 
> 	return mtrr_start_op(cpu_select, &oper);
> }
>+
>+static void read_mtrrs_(void *arg)
>+{
>+	struct mtrr_info *info = arg;
>+
>+	mtrr_read_all(info);
>+}
>+
>+int mtrr_list(int reg_count, int cpu_select)
>+{
>+	struct mtrr_info info;
>+	int ret;
>+	int i;
>+
>+	printf("Reg Valid Write-type   %-16s %-16s %-16s\n", "Base   ||",
>+	       "Mask   ||", "Size   ||");
>+	memset(&info, '\0', sizeof(info));
>+	ret = mp_run_on_cpus(cpu_select, read_mtrrs_, &info);
>+	if (ret)
>+		return log_msg_ret("run", ret);
>+	for (i = 0; i < reg_count; i++) {
>+		const char *type = "Invalid";
>+		u64 base, mask, size;
>+		bool valid;
>+
>+		base = info.mtrr[i].base;
>+		mask = info.mtrr[i].mask;
>+		size = ~mask & ((1ULL << CONFIG_CPU_ADDR_BITS) - 1);
>+		size |= (1 << 12) - 1;
>+		size += 1;
>+		valid = mask & MTRR_PHYS_MASK_VALID;
>+		type = mtrr_type_name[base & MTRR_BASE_TYPE_MASK];
>+		printf("%d   %-5s %-12s %016llx %016llx %016llx\n", i,
>+		       valid ? "Y" : "N", type, base & ~MTRR_BASE_TYPE_MASK,
>+		       mask & ~MTRR_PHYS_MASK_VALID, size);
>+	}
>+
>+	return 0;
>+}
>+
>+int mtrr_get_type_by_name(const char *typename)
>+{
>+	int i;
>+
>+	for (i = 0; i < MTRR_TYPE_COUNT; i++) {
>+		if (*typename == *mtrr_type_name[i])
>+			return i;
>+	}
>+
>+	return -EINVAL;
>+};
>diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
>index ca2edc7878f7..2e995f540616 100644
>--- a/arch/x86/include/asm/mtrr.h
>+++ b/arch/x86/include/asm/mtrr.h
>@@ -190,6 +190,26 @@ int mtrr_set(int cpu_select, int reg, u64 base, u64 mask);
>  */
> int mtrr_get_var_count(void);
> 
>+/**
>+ * mtrr_list() - List the MTRRs
>+ *
>+ * Shows a list of all the MTRRs including their values
>+ *
>+ * @reg_count: Number of registers to show. You can use mtrr_get_var_count() for
>+ * this
>+ * @cpu_select: CPU to use. Use MP_SELECT_BSP for the boot CPU
>+ * Returns: 0 if OK, -ve if the CPU was not found
>+ */
>+int mtrr_list(int reg_count, int cpu_select);
>+
>+/**
>+ * mtrr_get_type_by_name() - Get the type of an MTRR given its type name
>+ *
>+ * @typename: Name to check
>+ * Returns: MTRR type (MTRR_TYPE_...) or -EINVAL if invalid
>+ */
>+int mtrr_get_type_by_name(const char *typename);
>+
> #endif
> 
> #if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0)
>diff --git a/cmd/x86/mtrr.c b/cmd/x86/mtrr.c
>index ff4be6b7bf5b..fd0e67e46eb3 100644
>--- a/cmd/x86/mtrr.c
>+++ b/cmd/x86/mtrr.c
>@@ -10,71 +10,19 @@
> #include <asm/mp.h>
> #include <asm/mtrr.h>
> 
>-static const char *const mtrr_type_name[MTRR_TYPE_COUNT] = {
>-	"Uncacheable",
>-	"Combine",
>-	"2",
>-	"3",
>-	"Through",
>-	"Protect",
>-	"Back",
>-};


Adding a "write-" prefix would make the meaning clearer

{
"uncachable", /* 0 */ 
"write-combining", /* 1 */ 
"2", /* 2 */
"3", /* 3 */ 
"write-through", /* 4 */
"write-protect", /* 5 */
"write-back", /* 6 */ 
};

Please, provide /doc/usage/cmd/mtrr.rst.

Best regards

Heinrich 

>-
>-static void read_mtrrs(void *arg)
>-{
>-	struct mtrr_info *info = arg;
>-
>-	mtrr_read_all(info);
>-}
>-
>-static int do_mtrr_list(int reg_count, int cpu_select)
>-{
>-	struct mtrr_info info;
>-	int ret;
>-	int i;
>-
>-	printf("Reg Valid Write-type   %-16s %-16s %-16s\n", "Base   ||",
>-	       "Mask   ||", "Size   ||");
>-	memset(&info, '\0', sizeof(info));
>-	ret = mp_run_on_cpus(cpu_select, read_mtrrs, &info);
>-	if (ret)
>-		return log_msg_ret("run", ret);
>-	for (i = 0; i < reg_count; i++) {
>-		const char *type = "Invalid";
>-		uint64_t base, mask, size;
>-		bool valid;
>-
>-		base = info.mtrr[i].base;
>-		mask = info.mtrr[i].mask;
>-		size = ~mask & ((1ULL << CONFIG_CPU_ADDR_BITS) - 1);
>-		size |= (1 << 12) - 1;
>-		size += 1;
>-		valid = mask & MTRR_PHYS_MASK_VALID;
>-		type = mtrr_type_name[base & MTRR_BASE_TYPE_MASK];
>-		printf("%d   %-5s %-12s %016llx %016llx %016llx\n", i,
>-		       valid ? "Y" : "N", type, base & ~MTRR_BASE_TYPE_MASK,
>-		       mask & ~MTRR_PHYS_MASK_VALID, size);
>-	}
>-
>-	return 0;
>-}
>-
> static int do_mtrr_set(int cpu_select, uint reg, int argc, char *const argv[])
> {
> 	const char *typename = argv[0];
> 	uint32_t start, size;
> 	uint64_t base, mask;
>-	int i, type = -1;
>+	int type = -1;
> 	bool valid;
> 	int ret;
> 
> 	if (argc < 3)
> 		return CMD_RET_USAGE;
>-	for (i = 0; i < MTRR_TYPE_COUNT; i++) {
>-		if (*typename == *mtrr_type_name[i])
>-			type = i;
>-	}
>-	if (type == -1) {
>+	type = mtrr_get_type_by_name(typename);
>+	if (type < 0) {
> 		printf("Invalid type name %s\n", typename);
> 		return CMD_RET_USAGE;
> 	}
>@@ -147,7 +95,7 @@ static int do_mtrr(struct cmd_tbl *cmdtp, int flag, int argc,
> 				printf("\n");
> 			if (i < MP_SELECT_ALL)
> 				printf("CPU %d:\n", i);
>-			ret = do_mtrr_list(reg_count, i);
>+			ret = mtrr_list(reg_count, i);
> 			if (ret) {
> 				printf("Failed to read CPU %s (err=%d)\n",
> 				       i < MP_SELECT_ALL ? simple_itoa(i) : "",


More information about the U-Boot mailing list