2005-04-16 15:20:36 -07:00
# ifndef __ASM_SMP_H
# define __ASM_SMP_H
/*
* We need the APIC definitions automatically as part of ' smp . h '
*/
# ifndef __ASSEMBLY__
# include <linux/kernel.h>
# include <linux/threads.h>
# include <linux/cpumask.h>
# endif
2007-05-02 19:27:04 +02:00
# if defined(CONFIG_X86_LOCAL_APIC) && !defined(__ASSEMBLY__)
2005-04-16 15:20:36 -07:00
# include <asm/bitops.h>
# include <asm/mpspec.h>
2007-05-02 19:27:04 +02:00
# include <asm/apic.h>
2005-04-16 15:20:36 -07:00
# ifdef CONFIG_X86_IO_APIC
# include <asm/io_apic.h>
# endif
# endif
# define BAD_APICID 0xFFu
# ifdef CONFIG_SMP
# ifndef __ASSEMBLY__
/*
* Private routines / data
*/
extern void smp_alloc_memory ( void ) ;
extern int pic_mode ;
extern int smp_num_siblings ;
extern cpumask_t cpu_sibling_map [ ] ;
2005-04-16 15:25:15 -07:00
extern cpumask_t cpu_core_map [ ] ;
2005-04-16 15:20:36 -07:00
extern void ( * mtrr_hook ) ( void ) ;
extern void zap_low_mappings ( void ) ;
2005-06-25 14:54:53 -07:00
extern void lock_ipi_call_lock ( void ) ;
extern void unlock_ipi_call_lock ( void ) ;
2005-04-16 15:20:36 -07:00
# define MAX_APICID 256
extern u8 x86_cpu_to_apicid [ ] ;
2005-11-08 21:42:33 -08:00
# define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu]
2007-07-17 18:37:03 -07:00
extern void set_cpu_sibling_map ( int cpu ) ;
2005-06-25 14:54:56 -07:00
# ifdef CONFIG_HOTPLUG_CPU
extern void cpu_exit_clear ( void ) ;
extern void cpu_uninit ( void ) ;
2007-07-17 18:37:03 -07:00
extern void remove_siblinginfo ( int cpu ) ;
2005-06-25 14:54:56 -07:00
# endif
2007-05-02 19:27:11 +02:00
struct smp_ops
{
void ( * smp_prepare_boot_cpu ) ( void ) ;
void ( * smp_prepare_cpus ) ( unsigned max_cpus ) ;
int ( * cpu_up ) ( unsigned cpu ) ;
void ( * smp_cpus_done ) ( unsigned max_cpus ) ;
void ( * smp_send_stop ) ( void ) ;
void ( * smp_send_reschedule ) ( int cpu ) ;
int ( * smp_call_function_mask ) ( cpumask_t mask ,
void ( * func ) ( void * info ) , void * info ,
int wait ) ;
} ;
extern struct smp_ops smp_ops ;
static inline void smp_prepare_boot_cpu ( void )
{
smp_ops . smp_prepare_boot_cpu ( ) ;
}
static inline void smp_prepare_cpus ( unsigned int max_cpus )
{
smp_ops . smp_prepare_cpus ( max_cpus ) ;
}
static inline int __cpu_up ( unsigned int cpu )
{
return smp_ops . cpu_up ( cpu ) ;
}
static inline void smp_cpus_done ( unsigned int max_cpus )
{
smp_ops . smp_cpus_done ( max_cpus ) ;
}
static inline void smp_send_stop ( void )
{
smp_ops . smp_send_stop ( ) ;
}
static inline void smp_send_reschedule ( int cpu )
{
smp_ops . smp_send_reschedule ( cpu ) ;
}
static inline int smp_call_function_mask ( cpumask_t mask ,
void ( * func ) ( void * info ) , void * info ,
int wait )
{
return smp_ops . smp_call_function_mask ( mask , func , info , wait ) ;
}
void native_smp_prepare_boot_cpu ( void ) ;
void native_smp_prepare_cpus ( unsigned int max_cpus ) ;
int native_cpu_up ( unsigned int cpunum ) ;
void native_smp_cpus_done ( unsigned int max_cpus ) ;
2007-02-13 13:26:21 +01:00
# ifndef CONFIG_PARAVIRT
# define startup_ipi_hook(phys_apicid, start_eip, start_esp) \
do { } while ( 0 )
# endif
2005-04-16 15:20:36 -07:00
/*
* This function is needed by all SMP systems . It must _always_ be valid
* from the initial startup . We map APIC_BASE very early in page_setup ( ) ,
* so this is correct in the x86 case .
*/
2007-05-02 19:27:16 +02:00
DECLARE_PER_CPU ( int , cpu_number ) ;
# define raw_smp_processor_id() (x86_read_percpu(cpu_number))
2005-04-16 15:20:36 -07:00
extern cpumask_t cpu_callout_map ;
extern cpumask_t cpu_callin_map ;
2005-09-03 15:56:51 -07:00
extern cpumask_t cpu_possible_map ;
2005-04-16 15:20:36 -07:00
/* We don't mark CPUs online until __cpu_up(), so we need another measure */
static inline int num_booting_cpus ( void )
{
return cpus_weight ( cpu_callout_map ) ;
}
2006-09-30 23:29:07 -07:00
extern int safe_smp_processor_id ( void ) ;
2005-06-25 14:54:50 -07:00
extern int __cpu_disable ( void ) ;
extern void __cpu_die ( unsigned int cpu ) ;
2006-09-26 10:52:35 +02:00
extern unsigned int num_processors ;
2006-09-26 10:52:26 +02:00
2007-07-17 18:37:03 -07:00
void __cpuinit smp_store_cpu_info ( int id ) ;
2005-04-16 15:20:36 -07:00
# endif /* !__ASSEMBLY__ */
2005-11-08 21:42:33 -08:00
# else /* CONFIG_SMP */
2006-09-30 23:29:07 -07:00
# define safe_smp_processor_id() 0
2005-11-08 21:42:33 -08:00
# define cpu_physical_id(cpu) boot_cpu_physical_apicid
2005-04-16 15:20:36 -07:00
# define NO_PROC_ID 0xFF /* No processor magic marker */
2007-05-09 02:33:25 -07:00
# endif /* CONFIG_SMP */
2006-09-26 10:52:26 +02:00
# ifndef __ASSEMBLY__
2006-10-06 11:11:56 +02:00
2007-05-09 02:33:27 -07:00
# ifdef CONFIG_X86_LOCAL_APIC
# ifdef APIC_DEFINITION
extern int hard_smp_processor_id ( void ) ;
# else
# include <mach_apicdef.h>
static inline int hard_smp_processor_id ( void )
{
/* we don't want to mark this access volatile - bad code generation */
return GET_APIC_ID ( * ( unsigned long * ) ( APIC_BASE + APIC_ID ) ) ;
}
# endif /* APIC_DEFINITION */
# else /* CONFIG_X86_LOCAL_APIC */
# ifndef CONFIG_SMP
# define hard_smp_processor_id() 0
# endif
# endif /* CONFIG_X86_LOCAL_APIC */
2006-10-06 11:11:56 +02:00
extern u8 apicid_2_node [ ] ;
2006-09-26 10:52:26 +02:00
# ifdef CONFIG_X86_LOCAL_APIC
static __inline int logical_smp_processor_id ( void )
{
/* we don't want to mark this access volatile - bad code generation */
return GET_APIC_LOGICAL_ID ( * ( unsigned long * ) ( APIC_BASE + APIC_LDR ) ) ;
}
# endif
# endif
2005-04-16 15:20:36 -07:00
# endif