Skip to content

Commit

Permalink
powerpc: Merge smp.c and smp.h
Browse files Browse the repository at this point in the history
This also moves setup_cpu_maps to setup-common.c (calling it
smp_setup_cpu_maps) and uses it on both 32-bit and 64-bit.

Signed-off-by: Paul Mackerras <[email protected]>
  • Loading branch information
paulusmack committed Nov 4, 2005
1 parent c3df69c commit 5ad5707
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 197 deletions.
4 changes: 3 additions & 1 deletion arch/powerpc/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ obj-$(CONFIG_PPC_OF) += prom_init.o
obj-$(CONFIG_MODULES) += ppc_ksyms.o
obj-$(CONFIG_BOOTX_TEXT) += btext.o
obj-$(CONFIG_6xx) += idle_6xx.o
obj-$(CONFIG_SMP) += smp.o

ifeq ($(CONFIG_PPC_ISERIES),y)
$(obj)/head_64.o: $(obj)/lparmap.s
Expand All @@ -49,8 +50,9 @@ endif

else
# stuff used from here for ARCH=ppc or ARCH=ppc64
smpobj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_PPC64) += traps.o process.o init_task.o time.o \
setup-common.o
setup-common.o $(smpobj-y)


endif
Expand Down
119 changes: 115 additions & 4 deletions arch/powerpc/kernel/setup-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
}

#ifdef CONFIG_SMP
#ifdef CONFIG_PPC64 /* XXX for now */
pvr = per_cpu(pvr, cpu_id);
#else
pvr = cpu_data[cpu_id].pvr;
#endif
#else
pvr = mfspr(SPRN_PVR);
#endif
Expand Down Expand Up @@ -408,3 +404,118 @@ static int __init set_preferred_console(void)
}
console_initcall(set_preferred_console);
#endif /* CONFIG_PPC_MULTIPLATFORM */

#ifdef CONFIG_SMP

/**
* setup_cpu_maps - initialize the following cpu maps:
* cpu_possible_map
* cpu_present_map
* cpu_sibling_map
*
* Having the possible map set up early allows us to restrict allocations
* of things like irqstacks to num_possible_cpus() rather than NR_CPUS.
*
* We do not initialize the online map here; cpus set their own bits in
* cpu_online_map as they come up.
*
* This function is valid only for Open Firmware systems. finish_device_tree
* must be called before using this.
*
* While we're here, we may as well set the "physical" cpu ids in the paca.
*/
void __init smp_setup_cpu_maps(void)
{
struct device_node *dn = NULL;
int cpu = 0;
int swap_cpuid = 0;

while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
int *intserv;
int j, len = sizeof(u32), nthreads = 1;

intserv = (int *)get_property(dn, "ibm,ppc-interrupt-server#s",
&len);
if (intserv)
nthreads = len / sizeof(int);
else {
intserv = (int *) get_property(dn, "reg", NULL);
if (!intserv)
intserv = &cpu; /* assume logical == phys */
}

for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
cpu_set(cpu, cpu_present_map);
set_hard_smp_processor_id(cpu, intserv[j]);

if (intserv[j] == boot_cpuid_phys)
swap_cpuid = cpu;
cpu_set(cpu, cpu_possible_map);
cpu++;
}
}

/* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that
* boot cpu is logical 0.
*/
if (boot_cpuid_phys != get_hard_smp_processor_id(0)) {
u32 tmp;
tmp = get_hard_smp_processor_id(0);
set_hard_smp_processor_id(0, boot_cpuid_phys);
set_hard_smp_processor_id(swap_cpuid, tmp);
}

#ifdef CONFIG_PPC64
/*
* On pSeries LPAR, we need to know how many cpus
* could possibly be added to this partition.
*/
if (systemcfg->platform == PLATFORM_PSERIES_LPAR &&
(dn = of_find_node_by_path("/rtas"))) {
int num_addr_cell, num_size_cell, maxcpus;
unsigned int *ireg;

num_addr_cell = prom_n_addr_cells(dn);
num_size_cell = prom_n_size_cells(dn);

ireg = (unsigned int *)
get_property(dn, "ibm,lrdr-capacity", NULL);

if (!ireg)
goto out;

maxcpus = ireg[num_addr_cell + num_size_cell];

/* Double maxcpus for processors which have SMT capability */
if (cpu_has_feature(CPU_FTR_SMT))
maxcpus *= 2;

if (maxcpus > NR_CPUS) {
printk(KERN_WARNING
"Partition configured for %d cpus, "
"operating system maximum is %d.\n",
maxcpus, NR_CPUS);
maxcpus = NR_CPUS;
} else
printk(KERN_INFO "Partition configured for %d cpus.\n",
maxcpus);

for (cpu = 0; cpu < maxcpus; cpu++)
cpu_set(cpu, cpu_possible_map);
out:
of_node_put(dn);
}

/*
* Do the sibling map; assume only two threads per processor.
*/
for_each_cpu(cpu) {
cpu_set(cpu, cpu_sibling_map[cpu]);
if (cpu_has_feature(CPU_FTR_SMT))
cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
}

systemcfg->processorCount = num_present_cpus();
#endif /* CONFIG_PPC64 */
}
#endif /* CONFIG_SMP */
2 changes: 2 additions & 0 deletions arch/powerpc/kernel/setup_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ void __init setup_arch(char **cmdline_p)
unflatten_device_tree();
finish_device_tree();

smp_setup_cpu_maps();

#ifdef CONFIG_BOOTX_TEXT
init_boot_display();
#endif
Expand Down
120 changes: 6 additions & 114 deletions arch/powerpc/kernel/setup_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,114 +181,8 @@ static int __init early_smt_enabled(char *p)
}
early_param("smt-enabled", early_smt_enabled);

/**
* setup_cpu_maps - initialize the following cpu maps:
* cpu_possible_map
* cpu_present_map
* cpu_sibling_map
*
* Having the possible map set up early allows us to restrict allocations
* of things like irqstacks to num_possible_cpus() rather than NR_CPUS.
*
* We do not initialize the online map here; cpus set their own bits in
* cpu_online_map as they come up.
*
* This function is valid only for Open Firmware systems. finish_device_tree
* must be called before using this.
*
* While we're here, we may as well set the "physical" cpu ids in the paca.
*/
static void __init setup_cpu_maps(void)
{
struct device_node *dn = NULL;
int cpu = 0;
int swap_cpuid = 0;

check_smt_enabled();

while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
u32 *intserv;
int j, len = sizeof(u32), nthreads;

intserv = (u32 *)get_property(dn, "ibm,ppc-interrupt-server#s",
&len);
if (!intserv)
intserv = (u32 *)get_property(dn, "reg", NULL);

nthreads = len / sizeof(u32);

for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
cpu_set(cpu, cpu_present_map);
set_hard_smp_processor_id(cpu, intserv[j]);

if (intserv[j] == boot_cpuid_phys)
swap_cpuid = cpu;
cpu_set(cpu, cpu_possible_map);
cpu++;
}
}

/* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that
* boot cpu is logical 0.
*/
if (boot_cpuid_phys != get_hard_smp_processor_id(0)) {
u32 tmp;
tmp = get_hard_smp_processor_id(0);
set_hard_smp_processor_id(0, boot_cpuid_phys);
set_hard_smp_processor_id(swap_cpuid, tmp);
}

/*
* On pSeries LPAR, we need to know how many cpus
* could possibly be added to this partition.
*/
if (systemcfg->platform == PLATFORM_PSERIES_LPAR &&
(dn = of_find_node_by_path("/rtas"))) {
int num_addr_cell, num_size_cell, maxcpus;
unsigned int *ireg;

num_addr_cell = prom_n_addr_cells(dn);
num_size_cell = prom_n_size_cells(dn);

ireg = (unsigned int *)
get_property(dn, "ibm,lrdr-capacity", NULL);

if (!ireg)
goto out;

maxcpus = ireg[num_addr_cell + num_size_cell];

/* Double maxcpus for processors which have SMT capability */
if (cpu_has_feature(CPU_FTR_SMT))
maxcpus *= 2;

if (maxcpus > NR_CPUS) {
printk(KERN_WARNING
"Partition configured for %d cpus, "
"operating system maximum is %d.\n",
maxcpus, NR_CPUS);
maxcpus = NR_CPUS;
} else
printk(KERN_INFO "Partition configured for %d cpus.\n",
maxcpus);

for (cpu = 0; cpu < maxcpus; cpu++)
cpu_set(cpu, cpu_possible_map);
out:
of_node_put(dn);
}

/*
* Do the sibling map; assume only two threads per processor.
*/
for_each_cpu(cpu) {
cpu_set(cpu, cpu_sibling_map[cpu]);
if (cpu_has_feature(CPU_FTR_SMT))
cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
}

systemcfg->processorCount = num_present_cpus();
}
#else
#define check_smt_enabled()
#endif /* CONFIG_SMP */

extern struct machdep_calls pSeries_md;
Expand Down Expand Up @@ -417,6 +311,8 @@ void smp_release_cpus(void)

DBG(" <- smp_release_cpus()\n");
}
#else
#define smp_release_cpus()
#endif /* CONFIG_SMP || CONFIG_KEXEC */

/*
Expand Down Expand Up @@ -608,17 +504,13 @@ void __init setup_system(void)

parse_early_param();

#ifdef CONFIG_SMP
/*
* iSeries has already initialized the cpu maps at this point.
*/
setup_cpu_maps();
check_smt_enabled();
smp_setup_cpu_maps();

/* Release secondary cpus out of their spinloops at 0x60 now that
* we can map physical -> logical CPU ids
*/
smp_release_cpus();
#endif

printk("Starting Linux PPC64 %s\n", system_utsname.version);

Expand Down
Loading

0 comments on commit 5ad5707

Please sign in to comment.