qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Daniel Henrique Barboza <danielhb413@gmail.com>
To: qemu-devel@nongnu.org
Cc: qemu-ppc@nongnu.org, clg@kaod.org, david@gibson.dropbear.id.au,
	alistair.francis@wdc.com,
	Daniel Henrique Barboza <danielhb413@gmail.com>,
	"Dr . David Alan Gilbert" <dgilbert@redhat.com>
Subject: [PATCH for-7.2 v4 15/21] qmp/hmp, device_tree.c: introduce 'info fdt' command
Date: Fri, 26 Aug 2022 11:11:44 -0300	[thread overview]
Message-ID: <20220826141150.7201-16-danielhb413@gmail.com> (raw)
In-Reply-To: <20220826141150.7201-1-danielhb413@gmail.com>

Reading the FDT requires that the user saves the fdt_blob and then use
'dtc' to read the contents. Saving the file and using 'dtc' is a strong
use case when we need to compare two FDTs, but it's a lot of steps if
you want to do quick check on a certain node or property.

'info fdt' retrieves FDT nodes (and properties, later on) and print it
to the user. This can be used to check the FDT on running machines
without having to save the blob and use 'dtc'.

The implementation is based on the premise that the machine thas a FDT
created using libfdt and pointed by 'machine->fdt'. As long as this
pre-requisite is met the machine should be able to support it.

For now we're going to add the required QMP/HMP boilerplate and the
capability of printing the name of the properties of a given node. Next
patches will extend 'info fdt' to be able to print nodes recursively,
and then individual properties.

This command will always be executed in-band (i.e. holding BQL),
avoiding potential race conditions with machines that might change the
FDT during runtime (e.g. PowerPC 'pseries' machine).

'info fdt' is not something that we expect to be used aside from debugging,
so we're implementing it in QMP as 'x-query-fdt'.

This is an example of 'info fdt' fetching the '/chosen' node of the
pSeries machine:

(qemu) info fdt /chosen
chosen {
    ibm,architecture-vec-5;
    rng-seed;
    ibm,arch-vec-5-platform-support;
    linux,pci-probe-only;
    stdout-path;
    linux,stdout-path;
    qemu,graphic-depth;
    qemu,graphic-height;
    qemu,graphic-width;
};

And the same node for the aarch64 'virt' machine:

(qemu) info fdt /chosen
chosen {
    stdout-path;
    rng-seed;
    kaslr-seed;
};

Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
---
 hmp-commands-info.hx         | 13 ++++++++++
 include/monitor/hmp.h        |  1 +
 include/sysemu/device_tree.h |  4 +++
 monitor/hmp-cmds.c           | 13 ++++++++++
 monitor/qmp-cmds.c           | 12 +++++++++
 qapi/machine.json            | 19 +++++++++++++++
 softmmu/device_tree.c        | 47 ++++++++++++++++++++++++++++++++++++
 7 files changed, 109 insertions(+)

diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 188d9ece3b..743b48865d 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -921,3 +921,16 @@ SRST
   ``stats``
     Show runtime-collected statistics
 ERST
+
+    {
+        .name       = "fdt",
+        .args_type  = "nodepath:s",
+        .params     = "nodepath",
+        .help       = "show firmware device tree node given its path",
+        .cmd        = hmp_info_fdt,
+    },
+
+SRST
+  ``info fdt``
+    Show a firmware device tree node given its path. Requires libfdt.
+ERST
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index d7f324da59..c0883dd1e3 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -135,6 +135,7 @@ void hmp_set_vcpu_dirty_limit(Monitor *mon, const QDict *qdict);
 void hmp_cancel_vcpu_dirty_limit(Monitor *mon, const QDict *qdict);
 void hmp_info_vcpu_dirty_limit(Monitor *mon, const QDict *qdict);
 void hmp_dumpdtb(Monitor *mon, const QDict *qdict);
+void hmp_info_fdt(Monitor *mon, const QDict *qdict);
 void hmp_human_readable_text_helper(Monitor *mon,
                                     HumanReadableText *(*qmp_handler)(Error **));
 void hmp_info_stats(Monitor *mon, const QDict *qdict);
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
index bf7684e4ed..057d13e397 100644
--- a/include/sysemu/device_tree.h
+++ b/include/sysemu/device_tree.h
@@ -14,6 +14,8 @@
 #ifndef DEVICE_TREE_H
 #define DEVICE_TREE_H
 
+#include "qapi/qapi-types-common.h"
+
 void *create_device_tree(int *sizep);
 void *load_device_tree(const char *filename_path, int *sizep);
 #ifdef CONFIG_LINUX
@@ -137,6 +139,8 @@ int qemu_fdt_add_path(void *fdt, const char *path);
 
 void qemu_fdt_dumpdtb(void *fdt, int size);
 void qemu_fdt_qmp_dumpdtb(const char *filename, Error **errp);
+HumanReadableText *qemu_fdt_qmp_query_fdt(const char *nodepath,
+                                          Error **errp);
 
 /**
  * qemu_fdt_setprop_sized_cells_from_array:
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 1c7bfd3b9d..93a4103afa 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -2484,3 +2484,16 @@ void hmp_dumpdtb(Monitor *mon, const QDict *qdict)
         hmp_handle_error(mon, local_err);
     }
 }
+
+void hmp_info_fdt(Monitor *mon, const QDict *qdict)
+{
+    const char *nodepath = qdict_get_str(qdict, "nodepath");
+    Error *err = NULL;
+    g_autoptr(HumanReadableText) info = qmp_x_query_fdt(nodepath, &err);
+
+    if (hmp_handle_error(mon, err)) {
+        return;
+    }
+
+    monitor_printf(mon, "%s", info->human_readable_text);
+}
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index 8415aca08c..db2c6aa7da 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -603,9 +603,21 @@ void qmp_dumpdtb(const char *filename, Error **errp)
 {
     return qemu_fdt_qmp_dumpdtb(filename, errp);
 }
+
+HumanReadableText *qmp_x_query_fdt(const char *nodepath, Error **errp)
+{
+    return qemu_fdt_qmp_query_fdt(nodepath, errp);
+}
 #else
 void qmp_dumpdtb(const char *filename, Error **errp)
 {
     error_setg(errp, "dumpdtb requires libfdt");
 }
+
+HumanReadableText *qmp_x_query_fdt(const char *nodepath, Error **errp)
+{
+    error_setg(errp, "this command requires libfdt");
+
+    return NULL;
+}
 #endif
diff --git a/qapi/machine.json b/qapi/machine.json
index aeb013f3dd..96cff541ca 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1681,3 +1681,22 @@
 ##
 { 'command': 'dumpdtb',
   'data': { 'filename': 'str' } }
+
+##
+# @x-query-fdt:
+#
+# Query for FDT element (node or property). Requires 'libfdt'.
+#
+# @nodepath: the path of the FDT node to be retrieved
+#
+# Features:
+# @unstable: This command is meant for debugging.
+#
+# Returns: FDT node
+#
+# Since: 7.2
+##
+{ 'command': 'x-query-fdt',
+  'data': { 'nodepath': 'str' },
+  'returns': 'HumanReadableText',
+  'features': [ 'unstable' ]  }
diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c
index cd487ddd4d..6b15f6ace2 100644
--- a/softmmu/device_tree.c
+++ b/softmmu/device_tree.c
@@ -18,6 +18,7 @@
 #endif
 
 #include "qapi/error.h"
+#include "qapi/type-helpers.h"
 #include "qemu/error-report.h"
 #include "qemu/option.h"
 #include "qemu/bswap.h"
@@ -661,3 +662,49 @@ void qemu_fdt_qmp_dumpdtb(const char *filename, Error **errp)
 
     error_setg(errp, "Error when saving machine FDT to file %s", filename);
 }
+
+static void fdt_format_node(GString *buf, int node, int depth)
+{
+    const struct fdt_property *prop = NULL;
+    const char *propname = NULL;
+    void *fdt = current_machine->fdt;
+    int padding = depth * 4;
+    int property = 0;
+    int prop_size;
+
+    g_string_append_printf(buf, "%*s%s {\n", padding, "",
+                           fdt_get_name(fdt, node, NULL));
+
+    padding += 4;
+
+    fdt_for_each_property_offset(property, fdt, node) {
+        prop = fdt_get_property_by_offset(fdt, property, &prop_size);
+        propname = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+
+        g_string_append_printf(buf, "%*s%s;\n", padding, "", propname);
+    }
+
+    padding -= 4;
+    g_string_append_printf(buf, "%*s};\n", padding, "");
+}
+
+HumanReadableText *qemu_fdt_qmp_query_fdt(const char *nodepath, Error **errp)
+{
+    g_autoptr(GString) buf = g_string_new("");
+    int node;
+
+    if (!current_machine->fdt) {
+        error_setg(errp, "Unable to find the machine FDT");
+        return NULL;
+    }
+
+    node = fdt_path_offset(current_machine->fdt, nodepath);
+    if (node < 0) {
+        error_setg(errp, "node '%s' not found in FDT", nodepath);
+        return NULL;
+    }
+
+    fdt_format_node(buf, node, 0);
+
+    return human_readable_text_from_str(buf);
+}
-- 
2.37.2



  parent reply	other threads:[~2022-08-26 14:34 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-26 14:11 [PATCH for-7.2 v4 00/21] QMP/HMP: add 'dumpdtb' and 'info fdt' commands Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 01/21] hw/arm: do not free machine->fdt in arm_load_dtb() Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 02/21] hw/microblaze: set machine->fdt in microblaze_load_dtb() Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 03/21] hw/nios2: set machine->fdt in nios2_load_dtb() Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 04/21] hw/ppc: set machine->fdt in ppce500_load_device_tree() Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 05/21] hw/ppc: set machine->fdt in bamboo_load_device_tree() Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 06/21] hw/ppc: set machine->fdt in sam460ex_load_device_tree() Daniel Henrique Barboza
2022-08-26 18:56   ` BALATON Zoltan
2022-08-26 20:34     ` Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 07/21] hw/ppc: set machine->fdt in xilinx_load_device_tree() Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 08/21] hw/ppc: set machine->fdt in pegasos2_machine_reset() Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 09/21] hw/ppc: set machine->fdt in pnv_reset() Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 10/21] hw/ppc: set machine->fdt in spapr machine Daniel Henrique Barboza
2022-08-29  3:29   ` David Gibson
2022-08-26 14:11 ` [PATCH for-7.2 v4 11/21] hw/riscv: set machine->fdt in sifive_u_machine_init() Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 12/21] hw/riscv: set machine->fdt in spike_board_init() Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 13/21] hw/xtensa: set machine->fdt in xtfpga_init() Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 14/21] qmp/hmp, device_tree.c: introduce dumpdtb Daniel Henrique Barboza
2022-08-30 10:40   ` Markus Armbruster
2022-08-26 14:11 ` Daniel Henrique Barboza [this message]
2022-08-29  3:34   ` [PATCH for-7.2 v4 15/21] qmp/hmp, device_tree.c: introduce 'info fdt' command David Gibson
2022-08-29 22:00     ` Daniel Henrique Barboza
2022-08-30  1:50       ` David Gibson
2022-08-30  9:59         ` Daniel Henrique Barboza
2022-08-30 10:43         ` Markus Armbruster
2022-09-01  2:10           ` David Gibson
2022-08-30 10:41   ` Markus Armbruster
2022-08-26 14:11 ` [PATCH for-7.2 v4 16/21] device_tree.c: support string array prop in fdt_format_node() Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 17/21] device_tree.c: support remaining FDT prop types Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 18/21] device_node.c: enable 'info fdt' to print subnodes Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 19/21] device_tree.c: add fdt_format_property() helper Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 20/21] hmp, device_tree.c: add 'info fdt <property>' support Daniel Henrique Barboza
2022-08-26 14:11 ` [PATCH for-7.2 v4 21/21] qmp/hmp, device_tree.c: add textformat dumpdtb option Daniel Henrique Barboza

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220826141150.7201-16-danielhb413@gmail.com \
    --to=danielhb413@gmail.com \
    --cc=alistair.francis@wdc.com \
    --cc=clg@kaod.org \
    --cc=david@gibson.dropbear.id.au \
    --cc=dgilbert@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).