summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorKanoj Sarcar <kanoj@engr.sgi.com>2000-04-06 01:48:13 +0000
committerKanoj Sarcar <kanoj@engr.sgi.com>2000-04-06 01:48:13 +0000
commitbaf53a8667f9b9bf9b4ff3ef272caabf5372a4f0 (patch)
treeb580461583907fef56a0139ea5806689a5956b60 /arch
parent3e91b5dd87a280a583adcd976853c6f756a6d45e (diff)
Create idle threads for the slave processors and put them in their
resched loops.
Diffstat (limited to 'arch')
-rw-r--r--arch/mips64/kernel/smp.c2
-rw-r--r--arch/mips64/sgi-ip27/ip27-init.c88
2 files changed, 78 insertions, 12 deletions
diff --git a/arch/mips64/kernel/smp.c b/arch/mips64/kernel/smp.c
index bf74a983e..2ed180820 100644
--- a/arch/mips64/kernel/smp.c
+++ b/arch/mips64/kernel/smp.c
@@ -50,7 +50,7 @@ static void sendintr(int destid, unsigned char status)
/* The 'big kernel lock' */
spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
int smp_threads_ready = 0; /* Not used */
-static atomic_t smp_commenced = ATOMIC_INIT(0);
+atomic_t smp_commenced = ATOMIC_INIT(0);
struct cpuinfo_mips cpu_data[NR_CPUS];
int smp_num_cpus; /* Number that came online. */
int __cpu_number_map[NR_CPUS];
diff --git a/arch/mips64/sgi-ip27/ip27-init.c b/arch/mips64/sgi-ip27/ip27-init.c
index fa008dcb6..882e58f33 100644
--- a/arch/mips64/sgi-ip27/ip27-init.c
+++ b/arch/mips64/sgi-ip27/ip27-init.c
@@ -1,4 +1,5 @@
#include <linux/kernel.h>
+#include <linux/init.h>
#include <linux/sched.h>
#include <linux/mmzone.h> /* for numnodes */
#include <asm/sn/types.h>
@@ -281,19 +282,53 @@ void per_cpu_init(void)
#endif
}
+/*
+ * This is similar to hard_smp_processor_id().
+ */
+cpuid_t getcpuid(void)
+{
+ klcpu_t *klcpu;
+
+ klcpu = nasid_slice_to_cpuinfo(get_nasid(),LOCAL_HUB_L(PI_CPU_NUM));
+ return klcpu->cpu_info.virtid;
+}
+
+#ifdef CONFIG_SMP
+
+void __init smp_callin(void)
+{
+#if 0
+ calibrate_delay();
+ smp_store_cpu_info(cpuid);
+#endif
+}
+
+int __init start_secondary(void)
+{
+ extern int cpu_idle(void);
+ extern atomic_t smp_commenced;
+
+ smp_callin();
+ while (!atomic_read(&smp_commenced));
+ return cpu_idle();
+}
static atomic_t numstarted = ATOMIC_INIT(0);
void cboot(void)
{
atomic_inc(&numstarted);
- /* printk("Child!\n"); */
- while(1);
+ CPUMASK_CLRB(boot_barrier, getcpuid()); /* needs atomicity */
+#if 0
+ per_cpu_init();
+ ecc_init();
+ bte_lateinit();
+ init_mfhi_war();
+ flush_tlb();
+ flush_cache();
+#endif
+ start_secondary();
}
-#ifdef CONFIG_SMP
-
-static long bootstacks[MAXCPUS][128];
-
void allowboot(void)
{
int num_cpus = 0;
@@ -320,15 +355,44 @@ void allowboot(void)
/* Skip holes in CPU space */
if (CPUMASK_TSTB(boot_cpumask, cpu)) {
- num_cpus++;
+ struct task_struct *p;
/*
+ * The following code is purely to make sure
+ * Linux can schedule processes on this slave.
+ */
+ kernel_thread(0, NULL, CLONE_PID);
+ p = init_task.prev_task;
+ init_tasks[num_cpus] = p;
+ p->processor = num_cpus;
+ p->has_cpu = 1; /* we schedule the first task manually */
+ del_from_runqueue(p);
+ unhash_process(p);
+ /* Attach to the address space of init_task. */
+ atomic_inc(&init_mm.mm_count);
+ p->active_mm = &init_mm;
+
+ /*
* Launch a slave into bootstrap().
- * It doesn't take an argument, and we'll
- * take care of sp and gp when we get there.
+ * It doesn't take an argument, and we
+ * set sp to the kernel stack of the newly
+ * created idle process, gp to the proc struct
+ * (so that current-> works).
*/
LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu),
- (launch_proc_t)bootstrap, 0, bootstacks[cpu], 0);
+ (launch_proc_t)bootstrap, 0,
+ (void *)((unsigned long)p+KERNEL_STACK_SIZE - 32),
+ (void *)p);
+
+ /*
+ * Now optimistically set the mapping arrays. We
+ * need to wait here, verify the cpu booted up, then
+ * fire up the next cpu.
+ */
+ __cpu_number_map[cpu] = num_cpus;
+ __cpu_logical_map[num_cpus] = cpu;
+ num_cpus++;
+ /* smp_num_cpus++; Do after smp_send_reschedule works */
}
}
@@ -353,4 +417,6 @@ void allowboot(void)
#endif
}
-#endif
+#else /* CONFIG_SMP */
+void cboot(void) {}
+#endif /* CONFIG_SMP */