blob: ef3ea01274eb3b30902e8daf4b53cbcef894a779 [file]
/*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: GPL-2.0-only
*/
#include <elfloader_common.h>
#include <devices_gen.h>
#include <drivers/common.h>
#include <drivers/smp.h>
#include <armv/machine.h>
#include <psci.h>
#include <armv/smp.h>
#include <printf.h>
#include <types.h>
static int smp_psci_cpu_on(UNUSED struct elfloader_device *dev,
UNUSED struct elfloader_cpu *cpu, UNUSED void *entry, UNUSED void *stack)
{
#if CONFIG_MAX_NUM_NODES > 1
if (cpu->extra_data == PSCI_METHOD_HVC) {
printf("HVC is not supported for PSCI!\n");
return -1;
}
secondary_data.entry = entry;
secondary_data.stack = stack;
dmb();
int ret = psci_cpu_on(cpu->cpu_id, (unsigned long)&secondary_startup, 0);
if (ret != PSCI_SUCCESS) {
printf("Failed to bring up core 0x%x with error %d\n", cpu->cpu_id, ret);
return -1;
}
return 0;
#else
return -1;
#endif
}
static int smp_psci_init(struct elfloader_device *dev,
UNUSED void *match_data)
{
smp_register_handler(dev);
return 0;
}
static const struct dtb_match_table smp_psci_matches[] = {
{ .compatible = "arm,psci-0.2" },
{ .compatible = "arm,psci-1.0" },
{ .compatible = NULL /* sentinel */ },
};
static const struct elfloader_smp_ops smp_psci_ops = {
.enable_method = "psci",
.cpu_on = &smp_psci_cpu_on,
};
static const struct elfloader_driver smp_psci = {
.match_table = smp_psci_matches,
.type = DRIVER_SMP,
.init = &smp_psci_init,
.ops = &smp_psci_ops,
};
ELFLOADER_DRIVER(smp_psci);