diff options
author | Jens Wiklander <jens.wiklander@linaro.org> | 2015-12-07 14:37:10 +0100 |
---|---|---|
committer | Jens Wiklander <jens.wiklander@linaro.org> | 2016-06-09 11:23:28 +0200 |
commit | 419e0d262be23fe3da6e4498ed8b0e2712410d14 (patch) | |
tree | 31f1656a9846047b34a080c2a189b4dcf53da616 /plat/qemu/dt.c | |
parent | ae43c9493d2c6a2a878f3cee0c240c69fe88f130 (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.c | 119 |
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; +} |