* [PATCH] commands: add new of_fixup command to list and disable DT fixups
@ 2023-02-17 20:31 Ahmad Fatoum
2023-02-21 10:08 ` Sascha Hauer
0 siblings, 1 reply; 3+ messages in thread
From: Ahmad Fatoum @ 2023-02-17 20:31 UTC (permalink / raw)
To: barebox; +Cc: Daniel Brát, Ahmad Fatoum
For debugging, it can be useful to disable a fixup to rule out it causing
issues. For platforms supporting kallsyms, we can readily allow enabling
and disabling fixups by name, so let's add a command that does just that.
Suggested-by: Daniel Brát <danek.brat@gmail.com>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
commands/Kconfig | 15 ++++++++
commands/Makefile | 1 +
commands/of_fixup.c | 86 +++++++++++++++++++++++++++++++++++++++++++++
common/kallsyms.c | 8 ++---
common/oftree.c | 17 +++++----
drivers/of/Kconfig | 6 ++++
include/kallsyms.h | 4 +++
include/of.h | 10 ++++++
8 files changed, 137 insertions(+), 10 deletions(-)
create mode 100644 commands/of_fixup.c
diff --git a/commands/Kconfig b/commands/Kconfig
index 7d01dddd3474..fc0df5550418 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -2266,6 +2266,21 @@ config CMD_OF_DISPLAY_TIMINGS
-s path select display-timings and register oftree fixup
-f dtb work on dtb. Has no effect on -s option
+config CMD_OF_FIXUP
+ tristate
+ select OFTREE
+ select OF_FIXUP_TOGGLE
+ depends on KALLSYMS
+ prompt "of_fixup"
+ help
+ List and enable/disable fixups
+
+ Usage: of_fixup [-de] [fixups...]
+
+ Options:
+ -d disable fixup
+ -e re-enable fixup
+
config CMD_OF_FIXUP_STATUS
tristate
select OFTREE
diff --git a/commands/Makefile b/commands/Makefile
index c0b0a22b08c1..e5cc21f1970a 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -87,6 +87,7 @@ obj-$(CONFIG_CMD_OF_PROPERTY) += of_property.o
obj-$(CONFIG_CMD_OF_NODE) += of_node.o
obj-$(CONFIG_CMD_OF_DUMP) += of_dump.o
obj-$(CONFIG_CMD_OF_DISPLAY_TIMINGS) += of_display_timings.o
+obj-$(CONFIG_CMD_OF_FIXUP) += of_fixup.o
obj-$(CONFIG_CMD_OF_FIXUP_STATUS) += of_fixup_status.o
obj-$(CONFIG_CMD_OF_OVERLAY) += of_overlay.o
obj-$(CONFIG_CMD_MAGICVAR) += magicvar.o
diff --git a/commands/of_fixup.c b/commands/of_fixup.c
new file mode 100644
index 000000000000..e323b38a93ef
--- /dev/null
+++ b/commands/of_fixup.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/*
+ * of_fixup.c - List and remove OF fixups
+ */
+
+#include <common.h>
+#include <kallsyms.h>
+#include <of.h>
+#include <command.h>
+#include <malloc.h>
+#include <complete.h>
+#include <getopt.h>
+#include <string.h>
+
+static int do_of_fixup(int argc, char *argv[])
+{
+ struct of_fixup *of_fixup;
+ int opt, enable = -1;
+
+ while ((opt = getopt(argc, argv, "ed")) > 0) {
+ switch (opt) {
+ case 'e':
+ enable = 1;
+ break;
+ case 'd':
+ enable = 0;
+ break;
+ default:
+ return COMMAND_ERROR_USAGE;
+ }
+ }
+
+ argv += optind;
+ argc -= optind;
+
+ if ((enable < 0 && argc > 0) || (enable >= 0 && argc == 0))
+ return COMMAND_ERROR_USAGE;
+
+ list_for_each_entry(of_fixup, &of_fixup_list, list) {
+ int i;
+ ulong addr = (ulong)of_fixup->fixup;
+ char sym[KSYM_SYMBOL_LEN];
+ const char *name;
+
+ name = kallsyms_lookup(addr, NULL, NULL, NULL, sym);
+ if (!name) {
+ sprintf(sym, "<0x%lx>", addr);
+ name = sym;
+ }
+
+ if (enable == -1) {
+ printf("%s(0x%p)%s\n", name, of_fixup->context,
+ of_fixup->disabled ? " [DISABELD]" : "");
+ continue;
+ }
+
+ for (i = 0; i < argc; i++) {
+ if (strcmp(name, argv[i]) != 0)
+ continue;
+
+ of_fixup->disabled = !enable;
+ }
+ }
+
+ return 0;
+}
+
+BAREBOX_CMD_HELP_START(of_fixup)
+BAREBOX_CMD_HELP_TEXT("Disable or re-enable an already registered fixup for the device tree.")
+BAREBOX_CMD_HELP_TEXT("Call without arguments to list all fixups")
+BAREBOX_CMD_HELP_TEXT("")
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT("-d", "disable fixup")
+BAREBOX_CMD_HELP_OPT("-e", "re-enable fixup")
+BAREBOX_CMD_HELP_OPT("fixups", "List of fixups to enable or disable")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(of_fixup)
+ .cmd = do_of_fixup,
+ BAREBOX_CMD_DESC("list and enable/disable fixups")
+ BAREBOX_CMD_OPTS("[-de] [fixups...]")
+ BAREBOX_CMD_GROUP(CMD_GRP_MISC)
+ BAREBOX_CMD_COMPLETE(empty_complete)
+ BAREBOX_CMD_HELP(cmd_of_fixup_help)
+BAREBOX_CMD_END
diff --git a/common/kallsyms.c b/common/kallsyms.c
index a9b2b9368992..3c5904f8a833 100644
--- a/common/kallsyms.c
+++ b/common/kallsyms.c
@@ -165,10 +165,10 @@ static unsigned long get_symbol_pos(unsigned long addr,
* It resides in a module.
* - We also guarantee that modname will be valid until rescheduled.
*/
-static const char *kallsyms_lookup(unsigned long addr,
- unsigned long *symbolsize,
- unsigned long *offset,
- char **modname, char *namebuf)
+const char *kallsyms_lookup(unsigned long addr,
+ unsigned long *symbolsize,
+ unsigned long *offset,
+ char **modname, char *namebuf)
{
namebuf[KSYM_NAME_LEN - 1] = 0;
namebuf[0] = 0;
diff --git a/common/oftree.c b/common/oftree.c
index 4beadc5aaa89..86a1ba96150e 100644
--- a/common/oftree.c
+++ b/common/oftree.c
@@ -350,13 +350,15 @@ int of_register_set_status_fixup(const char *path, bool status)
return of_register_fixup(of_fixup_status, (void *)data);
}
-struct of_fixup {
- int (*fixup)(struct device_node *, void *);
- void *context;
- struct list_head list;
-};
+LIST_HEAD(of_fixup_list);
-static LIST_HEAD(of_fixup_list);
+static inline bool of_fixup_disabled(struct of_fixup *fixup)
+{
+ if (!IS_ENABLED(CONFIG_OF_FIXUP_TOGGLE))
+ return false;
+
+ return fixup->disabled;
+}
int of_register_fixup(int (*fixup)(struct device_node *, void *), void *context)
{
@@ -401,6 +403,9 @@ int of_fix_tree(struct device_node *node)
of_overlay_load_firmware_clear();
list_for_each_entry(of_fixup, &of_fixup_list, list) {
+ if (of_fixup_disabled(of_fixup))
+ continue;
+
ret = of_fixup->fixup(node, of_fixup->context);
if (ret)
pr_warn("Failed to fixup node in %pS: %s\n",
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 4dc40b27f442..1269cf8a459b 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -3,6 +3,12 @@ config OFTREE
select DTC
bool
+config OF_FIXUP_TOGGLE
+ bool
+ help
+ This is selected when some device tree fixups may be selectively
+ disabled.
+
config OFTREE_MEM_GENERIC
depends on OFTREE
depends on PPC || ARM || EFI_BOOTUP || OPENRISC || SANDBOX || RISCV || KVX
diff --git a/include/kallsyms.h b/include/kallsyms.h
index e0b3ff7cd503..f61efc9e0c42 100644
--- a/include/kallsyms.h
+++ b/include/kallsyms.h
@@ -6,6 +6,10 @@
#define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + 1)
unsigned long kallsyms_lookup_name(const char *name);
+const char *kallsyms_lookup(unsigned long addr,
+ unsigned long *symbolsize,
+ unsigned long *offset,
+ char **modname, char *namebuf);
/* Look up a kernel symbol and return it in a text buffer. */
int sprint_symbol(char *buffer, unsigned long address);
diff --git a/include/of.h b/include/of.h
index 7ee1304b932b..282c11ee8c49 100644
--- a/include/of.h
+++ b/include/of.h
@@ -328,6 +328,16 @@ int of_find_path_by_node(struct device_node *node, char **outpath, unsigned flag
struct device_node *of_find_node_by_devpath(struct device_node *root, const char *path);
int of_register_fixup(int (*fixup)(struct device_node *, void *), void *context);
int of_unregister_fixup(int (*fixup)(struct device_node *, void *), void *context);
+
+struct of_fixup {
+ int (*fixup)(struct device_node *, void *);
+ void *context;
+ struct list_head list;
+ bool disabled;
+};
+
+extern struct list_head of_fixup_list;
+
int of_register_set_status_fixup(const char *node, bool status);
struct device_node *of_find_node_by_alias(struct device_node *root,
const char *alias);
--
2.30.2
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] commands: add new of_fixup command to list and disable DT fixups
2023-02-17 20:31 [PATCH] commands: add new of_fixup command to list and disable DT fixups Ahmad Fatoum
@ 2023-02-21 10:08 ` Sascha Hauer
2023-04-20 20:15 ` Ahmad Fatoum
0 siblings, 1 reply; 3+ messages in thread
From: Sascha Hauer @ 2023-02-21 10:08 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox, Daniel Brát
On Fri, Feb 17, 2023 at 09:31:48PM +0100, Ahmad Fatoum wrote:
> For debugging, it can be useful to disable a fixup to rule out it causing
> issues. For platforms supporting kallsyms, we can readily allow enabling
> and disabling fixups by name, so let's add a command that does just that.
>
> Suggested-by: Daniel Brát <danek.brat@gmail.com>
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> commands/Kconfig | 15 ++++++++
> commands/Makefile | 1 +
> commands/of_fixup.c | 86 +++++++++++++++++++++++++++++++++++++++++++++
> common/kallsyms.c | 8 ++---
> common/oftree.c | 17 +++++----
> drivers/of/Kconfig | 6 ++++
> include/kallsyms.h | 4 +++
> include/of.h | 10 ++++++
> 8 files changed, 137 insertions(+), 10 deletions(-)
> create mode 100644 commands/of_fixup.c
>
> +static int do_of_fixup(int argc, char *argv[])
> +{
> + struct of_fixup *of_fixup;
> + int opt, enable = -1;
> +
> + while ((opt = getopt(argc, argv, "ed")) > 0) {
> + switch (opt) {
> + case 'e':
> + enable = 1;
> + break;
> + case 'd':
> + enable = 0;
> + break;
> + default:
> + return COMMAND_ERROR_USAGE;
> + }
> + }
> +
> + argv += optind;
> + argc -= optind;
> +
> + if ((enable < 0 && argc > 0) || (enable >= 0 && argc == 0))
> + return COMMAND_ERROR_USAGE;
> +
> + list_for_each_entry(of_fixup, &of_fixup_list, list) {
> + int i;
> + ulong addr = (ulong)of_fixup->fixup;
> + char sym[KSYM_SYMBOL_LEN];
> + const char *name;
> +
> + name = kallsyms_lookup(addr, NULL, NULL, NULL, sym);
> + if (!name) {
> + sprintf(sym, "<0x%lx>", addr);
> + name = sym;
> + }
Does this fallback make sense? kallsyms_lookup() should always return a
name, otherwise something is really wrong.
> +
> + if (enable == -1) {
> + printf("%s(0x%p)%s\n", name, of_fixup->context,
> + of_fixup->disabled ? " [DISABELD]" : "");
s/DISABELD/DISABLED/
We can have the same fixup function with different contexts, that's why
you print the context pointer here. Shouldn't we then have a way to
disable a specific fixup, like "of_fixup -d mtd_partition_fixup(0x2fed7a00)"?
Sascha
> +config OF_FIXUP_TOGGLE
> + bool
> + help
> + This is selected when some device tree fixups may be selectively
> + disabled.
Why does this have an extra config option? It doesn't look like it's
saving a lot of binary space.
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] commands: add new of_fixup command to list and disable DT fixups
2023-02-21 10:08 ` Sascha Hauer
@ 2023-04-20 20:15 ` Ahmad Fatoum
0 siblings, 0 replies; 3+ messages in thread
From: Ahmad Fatoum @ 2023-04-20 20:15 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox, Daniel Brát
Hello Sascha,
On 21.02.23 11:08, Sascha Hauer wrote:
> On Fri, Feb 17, 2023 at 09:31:48PM +0100, Ahmad Fatoum wrote:
>> For debugging, it can be useful to disable a fixup to rule out it causing
>> issues. For platforms supporting kallsyms, we can readily allow enabling
>> and disabling fixups by name, so let's add a command that does just that.
>>
>> Suggested-by: Daniel Brát <danek.brat@gmail.com>
>> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
>> ---
>> commands/Kconfig | 15 ++++++++
>> commands/Makefile | 1 +
>> commands/of_fixup.c | 86 +++++++++++++++++++++++++++++++++++++++++++++
>> common/kallsyms.c | 8 ++---
>> common/oftree.c | 17 +++++----
>> drivers/of/Kconfig | 6 ++++
>> include/kallsyms.h | 4 +++
>> include/of.h | 10 ++++++
>> 8 files changed, 137 insertions(+), 10 deletions(-)
>> create mode 100644 commands/of_fixup.c
>>
>> +static int do_of_fixup(int argc, char *argv[])
>> +{
>> + struct of_fixup *of_fixup;
>> + int opt, enable = -1;
>> +
>> + while ((opt = getopt(argc, argv, "ed")) > 0) {
>> + switch (opt) {
>> + case 'e':
>> + enable = 1;
>> + break;
>> + case 'd':
>> + enable = 0;
>> + break;
>> + default:
>> + return COMMAND_ERROR_USAGE;
>> + }
>> + }
>> +
>> + argv += optind;
>> + argc -= optind;
>> +
>> + if ((enable < 0 && argc > 0) || (enable >= 0 && argc == 0))
>> + return COMMAND_ERROR_USAGE;
>> +
>> + list_for_each_entry(of_fixup, &of_fixup_list, list) {
>> + int i;
>> + ulong addr = (ulong)of_fixup->fixup;
>> + char sym[KSYM_SYMBOL_LEN];
>> + const char *name;
>> +
>> + name = kallsyms_lookup(addr, NULL, NULL, NULL, sym);
>> + if (!name) {
>> + sprintf(sym, "<0x%lx>", addr);
>> + name = sym;
>> + }
>
> Does this fallback make sense? kallsyms_lookup() should always return a
> name, otherwise something is really wrong.
Fixup may be registered within a module, which barebox kallsyms doesn't
yet support.
>
>> +
>> + if (enable == -1) {
>> + printf("%s(0x%p)%s\n", name, of_fixup->context,
>> + of_fixup->disabled ? " [DISABELD]" : "");
>
> s/DISABELD/DISABLED/
Will fix.
> We can have the same fixup function with different contexts, that's why
> you print the context pointer here. Shouldn't we then have a way to
> disable a specific fixup, like "of_fixup -d mtd_partition_fixup(0x2fed7a00)"?
The command is meant for quick testing. To make sense of context pointers,
a map file or an instrumented barebox is needed, so it's not that useful
to be able to filter by context pointer IMO.
>
> Sascha
>
>> +config OF_FIXUP_TOGGLE
>> + bool
>> + help
>> + This is selected when some device tree fixups may be selectively
>> + disabled.
>
> Why does this have an extra config option? It doesn't look like it's
> saving a lot of binary space.
I can drop it, sure.
Cheers,
Ahmad
>
> Sascha
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2023-04-20 20:16 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-17 20:31 [PATCH] commands: add new of_fixup command to list and disable DT fixups Ahmad Fatoum
2023-02-21 10:08 ` Sascha Hauer
2023-04-20 20:15 ` Ahmad Fatoum
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox