diff options
author | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-04-05 01:48:44 +0000 |
---|---|---|
committer | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-04-05 01:48:44 +0000 |
commit | 5fa044b61946b5e3d0d959dc507a38aeb3d4f8fd (patch) | |
tree | b3a8c6144a7bd2e27519d81b0855c648c6590ea5 | |
parent | 687e82cd9a59b6a17e14bbe87c6f6ab299ff36ac (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.
-rw-r--r-- | arch/mips64/kernel/head.S | 208 | ||||
-rw-r--r-- | arch/mips64/kernel/smp.c | 1 | ||||
-rw-r--r-- | arch/mips64/sgi-ip27/ip27-init.c | 19 |
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(®ion_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 |