summaryrefslogtreecommitdiff
path: root/plat/qemu/dt.c
diff options
context:
space:
mode:
authorJens Wiklander <jens.wiklander@linaro.org>2015-12-07 14:37:10 +0100
committerJens Wiklander <jens.wiklander@linaro.org>2016-06-09 11:23:28 +0200
commit419e0d262be23fe3da6e4498ed8b0e2712410d14 (patch)
tree31f1656a9846047b34a080c2a189b4dcf53da616 /plat/qemu/dt.c
parentae43c9493d2c6a2a878f3cee0c240c69fe88f130 (diff)
Add support for QEMU virt ARMv8-A target
This patch adds support for the QEMU virt ARMv8-A target. Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'plat/qemu/dt.c')
-rw-r--r--plat/qemu/dt.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/plat/qemu/dt.c b/plat/qemu/dt.c
new file mode 100644
index 00000000..647ee016
--- /dev/null
+++ b/plat/qemu/dt.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <console.h>
+#include <debug.h>
+#include <libfdt.h>
+#include <psci.h>
+#include "qemu_private.h"
+#include <string.h>
+
+static int append_psci_compatible(void *fdt, int offs, const char *str)
+{
+ return fdt_appendprop(fdt, offs, "compatible", str, strlen(str) + 1);
+}
+
+int dt_add_psci_node(void *fdt)
+{
+ int offs;
+
+ if (fdt_path_offset(fdt, "/psci") >= 0) {
+ WARN("PSCI Device Tree node already exists!\n");
+ return 0;
+ }
+
+ offs = fdt_path_offset(fdt, "/");
+ if (offs < 0)
+ return -1;
+ offs = fdt_add_subnode(fdt, offs, "psci");
+ if (offs < 0)
+ return -1;
+ if (append_psci_compatible(fdt, offs, "arm,psci-1.0"))
+ return -1;
+ if (append_psci_compatible(fdt, offs, "arm,psci-0.2"))
+ return -1;
+ if (append_psci_compatible(fdt, offs, "arm,psci"))
+ return -1;
+ if (fdt_setprop_string(fdt, offs, "method", "smc"))
+ return -1;
+ if (fdt_setprop_u32(fdt, offs, "cpu_suspend", PSCI_CPU_SUSPEND_AARCH64))
+ return -1;
+ if (fdt_setprop_u32(fdt, offs, "cpu_off", PSCI_CPU_OFF))
+ return -1;
+ if (fdt_setprop_u32(fdt, offs, "cpu_on", PSCI_CPU_ON_AARCH64))
+ return -1;
+ if (fdt_setprop_u32(fdt, offs, "sys_poweroff", PSCI_SYSTEM_OFF))
+ return -1;
+ if (fdt_setprop_u32(fdt, offs, "sys_reset", PSCI_SYSTEM_RESET))
+ return -1;
+ return 0;
+}
+
+static int check_node_compat_prefix(void *fdt, int offs, const char *prefix)
+{
+ const size_t prefix_len = strlen(prefix);
+ size_t l;
+ int plen;
+ const char *prop;
+
+ prop = fdt_getprop(fdt, offs, "compatible", &plen);
+ if (!prop)
+ return -1;
+
+ while (plen > 0) {
+ if (memcmp(prop, prefix, prefix_len) == 0)
+ return 0; /* match */
+
+ l = strlen(prop) + 1;
+ prop += l;
+ plen -= l;
+ }
+
+ return -1;
+}
+
+int dt_add_psci_cpu_enable_methods(void *fdt)
+{
+ int offs = 0;
+
+ while (1) {
+ offs = fdt_next_node(fdt, offs, NULL);
+ if (offs < 0)
+ break;
+ if (fdt_getprop(fdt, offs, "enable-method", NULL))
+ continue; /* already set */
+ if (check_node_compat_prefix(fdt, offs, "arm,cortex-a"))
+ continue; /* no compatible */
+ if (fdt_setprop_string(fdt, offs, "enable-method", "psci"))
+ return -1;
+ /* Need to restart scanning as offsets may have changed */
+ offs = 0;
+ }
+ return 0;
+}