diff options
author | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-04-04 18:28:17 +0000 |
---|---|---|
committer | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-04-04 18:28:17 +0000 |
commit | 09b51a8bad6352607cc40618d3be5a7525eb4470 (patch) | |
tree | 4ad25ffaaace035cc1cfba0a44546ae351c0cf56 | |
parent | d49f62d0497bc81a70b1c2e01ddec71d8ea93c30 (diff) |
Rudimentary code to launch slave processors by the master processor.
Completely untested, never executed ...
-rw-r--r-- | arch/mips64/sgi-ip27/ip27-init.c | 124 | ||||
-rw-r--r-- | include/asm-mips64/addrspace.h | 5 | ||||
-rw-r--r-- | include/asm-mips64/sn/launch.h | 149 |
3 files changed, 277 insertions, 1 deletions
diff --git a/arch/mips64/sgi-ip27/ip27-init.c b/arch/mips64/sgi-ip27/ip27-init.c index e09bc6036..5c0ab4062 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/sched.h> #include <linux/mmzone.h> /* for numnodes */ #include <asm/sn/types.h> #include <asm/sn/sn0/addrs.h> @@ -8,16 +9,25 @@ #include <asm/ioc3.h> #include <asm/mipsregs.h> #include <asm/sn/gda.h> +#include <asm/sn/intr.h> +#include <asm/current.h> +#include <asm/smp.h> +#include <asm/processor.h> +#include <asm/sn/launch.h> typedef unsigned long cpumask_t; /* into asm/sn/types.h */ typedef unsigned long cpuid_t; #define CPUMASK_CLRALL(p) (p) = 0 #define CPUMASK_SETB(p, bit) (p) |= 1 << (bit) +#define CPUMASK_CLRB(p, bit) (p) &= ~(1ULL << (bit)) +#define CPUMASK_TSTB(p, bit) ((p) & (1ULL << (bit))) cpumask_t boot_cpumask; +static volatile cpumask_t boot_barrier; hubreg_t region_mask = 0; static int fine_mode = 0; +int maxcpus; cnodeid_t nasid_to_compact_node[MAX_NASIDS]; nasid_t compact_to_nasid_node[MAX_COMPACT_NODES]; @@ -184,7 +194,7 @@ cpuid_t cpu_node_probe(cpumask_t *boot_cpumask, int *numnodes) void mlreset (void) { - int i, maxcpus; + int i; fine_mode = is_fine_dirmode(); @@ -225,3 +235,115 @@ void mlreset (void) } } + +void intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend, int base_level, + char *name) +{ + volatile hubreg_t bits; + int i; + + /* Check pending interrupts */ + if ((bits = HUB_L(pend)) != 0) + for (i = 0; i < N_INTPEND_BITS; i++) + if (bits & (1 << i)) + LOCAL_HUB_CLR_INTR(base_level + i); +} + +void intr_clear_all(nasid_t nasid) +{ + REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0); + REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0); + REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0); + REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0); + intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND0), + INT_PEND0_BASELVL, "INT_PEND0"); + intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND1), + INT_PEND1_BASELVL, "INT_PEND1"); +} + +void sn_mp_setup(void) +{ + cnodeid_t cnode; +#if 0 + cpuid_t cpu; +#endif + + for (cnode = 0; cnode < numnodes; cnode++) { +#if 0 + init_platform_nodepda(); +#endif + intr_clear_all(COMPACT_TO_NASID_NODEID(cnode)); + } +#if 0 + for (cpu = 0; cpu < maxcpus; cpu++) { + init_platform_pda(); + } +#endif +} + +void per_cpu_init(void) +{ +#if 0 + cpuid_t cpu = getcpuid(); + cnodeid_t cnode = get_compact_nodeid(); + + intr_init(); + per_hub_init(cnode); + install_cpuintr(cpu); + install_tlbintr(cpu); +#endif +} + +void allowboot(void) +{ + int num_cpus = 0; + cpuid_t cpu; + cnodeid_t cnode; + + sn_mp_setup(); + per_cpu_init(); +#if 0 + bte_lateinit(); + ecc_init(); +#endif + + boot_barrier = boot_cpumask; + /* Launch slaves. */ + for (cpu = 0; cpu < maxcpus; cpu++) { + if (cpu == smp_processor_id()) { + num_cpus++; + /* We're already started, clear our bit */ + CPUMASK_CLRB(boot_barrier, cpu); + continue; + } + + /* Skip holes in CPU space */ + if (CPUMASK_TSTB(boot_cpumask, cpu)) { + num_cpus++; + + /* + * Launch a slave into bootstrap(). + * It doesn't take an argument, and we'll + * take care of sp and gp when we get there. + */ +/* cputonasid/cputoslice not working yet */ + LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu), 0, 0, 0, 0); + } + } + +#ifdef LATER + Wait logic goes here. +#endif + for (cnode = 0; cnode < numnodes; cnode++) { +#if 0 + if (cnodetocpu(cnode) == -1) { + printk("Initializing headless hub,cnode %d", cnode); + per_hub_init(cnode); + } +#endif + } +#if 0 + cpu_io_setup(); + init_mfhi_war(); +#endif +} diff --git a/include/asm-mips64/addrspace.h b/include/asm-mips64/addrspace.h index d4343a4b9..1591e1071 100644 --- a/include/asm-mips64/addrspace.h +++ b/include/asm-mips64/addrspace.h @@ -104,4 +104,9 @@ #endif #define K2BASE 0xc000000000000000 +#if !defined (CONFIG_CPU_R8000) +#define COMPAT_K1BASE32 0xffffffffa0000000 +#define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */ +#endif + #endif /* _ASM_ADDRSPACE_H */ diff --git a/include/asm-mips64/sn/launch.h b/include/asm-mips64/sn/launch.h new file mode 100644 index 000000000..5d1d683cf --- /dev/null +++ b/include/asm-mips64/sn/launch.h @@ -0,0 +1,149 @@ +/************************************************************************** + * * + * Copyright (C) 1992-1997, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ + +#ifndef __SYS_SN_LAUNCH_H__ +#define __SYS_SN_LAUNCH_H__ + +#ident "$Revision: 1.10 $" + +#include <linux/config.h> +#include <asm/sn/types.h> +#include <asm/sn/addrs.h> + +/* + * The launch data structure resides at a fixed place in each node's memory + * and is used to communicate between the master processor and the slave + * processors. + * + * The master stores launch parameters in the launch structure + * corresponding to a target processor that is in a slave loop, then sends + * an interrupt to the slave processor. The slave calls the desired + * function, then returns to the slave loop. The master may poll or wait + * for the slaves to finish. + * + * There is an array of launch structures, one per CPU on the node. One + * interrupt level is used per local CPU. + */ + +#define LAUNCH_MAGIC 0xaddbead2addbead3 +#define LAUNCH_SIZEOF 0x100 + +#define LAUNCH_OFF_MAGIC 0x00 /* Struct offsets for assembly */ +#define LAUNCH_OFF_BUSY 0x08 +#define LAUNCH_OFF_CALL 0x10 +#define LAUNCH_OFF_CALLC 0x18 +#define LAUNCH_OFF_CALLPARM 0x20 +#define LAUNCH_OFF_STACK 0x28 +#define LAUNCH_OFF_GP 0x30 +#define LAUNCH_OFF_BEVUTLB 0x38 +#define LAUNCH_OFF_BEVNORMAL 0x40 +#define LAUNCH_OFF_BEVECC 0x48 + +#define LAUNCH_STATE_DONE 0 /* Return value of LAUNCH_POLL */ +#define LAUNCH_STATE_SENT 1 +#define LAUNCH_STATE_RECD 2 + +/* + * The launch routine is called only if the complement address is correct. + * + * Before control is transferred to a routine, the compliment address + * is zeroed (invalidated) to prevent an accidental call from a spurious + * interrupt. + * + * The slave_launch routine turns on the BUSY flag, and the slave loop + * clears the BUSY flag after control is returned to it. + */ + +#ifdef _LANGUAGE_C + +typedef int launch_state_t; +typedef void (*launch_proc_t)(u64 call_parm); + +typedef struct launch_s { + volatile u64 magic; /* Magic number */ + volatile u64 busy; /* Slave currently active */ + volatile launch_proc_t call_addr; /* Func. for slave to call */ + volatile u64 call_addr_c; /* 1's complement of call_addr*/ + volatile u64 call_parm; /* Single parm passed to call*/ + volatile void *stack_addr; /* Stack pointer for slave function */ + volatile void *gp_addr; /* Global pointer for slave func. */ + volatile char *bevutlb;/* Address of bev utlb ex handler */ + volatile char *bevnormal;/*Address of bev normal ex handler */ + volatile char *bevecc;/* Address of bev cache err handler */ + volatile char pad[160]; /* Pad to LAUNCH_SIZEOF */ +} launch_t; + +/* + * PROM entry points for launch routines are determined by IP27prom/start.s + */ + +#ifdef CONFIG_SGI_IP27 +#define LAUNCH_SLAVE (*(void (*)(int nasid, int cpu, \ + launch_proc_t call_addr, \ + u64 call_parm, \ + void *stack_addr, \ + void *gp_addr)) \ + IP27PROM_LAUNCHSLAVE) + +#define LAUNCH_WAIT (*(void (*)(int nasid, int cpu, int timeout_msec)) \ + IP27PROM_WAITSLAVE) + +#define LAUNCH_POLL (*(launch_state_t (*)(int nasid, int cpu)) \ + IP27PROM_POLLSLAVE) + +#define LAUNCH_LOOP (*(void (*)(void)) \ + IP27PROM_SLAVELOOP) + +#define LAUNCH_FLASH (*(void (*)(void)) \ + IP27PROM_FLASHLEDS) + +#else /* if defined (SN1) */ + +#define LAUNCH_SLAVE (*(void (*)(int nasid, int cpu, \ + launch_proc_t call_addr, \ + __int64_t call_parm, \ + void *stack_addr, \ + void *gp_addr)) \ + IP33PROM_LAUNCHSLAVE) + +#define LAUNCH_WAIT (*(void (*)(int nasid, int cpu, int timeout_msec)) \ + IP33PROM_WAITSLAVE) + +#define LAUNCH_POLL (*(launch_state_t (*)(int nasid, int cpu)) \ + IP33PROM_POLLSLAVE) + +#define LAUNCH_LOOP (*(void (*)(void)) \ + IP33PROM_SLAVELOOP) + +#define LAUNCH_FLASH (*(void (*)(void)) \ + IP33PROM_FLASHLEDS) + +#endif + +#ifdef _STANDALONE + +launch_t *launch_get(int nasid, int cpu); +launch_t *launch_get_current(void); +void launch_loop(void); +void launch_slave(int nasid, int cpu, + launch_proc_t call_addr, + __int64_t call_parm, + void *stack_addr, + void *gp_addr); +int launch_wait(int nasid, int cpu, int timeout_msec); +launch_state_t launch_poll(int nasid, int cpu); + +#endif /* _STANDALONE */ + +#endif /* _LANGUAGE_C */ + +#endif /* __SYS_SN_LAUNCH_H__ */ |