1/* smp.h: Sparc specific SMP stuff. 2 * 3 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) 4 */ 5 6#ifndef _SPARC_SMP_H 7#define _SPARC_SMP_H 8 9#include <linux/threads.h> 10#include <asm/head.h> 11#include <asm/btfixup.h> 12 13#ifndef __ASSEMBLY__ 14 15#include <linux/cpumask.h> 16 17#endif /* __ASSEMBLY__ */ 18 19#ifdef CONFIG_SMP 20 21#ifndef __ASSEMBLY__ 22 23#include <asm/ptrace.h> 24#include <asm/asi.h> 25#include <asm/atomic.h> 26 27/* 28 * Private routines/data 29 */ 30 31extern unsigned char boot_cpu_id; 32extern cpumask_t phys_cpu_present_map; 33#define cpu_possible_map phys_cpu_present_map 34 35typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long, 36 unsigned long, unsigned long); 37 38/* 39 * General functions that each host system must provide. 40 */ 41 42void sun4m_init_smp(void); 43void sun4d_init_smp(void); 44 45void smp_callin(void); 46void smp_boot_cpus(void); 47void smp_store_cpu_info(int); 48 49struct seq_file; 50void smp_bogo(struct seq_file *); 51void smp_info(struct seq_file *); 52 53BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) 54BTFIXUPDEF_CALL(void, smp_message_pass, int, int, unsigned long, int) 55BTFIXUPDEF_CALL(int, __hard_smp_processor_id, void) 56BTFIXUPDEF_BLACKBOX(hard_smp_processor_id) 57BTFIXUPDEF_BLACKBOX(load_current) 58 59#define smp_cross_call(func,arg1,arg2,arg3,arg4,arg5) BTFIXUP_CALL(smp_cross_call)(func,arg1,arg2,arg3,arg4,arg5) 60#define smp_message_pass(target,msg,data,wait) BTFIXUP_CALL(smp_message_pass)(target,msg,data,wait) 61 62static inline void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); } 63static inline void xc1(smpfunc_t func, unsigned long arg1) 64{ smp_cross_call(func, arg1, 0, 0, 0, 0); } 65static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2) 66{ smp_cross_call(func, arg1, arg2, 0, 0, 0); } 67static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2, 68 unsigned long arg3) 69{ smp_cross_call(func, arg1, arg2, arg3, 0, 0); } 70static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2, 71 unsigned long arg3, unsigned long arg4) 72{ smp_cross_call(func, arg1, arg2, arg3, arg4, 0); } 73static inline void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg2, 74 unsigned long arg3, unsigned long arg4, unsigned long arg5) 75{ smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); } 76 77static inline int smp_call_function(void (*func)(void *info), void *info, int nonatomic, int wait) 78{ 79 xc1((smpfunc_t)func, (unsigned long)info); 80 return 0; 81} 82 83static inline int cpu_logical_map(int cpu) 84{ 85 return cpu; 86} 87 88static inline int hard_smp4m_processor_id(void) 89{ 90 int cpuid; 91 92 __asm__ __volatile__("rd %%tbr, %0\n\t" 93 "srl %0, 12, %0\n\t" 94 "and %0, 3, %0\n\t" : 95 "=&r" (cpuid)); 96 return cpuid; 97} 98 99static inline int hard_smp4d_processor_id(void) 100{ 101 int cpuid; 102 103 __asm__ __volatile__("lda [%%g0] %1, %0\n\t" : 104 "=&r" (cpuid) : "i" (ASI_M_VIKING_TMP1)); 105 return cpuid; 106} 107 108#ifndef MODULE 109static inline int hard_smp_processor_id(void) 110{ 111 int cpuid; 112 113 /* Black box - sun4m 114 __asm__ __volatile__("rd %%tbr, %0\n\t" 115 "srl %0, 12, %0\n\t" 116 "and %0, 3, %0\n\t" : 117 "=&r" (cpuid)); 118 - sun4d 119 __asm__ __volatile__("lda [%g0] ASI_M_VIKING_TMP1, %0\n\t" 120 "nop; nop" : 121 "=&r" (cpuid)); 122 See btfixup.h and btfixupprep.c to understand how a blackbox works. 123 */ 124 __asm__ __volatile__("sethi %%hi(___b_hard_smp_processor_id), %0\n\t" 125 "sethi %%hi(boot_cpu_id), %0\n\t" 126 "ldub [%0 + %%lo(boot_cpu_id)], %0\n\t" : 127 "=&r" (cpuid)); 128 return cpuid; 129} 130#else 131static inline int hard_smp_processor_id(void) 132{ 133 int cpuid; 134 135 __asm__ __volatile__("mov %%o7, %%g1\n\t" 136 "call ___f___hard_smp_processor_id\n\t" 137 " nop\n\t" 138 "mov %%g2, %0\n\t" : "=r"(cpuid) : : "g1", "g2"); 139 return cpuid; 140} 141#endif 142 143#define raw_smp_processor_id() (current_thread_info()->cpu) 144 145#define prof_multiplier(__cpu) cpu_data(__cpu).multiplier 146#define prof_counter(__cpu) cpu_data(__cpu).counter 147 148void smp_setup_cpu_possible_map(void); 149 150#endif /* !(__ASSEMBLY__) */ 151 152/* Sparc specific messages. */ 153#define MSG_CROSS_CALL 0x0005 /* run func on cpus */ 154 155/* Empirical PROM processor mailbox constants. If the per-cpu mailbox 156 * contains something other than one of these then the ipi is from 157 * Linux's active_kernel_processor. This facility exists so that 158 * the boot monitor can capture all the other cpus when one catches 159 * a watchdog reset or the user enters the monitor using L1-A keys. 160 */ 161#define MBOX_STOPCPU 0xFB 162#define MBOX_IDLECPU 0xFC 163#define MBOX_IDLECPU2 0xFD 164#define MBOX_STOPCPU2 0xFE 165 166#else /* SMP */ 167 168#define hard_smp_processor_id() 0 169#define smp_setup_cpu_possible_map() do { } while (0) 170 171#endif /* !(SMP) */ 172 173#define NO_PROC_ID 0xFF 174 175#endif /* !(_SPARC_SMP_H) */ 176