[PATCH v3 3/3] commands: iomem: add support for printing type/attributes

Ahmad Fatoum a.fatoum at barebox.org
Thu Jun 5 12:44:01 PDT 2025


To make it easier to verify attributes, let's teach iomem to print the
newly added information. This intentionally only operates on the
resources, the mmuinfo command is what should print information actually
in the page tables.

Signed-off-by: Ahmad Fatoum <a.fatoum at barebox.org>
---
v2 -> v3:
  - new commit
---
 commands/iomemport.c   | 55 +++++++++++++++++++++++++++++++----
 common/resource.c      | 66 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/ioport.h |  3 ++
 3 files changed, 119 insertions(+), 5 deletions(-)

diff --git a/commands/iomemport.c b/commands/iomemport.c
index bbe41f571b48..04d7b100a755 100644
--- a/commands/iomemport.c
+++ b/commands/iomemport.c
@@ -6,13 +6,23 @@
 #include <asm/io.h>
 #include <common.h>
 #include <command.h>
+#include <getopt.h>
+#include <range.h>
 
-static void __print_resources(struct resource *res, int indent)
+static void __print_resources(struct resource *res, int indent,
+			      ulong *addr, bool verbose)
 {
+	char buf[64];
 	struct resource *r;
 	resource_size_t size = resource_size(res);
 	int i;
 
+	if (addr && !region_overlap_end(*addr, *addr, res->start, res->end))
+		return;
+
+	if (verbose)
+		printf("%-58s", resource_typeattr_format(buf, sizeof(buf), res) ?: "");
+
 	for (i = 0; i < indent; i++)
 		printf("  ");
 
@@ -22,26 +32,61 @@ static void __print_resources(struct resource *res, int indent)
 			res->name);
 
 	list_for_each_entry(r, &res->children, sibling) {
-		__print_resources(r, indent + 1);
+		__print_resources(r, indent + 1, addr, verbose);
 	}
+
 }
 
-static void print_resources(struct resource *res)
+static void print_resources(struct resource *res, ulong *addr, bool verbose)
 {
-	__print_resources(res, 0);
+	__print_resources(res, 0, addr, verbose);
 }
 
 static int do_iomem(int argc, char *argv[])
 {
-	print_resources(&iomem_resource);
+	ulong addr, *arg = NULL;
+	bool verbose = false;
+	int opt, ret;
+
+	while((opt = getopt(argc, argv, "v")) > 0) {
+		switch(opt) {
+		case 'v':
+			verbose = true;
+			break;
+		default:
+			return COMMAND_ERROR_USAGE;
+		}
+	}
+
+	argv += optind;
+	argc -= optind;
+
+	if (argc == 1) {
+		ret = kstrtoul(argv[0], 16, &addr);
+		if (ret)
+			return ret;
+		arg = &addr;
+	} else if (argc != 0) {
+		return COMMAND_ERROR_USAGE;
+	}
+
+	print_resources(&iomem_resource, arg, verbose);
 
 	return 0;
 }
 
+BAREBOX_CMD_HELP_START(iomem)
+BAREBOX_CMD_HELP_TEXT("Print barebox view of the physical address space.")
+BAREBOX_CMD_HELP_TEXT("An optional ADDRESS can be specified to get information")
+BAREBOX_CMD_HELP_TEXT("about its region in particular")
+BAREBOX_CMD_HELP_END
+
 BAREBOX_CMD_START(iomem)
 	.cmd		= do_iomem,
 	BAREBOX_CMD_DESC("show IO memory usage")
+	BAREBOX_CMD_OPTS("[-v] [ADDRESS]")
 	BAREBOX_CMD_GROUP(CMD_GRP_INFO)
+	BAREBOX_CMD_HELP(cmd_iomem_help)
 BAREBOX_CMD_END
 
 #if IO_SPACE_LIMIT > 0
diff --git a/common/resource.c b/common/resource.c
index c233b106c17b..152f5a502a1e 100644
--- a/common/resource.c
+++ b/common/resource.c
@@ -183,3 +183,69 @@ struct resource_entry *resource_list_create_entry(struct resource *res,
 	return entry;
 }
 EXPORT_SYMBOL(resource_list_create_entry);
+
+static const char memory_type_name[][13] = {
+	"Reserved",
+	"Loader Code",
+	"Loader Data",
+	"Boot Code",
+	"Boot Data",
+	"Runtime Code",
+	"Runtime Data",
+	"Conventional",
+	"Unusable",
+	"ACPI Reclaim",
+	"ACPI Mem NVS",
+	"MMIO",
+	"MMIO Port",
+	"PAL Code",
+	"Persistent",
+	"Unaccepted",
+};
+
+const char *resource_typeattr_format(char *buf, size_t size,
+				     const struct resource *res)
+{
+	char *pos;
+	int type_len;
+	u64 attr;
+
+	if (!(res->flags & IORESOURCE_TYPE_VALID))
+		return NULL;
+
+	pos = buf;
+	type_len = snprintf(pos, size, "[%-*s",
+			    (int)(sizeof(memory_type_name[0]) - 1),
+			    memory_type_name[res->type]);
+	if (type_len >= size)
+		return buf;
+
+	pos += type_len;
+	size -= type_len;
+
+	attr = res->attrs;
+	if (attr & ~(MEMATTR_UC | MEMATTR_WC | MEMATTR_WT |
+		     MEMATTR_WB | MEMATTR_UCE | MEMATTR_RO |
+		     MEMATTR_WP | MEMATTR_RP | MEMATTR_XP |
+		     MEMATTR_NV | MEMATTR_SP | MEMATTR_MORE_RELIABLE)
+		     )
+		snprintf(pos, size, "|attr=0x%08llx]",
+			 (unsigned long long)attr);
+	else
+		snprintf(pos, size,
+			 "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
+			 res->runtime			? "RUN" : "",
+			 attr & MEMATTR_MORE_RELIABLE	? "MR"  : "",
+			 attr & MEMATTR_SP		? "SP"  : "",
+			 attr & MEMATTR_NV		? "NV"  : "",
+			 attr & MEMATTR_XP		? "XP"  : "",
+			 attr & MEMATTR_RP		? "RP"  : "",
+			 attr & MEMATTR_WP		? "WP"  : "",
+			 attr & MEMATTR_RO		? "RO"  : "",
+			 attr & MEMATTR_UCE		? "UCE" : "",
+			 attr & MEMATTR_WB		? "WB"  : "",
+			 attr & MEMATTR_WT		? "WT"  : "",
+			 attr & MEMATTR_WC		? "WC"  : "",
+			 attr & MEMATTR_UC		? "UC"  : "");
+	return buf;
+}
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 425928df3bfe..199280619da1 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -212,6 +212,9 @@ int release_region(struct resource *res);
 extern struct resource iomem_resource;
 extern struct resource ioport_resource;
 
+const char *resource_typeattr_format(char *buf, size_t size,
+				     const struct resource *res);
+
 static inline void reserve_resource(struct resource *res)
 {
 	res->type = MEMTYPE_RESERVED;
-- 
2.39.5




More information about the barebox mailing list