Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/*
  2 * arch/arm64/kernel/topology.c
  3 *
  4 * Copyright (C) 2011,2013,2014 Linaro Limited.
  5 *
  6 * Based on the arm32 version written by Vincent Guittot in turn based on
  7 * arch/sh/kernel/topology.c
  8 *
  9 * This file is subject to the terms and conditions of the GNU General Public
 10 * License.  See the file "COPYING" in the main directory of this archive
 11 * for more details.
 12 */
 13
 14#include <linux/acpi.h>
 15#include <linux/arch_topology.h>
 16#include <linux/cacheinfo.h>
 17#include <linux/init.h>
 18#include <linux/percpu.h>
 19
 20#include <asm/cpu.h>
 21#include <asm/cputype.h>
 22#include <asm/topology.h>
 23
 24void store_cpu_topology(unsigned int cpuid)
 25{
 26	struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
 27	u64 mpidr;
 28
 29	if (cpuid_topo->package_id != -1)
 30		goto topology_populated;
 31
 32	mpidr = read_cpuid_mpidr();
 33
 34	/* Uniprocessor systems can rely on default topology values */
 35	if (mpidr & MPIDR_UP_BITMASK)
 36		return;
 37
 38	/* Create cpu topology mapping based on MPIDR. */
 39	if (mpidr & MPIDR_MT_BITMASK) {
 40		/* Multiprocessor system : Multi-threads per core */
 41		cpuid_topo->thread_id  = MPIDR_AFFINITY_LEVEL(mpidr, 0);
 42		cpuid_topo->core_id    = MPIDR_AFFINITY_LEVEL(mpidr, 1);
 43		cpuid_topo->package_id = MPIDR_AFFINITY_LEVEL(mpidr, 2) |
 44					 MPIDR_AFFINITY_LEVEL(mpidr, 3) << 8;
 45	} else {
 46		/* Multiprocessor system : Single-thread per core */
 47		cpuid_topo->thread_id  = -1;
 48		cpuid_topo->core_id    = MPIDR_AFFINITY_LEVEL(mpidr, 0);
 49		cpuid_topo->package_id = MPIDR_AFFINITY_LEVEL(mpidr, 1) |
 50					 MPIDR_AFFINITY_LEVEL(mpidr, 2) << 8 |
 51					 MPIDR_AFFINITY_LEVEL(mpidr, 3) << 16;
 52	}
 53
 54	pr_debug("CPU%u: cluster %d core %d thread %d mpidr %#016llx\n",
 55		 cpuid, cpuid_topo->package_id, cpuid_topo->core_id,
 56		 cpuid_topo->thread_id, mpidr);
 57
 58topology_populated:
 59	update_siblings_masks(cpuid);
 60}
 61
 62#ifdef CONFIG_ACPI
 63static bool __init acpi_cpu_is_threaded(int cpu)
 64{
 65	int is_threaded = acpi_pptt_cpu_is_thread(cpu);
 66
 67	/*
 68	 * if the PPTT doesn't have thread information, assume a homogeneous
 69	 * machine and return the current CPU's thread state.
 70	 */
 71	if (is_threaded < 0)
 72		is_threaded = read_cpuid_mpidr() & MPIDR_MT_BITMASK;
 73
 74	return !!is_threaded;
 75}
 76
 77/*
 78 * Propagate the topology information of the processor_topology_node tree to the
 79 * cpu_topology array.
 80 */
 81int __init parse_acpi_topology(void)
 82{
 83	int cpu, topology_id;
 84
 85	if (acpi_disabled)
 86		return 0;
 87
 88	for_each_possible_cpu(cpu) {
 89		int i, cache_id;
 90
 91		topology_id = find_acpi_cpu_topology(cpu, 0);
 92		if (topology_id < 0)
 93			return topology_id;
 94
 95		if (acpi_cpu_is_threaded(cpu)) {
 96			cpu_topology[cpu].thread_id = topology_id;
 97			topology_id = find_acpi_cpu_topology(cpu, 1);
 98			cpu_topology[cpu].core_id   = topology_id;
 99		} else {
100			cpu_topology[cpu].thread_id  = -1;
101			cpu_topology[cpu].core_id    = topology_id;
102		}
103		topology_id = find_acpi_cpu_topology_package(cpu);
104		cpu_topology[cpu].package_id = topology_id;
105
106		i = acpi_find_last_cache_level(cpu);
107
108		if (i > 0) {
109			/*
110			 * this is the only part of cpu_topology that has
111			 * a direct relationship with the cache topology
112			 */
113			cache_id = find_acpi_cpu_cache_topology(cpu, i);
114			if (cache_id > 0)
115				cpu_topology[cpu].llc_id = cache_id;
116		}
117	}
118
119	return 0;
120}
121#endif
122
123