Generate the PSCI node in the device tree. Also add a reserve section for the "secure" code that lives in in normal RAM, so that the kernel knows it'd better not trip on it. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Acked-by: Ian Campbell <ijc@hellion.org.uk>master
parent
e29607ed97
commit
e771a3d538
@ -0,0 +1,100 @@ |
||||
/*
|
||||
* Copyright (C) 2013 - ARM Ltd |
||||
* Author: Marc Zyngier <marc.zyngier@arm.com> |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 as |
||||
* published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <stdio_dev.h> |
||||
#include <linux/ctype.h> |
||||
#include <linux/types.h> |
||||
#include <asm/global_data.h> |
||||
#include <libfdt.h> |
||||
#include <fdt_support.h> |
||||
#include <asm/armv7.h> |
||||
#include <asm/psci.h> |
||||
|
||||
static int fdt_psci(void *fdt) |
||||
{ |
||||
#ifdef CONFIG_ARMV7_PSCI |
||||
int nodeoff; |
||||
int tmp; |
||||
|
||||
nodeoff = fdt_path_offset(fdt, "/cpus"); |
||||
if (nodeoff < 0) { |
||||
printf("couldn't find /cpus\n"); |
||||
return nodeoff; |
||||
} |
||||
|
||||
/* add 'enable-method = "psci"' to each cpu node */ |
||||
for (tmp = fdt_first_subnode(fdt, nodeoff); |
||||
tmp >= 0; |
||||
tmp = fdt_next_subnode(fdt, tmp)) { |
||||
const struct fdt_property *prop; |
||||
int len; |
||||
|
||||
prop = fdt_get_property(fdt, tmp, "device_type", &len); |
||||
if (!prop) |
||||
continue; |
||||
if (len < 4) |
||||
continue; |
||||
if (strcmp(prop->data, "cpu")) |
||||
continue; |
||||
|
||||
fdt_setprop_string(fdt, tmp, "enable-method", "psci"); |
||||
} |
||||
|
||||
nodeoff = fdt_path_offset(fdt, "/psci"); |
||||
if (nodeoff < 0) { |
||||
nodeoff = fdt_path_offset(fdt, "/"); |
||||
if (nodeoff < 0) |
||||
return nodeoff; |
||||
|
||||
nodeoff = fdt_add_subnode(fdt, nodeoff, "psci"); |
||||
if (nodeoff < 0) |
||||
return nodeoff; |
||||
} |
||||
|
||||
tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci"); |
||||
if (tmp) |
||||
return tmp; |
||||
tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc"); |
||||
if (tmp) |
||||
return tmp; |
||||
tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", ARM_PSCI_FN_CPU_SUSPEND); |
||||
if (tmp) |
||||
return tmp; |
||||
tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", ARM_PSCI_FN_CPU_OFF); |
||||
if (tmp) |
||||
return tmp; |
||||
tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", ARM_PSCI_FN_CPU_ON); |
||||
if (tmp) |
||||
return tmp; |
||||
tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", ARM_PSCI_FN_MIGRATE); |
||||
if (tmp) |
||||
return tmp; |
||||
#endif |
||||
return 0; |
||||
} |
||||
|
||||
int armv7_update_dt(void *fdt) |
||||
{ |
||||
#ifndef CONFIG_ARMV7_SECURE_BASE |
||||
/* secure code lives in RAM, keep it alive */ |
||||
fdt_add_mem_rsv(fdt, (unsigned long)__secure_start, |
||||
__secure_end - __secure_start); |
||||
#endif |
||||
|
||||
return fdt_psci(fdt); |
||||
} |
Loading…
Reference in new issue