]> rtime.felk.cvut.cz Git - lisovros/qemu_apohw.git/blobdiff - device_tree.c
apohw: port A0B36APO labs matrix keyboard hardware emulation to QEMU 2.1.
[lisovros/qemu_apohw.git] / device_tree.c
index 69be9da8e408c93b9fb6fb587f0871a5754949a5..ca83504819823cba7ab9656372a001a7771b4e4b 100644 (file)
@@ -21,6 +21,7 @@
 #include "config.h"
 #include "qemu-common.h"
 #include "sysemu/device_tree.h"
+#include "sysemu/sysemu.h"
 #include "hw/loader.h"
 #include "qemu/option.h"
 #include "qemu/config-file.h"
@@ -40,6 +41,10 @@ void *create_device_tree(int *sizep)
     if (ret < 0) {
         goto fail;
     }
+    ret = fdt_finish_reservemap(fdt);
+    if (ret < 0) {
+        goto fail;
+    }
     ret = fdt_begin_node(fdt, "");
     if (ret < 0) {
         goto fail;
@@ -126,12 +131,12 @@ static int findnode_nofail(void *fdt, const char *node_path)
     return offset;
 }
 
-int qemu_devtree_setprop(void *fdt, const char *node_path,
-                         const char *property, const void *val_array, int size)
+int qemu_fdt_setprop(void *fdt, const char *node_path,
+                     const char *property, const void *val, int size)
 {
     int r;
 
-    r = fdt_setprop(fdt, findnode_nofail(fdt, node_path), property, val_array, size);
+    r = fdt_setprop(fdt, findnode_nofail(fdt, node_path), property, val, size);
     if (r < 0) {
         fprintf(stderr, "%s: Couldn't set %s/%s: %s\n", __func__, node_path,
                 property, fdt_strerror(r));
@@ -141,8 +146,8 @@ int qemu_devtree_setprop(void *fdt, const char *node_path,
     return r;
 }
 
-int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
-                              const char *property, uint32_t val)
+int qemu_fdt_setprop_cell(void *fdt, const char *node_path,
+                          const char *property, uint32_t val)
 {
     int r;
 
@@ -156,15 +161,15 @@ int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
     return r;
 }
 
-int qemu_devtree_setprop_u64(void *fdt, const char *node_path,
-                             const char *property, uint64_t val)
+int qemu_fdt_setprop_u64(void *fdt, const char *node_path,
+                         const char *property, uint64_t val)
 {
     val = cpu_to_be64(val);
-    return qemu_devtree_setprop(fdt, node_path, property, &val, sizeof(val));
+    return qemu_fdt_setprop(fdt, node_path, property, &val, sizeof(val));
 }
 
-int qemu_devtree_setprop_string(void *fdt, const char *node_path,
-                                const char *property, const char *string)
+int qemu_fdt_setprop_string(void *fdt, const char *node_path,
+                            const char *property, const char *string)
 {
     int r;
 
@@ -178,8 +183,8 @@ int qemu_devtree_setprop_string(void *fdt, const char *node_path,
     return r;
 }
 
-const void *qemu_devtree_getprop(void *fdt, const char *node_path,
-                                 const char *property, int *lenp)
+const void *qemu_fdt_getprop(void *fdt, const char *node_path,
+                             const char *property, int *lenp)
 {
     int len;
     const void *r;
@@ -195,11 +200,11 @@ const void *qemu_devtree_getprop(void *fdt, const char *node_path,
     return r;
 }
 
-uint32_t qemu_devtree_getprop_cell(void *fdt, const char *node_path,
-                                   const char *property)
+uint32_t qemu_fdt_getprop_cell(void *fdt, const char *node_path,
+                               const char *property)
 {
     int len;
-    const uint32_t *p = qemu_devtree_getprop(fdt, node_path, property, &len);
+    const uint32_t *p = qemu_fdt_getprop(fdt, node_path, property, &len);
     if (len != 4) {
         fprintf(stderr, "%s: %s/%s not 4 bytes long (not a cell?)\n",
                 __func__, node_path, property);
@@ -208,7 +213,7 @@ uint32_t qemu_devtree_getprop_cell(void *fdt, const char *node_path,
     return be32_to_cpu(*p);
 }
 
-uint32_t qemu_devtree_get_phandle(void *fdt, const char *path)
+uint32_t qemu_fdt_get_phandle(void *fdt, const char *path)
 {
     uint32_t r;
 
@@ -222,15 +227,15 @@ uint32_t qemu_devtree_get_phandle(void *fdt, const char *path)
     return r;
 }
 
-int qemu_devtree_setprop_phandle(void *fdt, const char *node_path,
-                                 const char *property,
-                                 const char *target_node_path)
+int qemu_fdt_setprop_phandle(void *fdt, const char *node_path,
+                             const char *property,
+                             const char *target_node_path)
 {
-    uint32_t phandle = qemu_devtree_get_phandle(fdt, target_node_path);
-    return qemu_devtree_setprop_cell(fdt, node_path, property, phandle);
+    uint32_t phandle = qemu_fdt_get_phandle(fdt, target_node_path);
+    return qemu_fdt_setprop_cell(fdt, node_path, property, phandle);
 }
 
-uint32_t qemu_devtree_alloc_phandle(void *fdt)
+uint32_t qemu_fdt_alloc_phandle(void *fdt)
 {
     static int phandle = 0x0;
 
@@ -239,15 +244,8 @@ uint32_t qemu_devtree_alloc_phandle(void *fdt)
      * which phandle id to start allocting phandles.
      */
     if (!phandle) {
-        QemuOpts *machine_opts;
-        machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
-        if (machine_opts) {
-            const char *phandle_start;
-            phandle_start = qemu_opt_get(machine_opts, "phandle_start");
-            if (phandle_start) {
-                phandle = strtoul(phandle_start, NULL, 0);
-            }
-        }
+        phandle = qemu_opt_get_number(qemu_get_machine_opts(),
+                                      "phandle_start", 0);
     }
 
     if (!phandle) {
@@ -261,7 +259,7 @@ uint32_t qemu_devtree_alloc_phandle(void *fdt)
     return phandle++;
 }
 
-int qemu_devtree_nop_node(void *fdt, const char *node_path)
+int qemu_fdt_nop_node(void *fdt, const char *node_path)
 {
     int r;
 
@@ -275,7 +273,7 @@ int qemu_devtree_nop_node(void *fdt, const char *node_path)
     return r;
 }
 
-int qemu_devtree_add_subnode(void *fdt, const char *name)
+int qemu_fdt_add_subnode(void *fdt, const char *name)
 {
     char *dupname = g_strdup(name);
     char *basename = strrchr(dupname, '/');
@@ -305,17 +303,45 @@ int qemu_devtree_add_subnode(void *fdt, const char *name)
     return retval;
 }
 
-void qemu_devtree_dumpdtb(void *fdt, int size)
+void qemu_fdt_dumpdtb(void *fdt, int size)
+{
+    const char *dumpdtb = qemu_opt_get(qemu_get_machine_opts(), "dumpdtb");
+
+    if (dumpdtb) {
+        /* Dump the dtb to a file and quit */
+        exit(g_file_set_contents(dumpdtb, fdt, size, NULL) ? 0 : 1);
+    }
+}
+
+int qemu_fdt_setprop_sized_cells_from_array(void *fdt,
+                                            const char *node_path,
+                                            const char *property,
+                                            int numvalues,
+                                            uint64_t *values)
 {
-    QemuOpts *machine_opts;
-
-    machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
-    if (machine_opts) {
-        const char *dumpdtb = qemu_opt_get(machine_opts, "dumpdtb");
-        if (dumpdtb) {
-            /* Dump the dtb to a file and quit */
-            exit(g_file_set_contents(dumpdtb, fdt, size, NULL) ? 0 : 1);
+    uint32_t *propcells;
+    uint64_t value;
+    int cellnum, vnum, ncells;
+    uint32_t hival;
+
+    propcells = g_new0(uint32_t, numvalues * 2);
+
+    cellnum = 0;
+    for (vnum = 0; vnum < numvalues; vnum++) {
+        ncells = values[vnum * 2];
+        if (ncells != 1 && ncells != 2) {
+            return -1;
+        }
+        value = values[vnum * 2 + 1];
+        hival = cpu_to_be32(value >> 32);
+        if (ncells > 1) {
+            propcells[cellnum++] = hival;
+        } else if (hival != 0) {
+            return -1;
         }
+        propcells[cellnum++] = cpu_to_be32(value);
     }
 
+    return qemu_fdt_setprop(fdt, node_path, property, propcells,
+                            cellnum * sizeof(uint32_t));
 }