summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorKanoj Sarcar <kanoj@engr.sgi.com>2000-04-05 01:48:44 +0000
committerKanoj Sarcar <kanoj@engr.sgi.com>2000-04-05 01:48:44 +0000
commit5fa044b61946b5e3d0d959dc507a38aeb3d4f8fd (patch)
treeb3a8c6144a7bd2e27519d81b0855c648c6590ea5 /arch
parent687e82cd9a59b6a17e14bbe87c6f6ab299ff36ac (diff)
Try to launch all the slave cpus in the system. Currently, I _think_
only the slave on the same node as the master gets launched, investigating why the slaves on the other nodes are not ... Slave processors use a static stack surrently while booting up.
Diffstat (limited to 'arch')
-rw-r--r--arch/mips64/kernel/head.S208
-rw-r--r--arch/mips64/kernel/smp.c1
-rw-r--r--arch/mips64/sgi-ip27/ip27-init.c19
3 files changed, 146 insertions, 82 deletions
diff --git a/arch/mips64/kernel/head.S b/arch/mips64/kernel/head.S
index 645209276..bf74a983e 100644
--- a/arch/mips64/kernel/head.S
+++ b/arch/mips64/kernel/head.S
@@ -1,85 +1,131 @@
-/* $Id: head.S,v 1.6 2000/03/27 21:05:04 ulfc Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Head.S contains the MIPS exception handler and startup code.
- *
- * Copyright (C) 1994, 1995 Waldorf Electronics
- * Written by Ralf Baechle and Andreas Busse
- * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
- */
-#define __ASSEMBLY__
#include <linux/config.h>
#include <linux/init.h>
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/processor.h>
-#include <asm/mipsregs.h>
-#include <asm/stackframe.h>
-
- .text
-
-EXPORT(stext) # used for profiling
-EXPORT(_stext)
+#include <linux/spinlock.h>
+#include <linux/threads.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/sched.h>
- __INIT
-
-NESTED(kernel_entry, 16, sp) # kernel entry point
-
-#ifdef CONFIG_ARC64
- /* We get launched at a XKPHYS address but the kernel is linked to
- run at a KSEG0 address, so jump there. */
- la t0, 1f
- jr t0
-1:
+#include <asm/atomic.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/hardirq.h>
+
+#ifdef CONFIG_SGI_IP27
+
+#include <asm/sn/arch.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/agent.h>
+
+#define DOACTION 0xab
+
+static void sendintr(int destid, unsigned char status)
+{
+ int level;
+
+#if (CPUS_PER_NODE == 2)
+ /*
+ * CPU slice A gets level CPU_ACTION_A
+ * CPU slice B gets level CPU_ACTION_B
+ */
+ if (status == DOACTION)
+ level = CPU_ACTION_A + cputoslice(destid);
+ else /* DOTLBACTION */
+ level = N_INTPEND_BITS + TLB_INTR_A + cputoslice(destid);
+
+ /*
+ * Convert the compact hub number to the NASID to get the correct
+ * part of the address space. Then set the interrupt bit associated
+ * with the CPU we want to send the interrupt to.
+ */
+ REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cputocnode(destid)), level);
+#else
+ << Bomb! Must redefine this for more than 2 CPUS. >>
#endif
-
- ori sp, 0xf # align stack on 16 byte.
- xori sp, 0xf
-
- /* Note that all firmware passed argument registers still
- have their values. */
- jal prom_init # initialize firmware
-
- CLI # disable interrupts
-
- mfc0 t0, CP0_STATUS
- li t1, ~(ST0_CU1|ST0_CU2|ST0_CU3)
- and t0, t1
- or t0, (ST0_CU0|ST0_KX|ST0_SX|ST0_FR)
- mtc0 t0, CP0_STATUS
-
- la $28, init_task_union # init current pointer
- daddiu t0, $28, KERNEL_STACK_SIZE-32
- sd t0, kernelsp
- dsubu sp, t0, 4*SZREG # init stack pointer
-
- jal start_kernel
-1: b 1b # just in case ...
- END(kernel_entry)
-
- __FINIT
-
- .comm kernelsp, 8, 8 # current stackpointer
- .comm current_pgd, 8, 8 # current page tables
-
-#define PAGE_SIZE 0x1000
-
- .macro page name, order=0
- .globl \name
- .org . + (PAGE_SIZE << \order)
-\name: .size \name, (PAGE_SIZE << \order)
- .type \name, @object
- .endm
-
- .align 12
- .data
-
- page swapper_pg_dir, 1
- page invalid_pte_table, 1
- page invalid_pmd_table, 1
- page empty_bad_page_table, 1
- page empty_bad_page
+}
+
+#endif /* CONFIG_SGI_IP27 */
+
+/* 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);
+struct cpuinfo_mips cpu_data[NR_CPUS];
+int smp_num_cpus; /* Number that came online. */
+int __cpu_number_map[NR_CPUS];
+int __cpu_logical_map[NR_CPUS];
+cycles_t cacheflush_time;
+
+static void smp_tune_scheduling (void)
+{
+}
+
+void __init smp_boot_cpus(void)
+{
+ global_irq_holder = 0;
+ current->processor = 0;
+ init_idle();
+ smp_tune_scheduling();
+ smp_num_cpus = 1; /* for now */
+ allowboot();
+}
+
+void __init smp_commence(void)
+{
+ wmb();
+ atomic_set(&smp_commenced,1);
+}
+
+static void stop_this_cpu(void *dummy)
+{
+ /*
+ * Remove this CPU
+ */
+ for (;;);
+}
+
+void smp_send_stop(void)
+{
+ smp_call_function(stop_this_cpu, NULL, 1, 0);
+ smp_num_cpus = 1;
+}
+
+/*
+ * this function sends a 'reschedule' IPI to another CPU.
+ * it goes straight through and wastes no time serializing
+ * anything. Worst case is that we lose a reschedule ...
+ */
+void smp_send_reschedule(int cpu)
+{
+ panic("smp_send_reschedule\n");
+}
+
+/* Not really SMP stuff ... */
+int setup_profiling_timer(unsigned int multiplier)
+{
+}
+
+/*
+ * Run a function on all other CPUs.
+ * <func> The function to run. This must be fast and non-blocking.
+ * <info> An arbitrary pointer to pass to the function.
+ * <retry> If true, keep retrying until ready.
+ * <wait> If true, wait until function has completed on other CPUs.
+ * [RETURNS] 0 on success, else a negative status code.
+ *
+ * Does not return until remote CPUs are nearly ready to execute <func>
+ * or are or have executed.
+ */
+int
+smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
+{
+ /* XXX - kinda important ;-) */
+ panic("smp_call_function\n");
+}
+
+void flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
+ unsigned long va)
+{
+ panic("flush_tlb_others\n");
+}
diff --git a/arch/mips64/kernel/smp.c b/arch/mips64/kernel/smp.c
index d4365c647..bf74a983e 100644
--- a/arch/mips64/kernel/smp.c
+++ b/arch/mips64/kernel/smp.c
@@ -68,6 +68,7 @@ void __init smp_boot_cpus(void)
init_idle();
smp_tune_scheduling();
smp_num_cpus = 1; /* for now */
+ allowboot();
}
void __init smp_commence(void)
diff --git a/arch/mips64/sgi-ip27/ip27-init.c b/arch/mips64/sgi-ip27/ip27-init.c
index 64b4d5236..e866d6571 100644
--- a/arch/mips64/sgi-ip27/ip27-init.c
+++ b/arch/mips64/sgi-ip27/ip27-init.c
@@ -187,6 +187,7 @@ void mlreset (void)
*/
CPUMASK_CLRALL(boot_cpumask);
maxcpus = cpu_node_probe(&boot_cpumask, &numnodes);
+ printk("Discovered %d cpus on %d nodes\n", maxcpus, numnodes);
initpdas();
gen_region_mask(&region_mask, numnodes);
@@ -278,11 +279,22 @@ void per_cpu_init(void)
#endif
}
+static atomic_t numstarted = ATOMIC_INIT(0);
+void cboot(void)
+{
+ atomic_inc(&numstarted);
+ /* printk("Child!\n"); */
+ while(1);
+}
+
+static long bootstacks[MAXCPUS][128];
+
void allowboot(void)
{
int num_cpus = 0;
cpuid_t cpu;
cnodeid_t cnode;
+ extern void bootstrap(void);
sn_mp_setup();
per_cpu_init();
@@ -310,10 +322,15 @@ void allowboot(void)
* It doesn't take an argument, and we'll
* take care of sp and gp when we get there.
*/
- LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu), 0, 0, 0, 0);
+ LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu),
+ (launch_proc_t)bootstrap, 0, bootstacks[cpu], 0);
}
}
+ /* while(atomic_read(&numstarted) != (maxcpus - num_cpus)) */
+ while(atomic_read(&numstarted) == 0);
+ printk("Holding %d cpus slave\n", atomic_read(&numstarted));
+
#ifdef LATER
Wait logic goes here.
#endif