• Andre Przywara's avatar
    qemu: Move and generalise FDT PSCI fixup · f240728b
    Andre Przywara authored
    
    The QEMU platform port scans its device tree to advertise PSCI as the
    CPU enable method. It does this by scanning *every* node in the DT and
    check whether its compatible string starts with "arm,cortex-a". Then it
    sets the enable-method to PSCI, if it doesn't already have one.
    
    Other platforms might want to use this functionality as well, so let's
    move it out of the QEMU platform directory and make it more robust by
    fixing some shortcomings:
    - A compatible string starting with a certain prefix is not a good way
    to find the CPU nodes. For instance a "arm,cortex-a72-pmu" node will
    match as well and is in turn favoured with an enable-method.
    - If the DT already has an enable-method, we won't change this to PSCI.
    
    Those two issues will for instance fail on the Raspberry Pi 4 DT.
    To fix those problems, we adjust the scanning method:
    The DT spec says that all CPU nodes are subnodes of the mandatory
    /cpus node, which is a subnode of the root node. Also each CPU node has
    to have a device_type = "cpu" property. So we find the /cpus node, then
    scan for a subnode with the proper device_type, forcing the
    enable-method to "psci".
    We have to restart this search after a property has been patched, as the
    node offsets might have changed meanwhile.
    
    This allows this routine to be reused for the Raspberry Pi 4 later.
    
    Change-Id: I00cae16cc923d9f8bb96a9b2a2933b9a79b06139
    Signed-off-by: default avatarAndre Przywara <andre.przywara@arm.com>
    f240728b
qemu_private.h 1.12 KB
/*
 * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef QEMU_PRIVATE_H
#define QEMU_PRIVATE_H

#include <stdint.h>

void qemu_configure_mmu_svc_mon(unsigned long total_base,
			unsigned long total_size,
			unsigned long code_start, unsigned long code_limit,
			unsigned long ro_start, unsigned long ro_limit,
			unsigned long coh_start, unsigned long coh_limit);

void qemu_configure_mmu_el1(unsigned long total_base, unsigned long total_size,
			unsigned long code_start, unsigned long code_limit,
			unsigned long ro_start, unsigned long ro_limit,
			unsigned long coh_start, unsigned long coh_limit);

void qemu_configure_mmu_el3(unsigned long total_base, unsigned long total_size,
			unsigned long code_start, unsigned long code_limit,
			unsigned long ro_start, unsigned long ro_limit,
			unsigned long coh_start, unsigned long coh_limit);

void plat_qemu_io_setup(void);
unsigned int plat_qemu_calc_core_pos(u_register_t mpidr);

void qemu_console_init(void);

void plat_qemu_gic_init(void);
void qemu_pwr_gic_on_finish(void);

#endif /* QEMU_PRIVATE_H */