qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH for-7.2 v4 21/21] qmp/hmp, device_tree.c: add textformat dumpdtb


From: Daniel Henrique Barboza
Subject: [PATCH for-7.2 v4 21/21] qmp/hmp, device_tree.c: add textformat dumpdtb option
Date: Fri, 26 Aug 2022 11:11:50 -0300

The QMP/HMP 'dumpdtb' command is saving the FDT blob to be decoded using
'dtc' like the '-machine dumpdtb' always did. However, after adding
support for the 'info fdt' command, we're now able to format a full FDT
in text format - which is what 'info fdt /' already does.

Let's extend the 'dumpdtb' QMP/HMP command with the capability of saving
the FDT in plain text format. A new textformat '-t' option was added to
it. With this option, qemu_fdt_qmp_dumpdtb() will call
qemu_fdt_qmp_query_fdt() to retrieve the human string that represents
the output of 'info fdt /' and write it to the file.

This will allow users to dump the FDT in a text file and immediately
open it to see its contents, without the need of an extra step to decode
a dtb blob with 'dtc'. Here's an example:

(qemu) dumpdtb fdt.dtb

$ file fdt.dtb
fdt.dtb: Device Tree Blob version 17, size=15458, boot CPU=0, string block
size=2318, DT structure block size=13084

(qemu) dumpdtb -t fdt.txt

$ file fdt.txt
fdt.txt: ASCII text, with very long lines (4746)

$ grep -A 3 'persistent-memory' fdt.txt
    ibm,persistent-memory {
        device_type = "ibm,persistent-memory";
        #size-cells = <0x0>;
        #address-cells = <0x1>;
    };

Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
---
 hmp-commands.hx              |  7 ++++---
 include/sysemu/device_tree.h |  3 ++-
 monitor/hmp-cmds.c           |  3 ++-
 monitor/qmp-cmds.c           |  8 +++++---
 qapi/machine.json            |  2 +-
 softmmu/device_tree.c        | 25 ++++++++++++++++++++++---
 6 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 2dd737078e..8a9595cc26 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1808,8 +1808,9 @@ SRST
 ERST
     {
         .name       = "dumpdtb",
-        .args_type  = "filename:F",
-        .params     = "filename",
-        .help       = "save the FDT in the 'filename' file to be decoded using 
dtc",
+        .args_type  = "textformat:-t,filename:F",
+        .params     = "[-t] filename",
+        .help       = "save the FDT in the 'filename' file to be decoded using 
dtc."
+                       "Use '-t' to save the file in text (dts) format.",
         .cmd        = hmp_dumpdtb,
     },
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
index 551a02dee2..082ff69751 100644
--- a/include/sysemu/device_tree.h
+++ b/include/sysemu/device_tree.h
@@ -138,7 +138,8 @@ int qemu_fdt_add_path(void *fdt, const char *path);
     } while (0)
 
 void qemu_fdt_dumpdtb(void *fdt, int size);
-void qemu_fdt_qmp_dumpdtb(const char *filename, Error **errp);
+void qemu_fdt_qmp_dumpdtb(const char *filename, bool textformat,
+                          Error **errp);
 HumanReadableText *qemu_fdt_qmp_query_fdt(const char *nodepath,
                                           bool has_propname,
                                           const char *propname,
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 320204e982..ffcb9ffb67 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -2476,9 +2476,10 @@ exit_no_print:
 void hmp_dumpdtb(Monitor *mon, const QDict *qdict)
 {
     const char *filename = qdict_get_str(qdict, "filename");
+    bool textformat = qdict_get_try_bool(qdict, "textformat", false);
     Error *local_err = NULL;
 
-    qmp_dumpdtb(filename, &local_err);
+    qmp_dumpdtb(true, textformat, filename, &local_err);
 
     if (local_err) {
         hmp_handle_error(mon, local_err);
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index ca2a96cdf7..8d625e5e7d 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -599,9 +599,10 @@ bool apply_str_list_filter(const char *string, strList 
*list)
 }
 
 #ifdef CONFIG_FDT
-void qmp_dumpdtb(const char *filename, Error **errp)
+void qmp_dumpdtb(bool has_textformat, bool textformat,
+                 const char *filename, Error **errp)
 {
-    return qemu_fdt_qmp_dumpdtb(filename, errp);
+    return qemu_fdt_qmp_dumpdtb(filename, textformat, errp);
 }
 
 HumanReadableText *qmp_x_query_fdt(const char *nodepath, bool has_propname,
@@ -610,7 +611,8 @@ HumanReadableText *qmp_x_query_fdt(const char *nodepath, 
bool has_propname,
     return qemu_fdt_qmp_query_fdt(nodepath, has_propname, propname, errp);
 }
 #else
-void qmp_dumpdtb(const char *filename, Error **errp)
+void qmp_dumpdtb(bool has_textformat, bool textformat,
+                 const char *filename, Error **errp)
 {
     error_setg(errp, "dumpdtb requires libfdt");
 }
diff --git a/qapi/machine.json b/qapi/machine.json
index c15ce60f46..8573f96da8 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1680,7 +1680,7 @@
 #
 ##
 { 'command': 'dumpdtb',
-  'data': { 'filename': 'str' } }
+  'data': { '*textformat':'bool', 'filename': 'str' } }
 
 ##
 # @x-query-fdt:
diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c
index ad2386295b..34af31552d 100644
--- a/softmmu/device_tree.c
+++ b/softmmu/device_tree.c
@@ -645,8 +645,10 @@ out:
     return ret;
 }
 
-void qemu_fdt_qmp_dumpdtb(const char *filename, Error **errp)
+void qemu_fdt_qmp_dumpdtb(const char *filename, bool textformat, Error **errp)
 {
+    g_autoptr(HumanReadableText) txt = NULL;
+    void *contents = NULL;
     int size;
 
     if (!current_machine->fdt) {
@@ -654,9 +656,26 @@ void qemu_fdt_qmp_dumpdtb(const char *filename, Error 
**errp)
         return;
     }
 
-    size = fdt_totalsize(current_machine->fdt);
+    if (textformat) {
+        /*
+         * 'info fdt /' returns all the FDT in text format, formatted
+         * with a style close to what 'dtc' uses to decode the blob
+         * to a .dts.
+         */
+        txt = qemu_fdt_qmp_query_fdt("/", false, NULL, errp);
+
+        if (!txt) {
+            return;
+        }
+
+        contents = txt->human_readable_text;
+        size = strlen(txt->human_readable_text);
+    } else {
+        contents = current_machine->fdt;
+        size = fdt_totalsize(current_machine->fdt);
+    }
 
-    if (g_file_set_contents(filename, current_machine->fdt, size, NULL)) {
+    if (g_file_set_contents(filename, contents, size, NULL)) {
         return;
     }
 
-- 
2.37.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]