Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/arch/arm/kernel/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 3 kB image not shown  

Quelle  psci_smp.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 *
 * Copyright (C) 2012 ARM Limited
 *
 * Author: Will Deacon <will.deacon@arm.com>
 */


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

#include <uapi/linux/psci.h>

#include <asm/psci.h>
#include <asm/smp_plat.h>

/*
 * psci_smp assumes that the following is true about PSCI:
 *
 * cpu_suspend   Suspend the execution on a CPU
 * @state        we don't currently describe affinity levels, so just pass 0.
 * @entry_point  the first instruction to be executed on return
 * returns 0  success, < 0 on failure
 *
 * cpu_off       Power down a CPU
 * @state        we don't currently describe affinity levels, so just pass 0.
 * no return on successful call
 *
 * cpu_on        Power up a CPU
 * @cpuid        cpuid of target CPU, as from MPIDR
 * @entry_point  the first instruction to be executed on return
 * returns 0  success, < 0 on failure
 *
 * migrate       Migrate the context to a different CPU
 * @cpuid        cpuid of target CPU, as from MPIDR
 * returns 0  success, < 0 on failure
 *
 */


extern void secondary_startup(void);

static int psci_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
 if (psci_ops.cpu_on)
#ifdef CONFIG_XIP_KERNEL
  return psci_ops.cpu_on(cpu_logical_map(cpu),
   ((phys_addr_t)(&secondary_startup)
   - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
   + CONFIG_XIP_PHYS_ADDR));
#else
  return psci_ops.cpu_on(cpu_logical_map(cpu),
     virt_to_idmap(&secondary_startup));
#endif
 return -ENODEV;
}

#ifdef CONFIG_HOTPLUG_CPU
static int psci_cpu_disable(unsigned int cpu)
{
 /* Fail early if we don't have CPU_OFF support */
 if (!psci_ops.cpu_off)
  return -EOPNOTSUPP;

 /* Trusted OS will deny CPU_OFF */
 if (psci_tos_resident_on(cpu))
  return -EPERM;

 return 0;
}

static void psci_cpu_die(unsigned int cpu)
{
 u32 state = PSCI_POWER_STATE_TYPE_POWER_DOWN <<
      PSCI_0_2_POWER_STATE_TYPE_SHIFT;

 if (psci_ops.cpu_off)
  psci_ops.cpu_off(state);

 /* We should never return */
 panic("psci: cpu %d failed to shutdown\n", cpu);
}

static int psci_cpu_kill(unsigned int cpu)
{
 int err, i;

 if (!psci_ops.affinity_info)
  return 1;
 /*
 * cpu_kill could race with cpu_die and we can
 * potentially end up declaring this cpu undead
 * while it is dying. So, try again a few times.
 */


 for (i = 0; i < 10; i++) {
  err = psci_ops.affinity_info(cpu_logical_map(cpu), 0);
  if (err == PSCI_0_2_AFFINITY_LEVEL_OFF) {
   pr_info("CPU%d killed.\n", cpu);
   return 1;
  }

  msleep(10);
  pr_info("Retrying again to check for CPU kill\n");
 }

 pr_warn("CPU%d may not have shut down cleanly (AFFINITY_INFO reports %d)\n",
   cpu, err);
 /* Make platform_cpu_kill() fail. */
 return 0;
}

#endif

bool __init psci_smp_available(void)
{
 /* is cpu_on available at least? */
 return (psci_ops.cpu_on != NULL);
}

const struct smp_operations psci_smp_ops __initconst = {
 .smp_boot_secondary = psci_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
 .cpu_disable  = psci_cpu_disable,
 .cpu_die  = psci_cpu_die,
 .cpu_kill  = psci_cpu_kill,
#endif
};

Messung V0.5
C=94 H=87 G=90

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© 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.