2005-04-17 02:20:36 +04:00
/* smp.h: Sparc specific SMP stuff.
*
* Copyright ( C ) 1996 David S . Miller ( davem @ caip . rutgers . edu )
*/
# ifndef _SPARC_SMP_H
# define _SPARC_SMP_H
# include <linux/threads.h>
# include <asm/head.h>
# include <asm/btfixup.h>
# ifndef __ASSEMBLY__
# include <linux/cpumask.h>
# endif /* __ASSEMBLY__ */
# ifdef CONFIG_SMP
# ifndef __ASSEMBLY__
# include <asm/ptrace.h>
# include <asm/asi.h>
# include <asm/atomic.h>
/*
* Private routines / data
*/
extern unsigned char boot_cpu_id ;
extern cpumask_t phys_cpu_present_map ;
# define cpu_possible_map phys_cpu_present_map
typedef void ( * smpfunc_t ) ( unsigned long , unsigned long , unsigned long ,
unsigned long , unsigned long ) ;
/*
* General functions that each host system must provide .
*/
void sun4m_init_smp ( void ) ;
void sun4d_init_smp ( void ) ;
void smp_callin ( void ) ;
void smp_boot_cpus ( void ) ;
void smp_store_cpu_info ( int ) ;
struct seq_file ;
void smp_bogo ( struct seq_file * ) ;
void smp_info ( struct seq_file * ) ;
BTFIXUPDEF_CALL ( void , smp_cross_call , smpfunc_t , unsigned long , unsigned long , unsigned long , unsigned long , unsigned long )
BTFIXUPDEF_CALL ( void , smp_message_pass , int , int , unsigned long , int )
BTFIXUPDEF_CALL ( int , __hard_smp_processor_id , void )
BTFIXUPDEF_BLACKBOX ( hard_smp_processor_id )
BTFIXUPDEF_BLACKBOX ( load_current )
# define smp_cross_call(func,arg1,arg2,arg3,arg4,arg5) BTFIXUP_CALL(smp_cross_call)(func,arg1,arg2,arg3,arg4,arg5)
# define smp_message_pass(target,msg,data,wait) BTFIXUP_CALL(smp_message_pass)(target,msg,data,wait)
2005-10-04 04:37:02 +04:00
static inline void xc0 ( smpfunc_t func ) { smp_cross_call ( func , 0 , 0 , 0 , 0 , 0 ) ; }
static inline void xc1 ( smpfunc_t func , unsigned long arg1 )
2005-04-17 02:20:36 +04:00
{ smp_cross_call ( func , arg1 , 0 , 0 , 0 , 0 ) ; }
2005-10-04 04:37:02 +04:00
static inline void xc2 ( smpfunc_t func , unsigned long arg1 , unsigned long arg2 )
2005-04-17 02:20:36 +04:00
{ smp_cross_call ( func , arg1 , arg2 , 0 , 0 , 0 ) ; }
2005-10-04 04:37:02 +04:00
static inline void xc3 ( smpfunc_t func , unsigned long arg1 , unsigned long arg2 ,
2005-04-17 02:20:36 +04:00
unsigned long arg3 )
{ smp_cross_call ( func , arg1 , arg2 , arg3 , 0 , 0 ) ; }
2005-10-04 04:37:02 +04:00
static inline void xc4 ( smpfunc_t func , unsigned long arg1 , unsigned long arg2 ,
2005-04-17 02:20:36 +04:00
unsigned long arg3 , unsigned long arg4 )
{ smp_cross_call ( func , arg1 , arg2 , arg3 , arg4 , 0 ) ; }
2005-10-04 04:37:02 +04:00
static inline void xc5 ( smpfunc_t func , unsigned long arg1 , unsigned long arg2 ,
2005-04-17 02:20:36 +04:00
unsigned long arg3 , unsigned long arg4 , unsigned long arg5 )
{ smp_cross_call ( func , arg1 , arg2 , arg3 , arg4 , arg5 ) ; }
2005-10-04 04:37:02 +04:00
static inline int smp_call_function ( void ( * func ) ( void * info ) , void * info , int nonatomic , int wait )
2005-04-17 02:20:36 +04:00
{
xc1 ( ( smpfunc_t ) func , ( unsigned long ) info ) ;
return 0 ;
}
2005-10-04 04:37:02 +04:00
static inline int cpu_logical_map ( int cpu )
2005-04-17 02:20:36 +04:00
{
2006-03-24 09:36:19 +03:00
return cpu ;
2005-04-17 02:20:36 +04:00
}
2005-10-04 04:37:02 +04:00
static inline int hard_smp4m_processor_id ( void )
2005-04-17 02:20:36 +04:00
{
int cpuid ;
__asm__ __volatile__ ( " rd %%tbr, %0 \n \t "
" srl %0, 12, %0 \n \t "
" and %0, 3, %0 \n \t " :
" =&r " ( cpuid ) ) ;
return cpuid ;
}
2005-10-04 04:37:02 +04:00
static inline int hard_smp4d_processor_id ( void )
2005-04-17 02:20:36 +04:00
{
int cpuid ;
__asm__ __volatile__ ( " lda [%%g0] %1, %0 \n \t " :
" =&r " ( cpuid ) : " i " ( ASI_M_VIKING_TMP1 ) ) ;
return cpuid ;
}
# ifndef MODULE
2005-10-04 04:37:02 +04:00
static inline int hard_smp_processor_id ( void )
2005-04-17 02:20:36 +04:00
{
int cpuid ;
/* Black box - sun4m
__asm__ __volatile__ ( " rd %%tbr, %0 \n \t "
" srl %0, 12, %0 \n \t "
" and %0, 3, %0 \n \t " :
" =&r " ( cpuid ) ) ;
- sun4d
__asm__ __volatile__ ( " lda [%g0] ASI_M_VIKING_TMP1, %0 \n \t "
" nop; nop " :
" =&r " ( cpuid ) ) ;
See btfixup . h and btfixupprep . c to understand how a blackbox works .
*/
__asm__ __volatile__ ( " sethi %%hi(___b_hard_smp_processor_id), %0 \n \t "
" sethi %%hi(boot_cpu_id), %0 \n \t "
" ldub [%0 + %%lo(boot_cpu_id)], %0 \n \t " :
" =&r " ( cpuid ) ) ;
return cpuid ;
}
# else
2005-10-04 04:37:02 +04:00
static inline int hard_smp_processor_id ( void )
2005-04-17 02:20:36 +04:00
{
int cpuid ;
__asm__ __volatile__ ( " mov %%o7, %%g1 \n \t "
" call ___f___hard_smp_processor_id \n \t "
" nop \n \t "
" mov %%g2, %0 \n \t " : " =r " ( cpuid ) : : " g1 " , " g2 " ) ;
return cpuid ;
}
# endif
2005-06-22 04:14:34 +04:00
# define raw_smp_processor_id() (current_thread_info()->cpu)
2005-04-17 02:20:36 +04:00
# define prof_multiplier(__cpu) cpu_data(__cpu).multiplier
# define prof_counter(__cpu) cpu_data(__cpu).counter
2006-06-20 11:30:31 +04:00
void smp_setup_cpu_possible_map ( void ) ;
2005-04-17 02:20:36 +04:00
# endif /* !(__ASSEMBLY__) */
/* Sparc specific messages. */
# define MSG_CROSS_CALL 0x0005 /* run func on cpus */
/* Empirical PROM processor mailbox constants. If the per-cpu mailbox
* contains something other than one of these then the ipi is from
* Linux ' s active_kernel_processor . This facility exists so that
* the boot monitor can capture all the other cpus when one catches
* a watchdog reset or the user enters the monitor using L1 - A keys .
*/
# define MBOX_STOPCPU 0xFB
# define MBOX_IDLECPU 0xFC
# define MBOX_IDLECPU2 0xFD
# define MBOX_STOPCPU2 0xFE
2006-06-20 11:30:31 +04:00
# else /* SMP */
2007-05-09 13:33:25 +04:00
# define hard_smp_processor_id() 0
2006-06-20 11:30:31 +04:00
# define smp_setup_cpu_possible_map() do { } while (0)
# endif /* !(SMP) */
2005-04-17 02:20:36 +04:00
# define NO_PROC_ID 0xFF
# endif /* !(_SPARC_SMP_H) */