EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(cpu_possible_map);
-static struct smp_ops_t *smp_ops;
+struct smp_ops_t *smp_ops;
static volatile unsigned int cpu_callin_map[NR_CPUS];
#define smp_message_pass(t,m,d,w) smp_ops->message_pass((t),(m),(d),(w))
+/* Low level assembly function used to backup CPU 0 state */
+extern void __save_cpu_setup(void);
#ifdef CONFIG_PPC_ISERIES
static unsigned long iSeries_smp_message[NR_CPUS];
{
}
+static struct smp_ops_t iSeries_smp_ops = {
+ .message_pass = smp_iSeries_message_pass,
+ .probe = smp_iSeries_probe,
+ .kick_cpu = smp_iSeries_kick_cpu,
+ .setup_cpu = smp_iSeries_setup_cpu,
+};
+
/* This is called very early. */
void __init smp_init_iSeries(void)
{
- smp_ops = &ppc_md.smp_ops;
- smp_ops->message_pass = smp_iSeries_message_pass;
- smp_ops->probe = smp_iSeries_probe;
- smp_ops->kick_cpu = smp_iSeries_kick_cpu;
- smp_ops->setup_cpu = smp_iSeries_setup_cpu;
+ smp_ops = &iSeries_smp_ops;
systemcfg->processorCount = smp_iSeries_numProcs();
}
#endif
#ifdef CONFIG_PPC_PSERIES
-static void
-smp_openpic_message_pass(int target, int msg, unsigned long data, int wait)
+void smp_openpic_message_pass(int target, int msg, unsigned long data, int wait)
{
/* make sure we're sending something that translates to an IPI */
if ( msg > 0x3 ){
do_openpic_setup_cpu();
}
-static void
-smp_kick_cpu(int nr)
+static void smp_pSeries_kick_cpu(int nr)
{
/* Verify we have a Paca for processor nr */
if ( ( nr <= 0 ) ||
register_vpa(flags, cpu, __pa((unsigned long)&(paca[cpu].xLpPaca)));
}
-static void
-smp_xics_message_pass(int target, int msg, unsigned long data, int wait)
+static void smp_xics_message_pass(int target, int msg, unsigned long data, int wait)
{
int i;
spin_unlock(&timebase_lock);
}
+static struct smp_ops_t pSeries_openpic_smp_ops = {
+ .message_pass = smp_openpic_message_pass,
+ .probe = smp_openpic_probe,
+ .kick_cpu = smp_pSeries_kick_cpu,
+ .setup_cpu = smp_openpic_setup_cpu,
+};
+
+static struct smp_ops_t pSeries_xics_smp_ops = {
+ .message_pass = smp_xics_message_pass,
+ .probe = smp_xics_probe,
+ .kick_cpu = smp_pSeries_kick_cpu,
+ .setup_cpu = smp_xics_setup_cpu,
+};
+
/* This is called very early */
void __init smp_init_pSeries(void)
{
- smp_ops = &ppc_md.smp_ops;
- if (naca->interrupt_controller == IC_OPEN_PIC) {
- smp_ops->message_pass = smp_openpic_message_pass;
- smp_ops->probe = smp_openpic_probe;
- smp_ops->setup_cpu = smp_openpic_setup_cpu;
- } else {
- smp_ops->message_pass = smp_xics_message_pass;
- smp_ops->probe = smp_xics_probe;
- smp_ops->setup_cpu = smp_xics_setup_cpu;
- }
+ if (naca->interrupt_controller == IC_OPEN_PIC)
+ smp_ops = &pSeries_openpic_smp_ops;
+ else
+ smp_ops = &pSeries_xics_smp_ops;
+ /* Non-lpar has additional take/give timebase */
if (systemcfg->platform == PLATFORM_PSERIES) {
smp_ops->give_timebase = pSeries_give_timebase;
smp_ops->take_timebase = pSeries_take_timebase;
}
-
- smp_ops->kick_cpu = smp_kick_cpu;
}
#endif
#endif
max_cpus = smp_ops->probe();
+
+ /* Backup CPU 0 state if necessary */
+ __save_cpu_setup();
+
smp_space_timers(max_cpus);
}