2008-03-03 20:12:29 +03:00
# ifndef _ASM_X86_SMP_H_
# define _ASM_X86_SMP_H_
# ifndef __ASSEMBLY__
2008-03-03 20:12:31 +03:00
# include <linux/cpumask.h>
2008-03-03 20:12:40 +03:00
# include <linux/init.h>
2008-03-19 20:25:18 +03:00
# include <asm/percpu.h>
2008-03-03 20:12:31 +03:00
2008-03-27 20:06:00 +03:00
/*
* We need the APIC definitions automatically as part of ' smp . h '
*/
# ifdef CONFIG_X86_LOCAL_APIC
# include <asm / mpspec.h>
# include <asm / apic.h>
# ifdef CONFIG_X86_IO_APIC
# include <asm / io_apic.h>
# endif
# endif
# include <asm/pda.h>
# include <asm/thread_info.h>
2008-03-03 20:12:31 +03:00
extern cpumask_t cpu_callout_map ;
2008-03-27 20:06:04 +03:00
extern cpumask_t cpu_initialized ;
extern cpumask_t cpu_callin_map ;
extern void ( * mtrr_hook ) ( void ) ;
extern void zap_low_mappings ( void ) ;
2008-03-03 20:12:31 +03:00
extern int smp_num_siblings ;
extern unsigned int num_processors ;
2008-03-19 20:25:59 +03:00
extern cpumask_t cpu_initialized ;
2008-03-03 20:12:29 +03:00
2008-03-26 01:06:51 +03:00
# ifdef CONFIG_SMP
2008-03-19 20:25:18 +03:00
extern u16 x86_cpu_to_apicid_init [ ] ;
extern u16 x86_bios_cpu_apicid_init [ ] ;
extern void * x86_cpu_to_apicid_early_ptr ;
extern void * x86_bios_cpu_apicid_early_ptr ;
2008-03-26 01:06:51 +03:00
# else
# define x86_cpu_to_apicid_early_ptr NULL
# define x86_bios_cpu_apicid_early_ptr NULL
# endif
2008-03-19 20:25:18 +03:00
DECLARE_PER_CPU ( cpumask_t , cpu_sibling_map ) ;
DECLARE_PER_CPU ( cpumask_t , cpu_core_map ) ;
DECLARE_PER_CPU ( u16 , cpu_llc_id ) ;
DECLARE_PER_CPU ( u16 , x86_cpu_to_apicid ) ;
DECLARE_PER_CPU ( u16 , x86_bios_cpu_apicid ) ;
2008-03-19 20:25:57 +03:00
/* Static state in head.S used to set up a CPU */
extern struct {
void * sp ;
unsigned short ss ;
} stack_start ;
2008-03-03 20:12:32 +03: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 ) ;
} ;
2008-03-03 20:12:59 +03:00
/* Globals due to paravirt */
extern void set_cpu_sibling_map ( int cpu ) ;
2008-03-03 20:12:33 +03:00
# ifdef CONFIG_SMP
2008-03-19 20:24:59 +03:00
# ifndef CONFIG_PARAVIRT
# define startup_ipi_hook(phys_apicid, start_eip, start_esp) do { } while (0)
# endif
2008-03-03 20:12:33 +03:00
extern struct smp_ops smp_ops ;
2008-03-03 20:12:34 +03:00
2008-03-03 20:12:51 +03:00
static inline void smp_send_stop ( void )
{
smp_ops . smp_send_stop ( ) ;
}
2008-03-03 20:12:37 +03:00
static inline void smp_prepare_boot_cpu ( void )
{
smp_ops . smp_prepare_boot_cpu ( ) ;
}
2008-03-03 20:12:38 +03:00
static inline void smp_prepare_cpus ( unsigned int max_cpus )
{
smp_ops . smp_prepare_cpus ( max_cpus ) ;
}
2008-03-03 20:12:39 +03:00
static inline void smp_cpus_done ( unsigned int max_cpus )
{
smp_ops . smp_cpus_done ( max_cpus ) ;
}
2008-03-03 20:12:36 +03:00
static inline int __cpu_up ( unsigned int cpu )
{
return smp_ops . cpu_up ( cpu ) ;
}
2008-03-03 20:12:34 +03:00
static inline void smp_send_reschedule ( int cpu )
{
smp_ops . smp_send_reschedule ( cpu ) ;
}
2008-03-03 20:12:35 +03:00
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 ) ;
}
2008-03-03 20:12:36 +03:00
2008-03-03 20:12:37 +03:00
void native_smp_prepare_boot_cpu ( void ) ;
2008-03-03 20:12:38 +03:00
void native_smp_prepare_cpus ( unsigned int max_cpus ) ;
2008-03-03 20:12:39 +03:00
void native_smp_cpus_done ( unsigned int max_cpus ) ;
2008-03-03 20:12:36 +03:00
int native_cpu_up ( unsigned int cpunum ) ;
2008-03-03 20:12:40 +03:00
2008-03-03 20:13:07 +03:00
extern int __cpu_disable ( void ) ;
extern void __cpu_die ( unsigned int cpu ) ;
2008-03-03 20:12:42 +03:00
extern void prefill_possible_map ( void ) ;
2008-03-03 20:13:12 +03:00
2008-03-19 20:25:05 +03:00
void smp_store_cpu_info ( int id ) ;
2008-03-19 20:25:58 +03:00
# define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu)
2008-03-27 20:06:02 +03: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 ) ;
}
# endif /* CONFIG_SMP */
2008-04-04 23:41:44 +04:00
extern unsigned disabled_cpus __cpuinitdata ;
2008-03-27 20:06:02 +03:00
# ifdef CONFIG_X86_32_SMP
/*
* 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 .
*/
DECLARE_PER_CPU ( int , cpu_number ) ;
# define raw_smp_processor_id() (x86_read_percpu(cpu_number))
extern int safe_smp_processor_id ( void ) ;
# elif defined(CONFIG_X86_64_SMP)
# define raw_smp_processor_id() read_pda(cpunumber)
# define stack_smp_processor_id() \
( { \
struct thread_info * ti ; \
__asm__ ( " andq %%rsp,%0; " : " =r " ( ti ) : " 0 " ( CURRENT_MASK ) ) ; \
ti - > cpu ; \
} )
# define safe_smp_processor_id() smp_processor_id()
# else /* !CONFIG_X86_32_SMP && !CONFIG_X86_64_SMP */
2008-03-19 20:25:58 +03:00
# define cpu_physical_id(cpu) boot_cpu_physical_apicid
2008-03-27 20:06:02 +03:00
# define safe_smp_processor_id() 0
# define stack_smp_processor_id() 0
2008-03-03 20:12:33 +03:00
# endif
2008-03-03 20:12:32 +03:00
2008-03-27 20:05:58 +03: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 ( * ( u32 * ) ( APIC_BASE + APIC_LDR ) ) ;
}
2008-03-30 14:17:12 +04:00
# ifndef CONFIG_X86_64
2008-03-28 22:12:02 +03:00
static inline unsigned int read_apic_id ( void )
{
return * ( u32 * ) ( APIC_BASE + APIC_ID ) ;
}
2008-03-28 22:12:16 +03:00
# else
extern unsigned int read_apic_id ( void ) ;
# endif
2008-03-28 22:12:02 +03:00
2008-03-27 20:05:58 +03:00
# 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 */
2008-03-28 22:12:02 +03:00
return GET_APIC_ID ( read_apic_id ( ) ) ;
2008-03-27 20:05:58 +03:00
}
# endif /* APIC_DEFINITION */
# else /* CONFIG_X86_LOCAL_APIC */
# ifndef CONFIG_SMP
# define hard_smp_processor_id() 0
# endif
# endif /* CONFIG_X86_LOCAL_APIC */
2008-03-03 20:13:01 +03:00
# ifdef CONFIG_HOTPLUG_CPU
extern void cpu_exit_clear ( void ) ;
extern void cpu_uninit ( void ) ;
# endif
2008-03-03 20:12:30 +03:00
extern void smp_alloc_memory ( void ) ;
extern void lock_ipi_call_lock ( void ) ;
extern void unlock_ipi_call_lock ( void ) ;
2008-03-03 20:12:29 +03:00
# endif /* __ASSEMBLY__ */
# endif