Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/arch/arm/mach-bcm/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  bcm63xx_smp.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Broadcom BCM63138 DSL SoCs SMP support code
 *
 * Copyright (C) 2015, Broadcom Corporation
 */


#include <linux/delay.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>

#include <asm/cacheflush.h>
#include <asm/smp_scu.h>
#include <asm/smp_plat.h>
#include <asm/vfp.h>

#include "bcm63xx_smp.h"

/* Size of mapped Cortex A9 SCU address space */
#define CORTEX_A9_SCU_SIZE 0x58

/*
 * Enable the Cortex A9 Snoop Control Unit
 *
 * By the time this is called we already know there are multiple
 * cores present.  We assume we're running on a Cortex A9 processor,
 * so any trouble getting the base address register or getting the
 * SCU base is a problem.
 *
 * Return 0 if successful or an error code otherwise.
 */

static int __init scu_a9_enable(void)
{
 unsigned long config_base;
 void __iomem *scu_base;
 unsigned int i, ncores;

 if (!scu_a9_has_base()) {
  pr_err("no configuration base address register!\n");
  return -ENXIO;
 }

 /* Config base address register value is zero for uniprocessor */
 config_base = scu_a9_get_base();
 if (!config_base) {
  pr_err("hardware reports only one core\n");
  return -ENOENT;
 }

 scu_base = ioremap((phys_addr_t)config_base, CORTEX_A9_SCU_SIZE);
 if (!scu_base) {
  pr_err("failed to remap config base (%lu/%u) for SCU\n",
   config_base, CORTEX_A9_SCU_SIZE);
  return -ENOMEM;
 }

 scu_enable(scu_base);

 ncores = scu_base ? scu_get_core_count(scu_base) : 1;

 if (ncores > nr_cpu_ids) {
  pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
    ncores, nr_cpu_ids);
  ncores = nr_cpu_ids;
 }

 /* The BCM63138 SoC has two Cortex-A9 CPUs, CPU0 features a complete
 * and fully functional VFP unit that can be used, but CPU1 does not.
 * Since we will not be able to trap kernel-mode NEON to force
 * migration to CPU0, just do not advertise VFP support at all.
 *
 * This will make vfp_init bail out and do not attempt to use VFP at
 * all, for kernel-mode NEON, we do not want to introduce any
 * conditionals in hot-paths, so we just restrict the system to UP.
 */

#ifdef CONFIG_VFP
 if (ncores > 1) {
  pr_warn("SMP: secondary CPUs lack VFP unit, disabling VFP\n");
  vfp_disable();

#ifdef CONFIG_KERNEL_MODE_NEON
  WARN(1, "SMP: kernel-mode NEON enabled, restricting to UP\n");
  ncores = 1;
#endif
 }
#endif

 for (i = 0; i < ncores; i++)
  set_cpu_possible(i, true);

 iounmap(scu_base); /* That's the last we'll need of this */

 return 0;
}

static const struct of_device_id bcm63138_bootlut_ids[] = {
 { .compatible = "brcm,bcm63138-bootlut", },
 { /* sentinel */ },
};

#define BOOTLUT_RESET_VECT 0x20

static int bcm63138_smp_boot_secondary(unsigned int cpu,
           struct task_struct *idle)
{
 void __iomem *bootlut_base;
 struct device_node *dn;
 int ret = 0;
 u32 val;

 dn = of_find_matching_node(NULL, bcm63138_bootlut_ids);
 if (!dn) {
  pr_err("SMP: unable to find bcm63138 boot LUT node\n");
  return -ENODEV;
 }

 bootlut_base = of_iomap(dn, 0);
 of_node_put(dn);

 if (!bootlut_base) {
  pr_err("SMP: unable to remap boot LUT base register\n");
  return -ENOMEM;
 }

 /* Locate the secondary CPU node */
 dn = of_get_cpu_node(cpu, NULL);
 if (!dn) {
  pr_err("SMP: failed to locate secondary CPU%d node\n", cpu);
  ret = -ENODEV;
  goto out;
 }

 /* Write the secondary init routine to the BootLUT reset vector */
 val = __pa_symbol(secondary_startup);
 writel_relaxed(val, bootlut_base + BOOTLUT_RESET_VECT);

 /* Power up the core, will jump straight to its reset vector when we
 * return
 */

 ret = bcm63xx_pmb_power_on_cpu(dn);
 of_node_put(dn);

out:
 iounmap(bootlut_base);

 return ret;
}

static void __init bcm63138_smp_prepare_cpus(unsigned int max_cpus)
{
 int ret;

 ret = scu_a9_enable();
 if (ret) {
  pr_warn("SMP: Cortex-A9 SCU setup failed\n");
  return;
 }
}

static const struct smp_operations bcm63138_smp_ops __initconst = {
 .smp_prepare_cpus = bcm63138_smp_prepare_cpus,
 .smp_boot_secondary = bcm63138_smp_boot_secondary,
};

CPU_METHOD_OF_DECLARE(bcm63138_smp, "brcm,bcm63138", &bcm63138_smp_ops);

Messung V0.5
C=97 H=90 G=93

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.