import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / include / asm-i386 / smpboot.h
1 #ifndef __ASM_SMPBOOT_H
2 #define __ASM_SMPBOOT_H
3
4 /*emum for clustered_apic_mode values*/
5 enum{
6         CLUSTERED_APIC_NONE = 0,
7         CLUSTERED_APIC_XAPIC,
8         CLUSTERED_APIC_NUMAQ
9 };
10
11 #ifdef CONFIG_X86_CLUSTERED_APIC
12 extern unsigned int apic_broadcast_id;
13 extern unsigned char clustered_apic_mode;
14 extern unsigned char esr_disable;
15 extern unsigned char int_delivery_mode;
16 extern unsigned int int_dest_addr_mode;
17 extern int cyclone_setup(char*);
18
19 static inline void detect_clustered_apic(char* oem, char* prod)
20 {
21         /*
22          * Can't recognize Summit xAPICs at present, so use the OEM ID.
23          */
24         if (!strncmp(oem, "IBM ENSW", 8) && !strncmp(prod, "VIGIL SMP", 9)){
25                 clustered_apic_mode = CLUSTERED_APIC_XAPIC;
26                 apic_broadcast_id = APIC_BROADCAST_ID_XAPIC;
27                 int_dest_addr_mode = APIC_DEST_PHYSICAL;
28                 int_delivery_mode = dest_Fixed;
29                 esr_disable = 1;
30                 /*Start cyclone clock*/
31                 cyclone_setup(0);
32         }
33         else if (!strncmp(oem, "IBM NUMA", 8)){
34                 clustered_apic_mode = CLUSTERED_APIC_NUMAQ;
35                 apic_broadcast_id = APIC_BROADCAST_ID_APIC;
36                 int_dest_addr_mode = APIC_DEST_LOGICAL;
37                 int_delivery_mode = dest_LowestPrio;
38                 esr_disable = 1;
39         }
40 }
41 #define INT_DEST_ADDR_MODE (int_dest_addr_mode)
42 #define INT_DELIVERY_MODE (int_delivery_mode)
43 #else /* CONFIG_X86_CLUSTERED_APIC */
44 #define apic_broadcast_id (APIC_BROADCAST_ID_APIC)
45 #define clustered_apic_mode (CLUSTERED_APIC_NONE)
46 #define esr_disable (0)
47 #define detect_clustered_apic(x,y)
48 #define INT_DEST_ADDR_MODE (APIC_DEST_LOGICAL)  /* logical delivery */
49 #define INT_DELIVERY_MODE (dest_LowestPrio)
50 #endif /* CONFIG_X86_CLUSTERED_APIC */
51 #define BAD_APICID 0xFFu
52
53 #define TRAMPOLINE_LOW phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0x8:0x467)
54 #define TRAMPOLINE_HIGH phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0xa:0x469)
55
56 #define boot_cpu_apicid ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?boot_cpu_logical_apicid:boot_cpu_physical_apicid)
57
58 extern unsigned char raw_phys_apicid[NR_CPUS];
59
60 /*
61  * How to map from the cpu_present_map
62  */
63 static inline int cpu_present_to_apicid(int mps_cpu)
64 {
65         if (clustered_apic_mode == CLUSTERED_APIC_XAPIC)
66                 return raw_phys_apicid[mps_cpu];
67         if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
68                 return (mps_cpu/4)*16 + (1<<(mps_cpu%4));
69         return mps_cpu;
70 }
71
72 static inline unsigned long apicid_to_phys_cpu_present(int apicid)
73 {
74         if(clustered_apic_mode)
75                 return 1UL << (((apicid >> 4) << 2) + (apicid & 0x3));
76         return 1UL << apicid;
77 }
78
79 #define physical_to_logical_apicid(phys_apic) ( (1ul << (phys_apic & 0x3)) | (phys_apic & 0xF0u) )
80
81 /*
82  * Mappings between logical cpu number and logical / physical apicid
83  * The first four macros are trivial, but it keeps the abstraction consistent
84  */
85 extern volatile int logical_apicid_2_cpu[];
86 extern volatile int cpu_2_logical_apicid[];
87 extern volatile int physical_apicid_2_cpu[];
88 extern volatile int cpu_2_physical_apicid[];
89
90 #define logical_apicid_to_cpu(apicid) logical_apicid_2_cpu[apicid]
91 #define cpu_to_logical_apicid(cpu) cpu_2_logical_apicid[cpu]
92 #define physical_apicid_to_cpu(apicid) physical_apicid_2_cpu[apicid]
93 #define cpu_to_physical_apicid(cpu) cpu_2_physical_apicid[cpu]
94 #ifdef CONFIG_MULTIQUAD                 /* use logical IDs to bootstrap */
95 #define boot_apicid_to_cpu(apicid) logical_apicid_2_cpu[apicid]
96 #define cpu_to_boot_apicid(cpu) cpu_2_logical_apicid[cpu]
97 #else /* !CONFIG_MULTIQUAD */           /* use physical IDs to bootstrap */
98 #define boot_apicid_to_cpu(apicid) physical_apicid_2_cpu[apicid]
99 #define cpu_to_boot_apicid(cpu) cpu_2_physical_apicid[cpu]
100 #endif /* CONFIG_MULTIQUAD */
101
102 #ifdef CONFIG_X86_CLUSTERED_APIC
103 static inline int target_cpus(void)
104 {
105         static int cpu;
106         switch(clustered_apic_mode){
107                 case CLUSTERED_APIC_NUMAQ:
108                         /* Broadcast intrs to local quad only. */
109                         return APIC_BROADCAST_ID_APIC;
110                 case CLUSTERED_APIC_XAPIC:
111                         /*round robin the interrupts*/
112                         cpu = (cpu+1)%smp_num_cpus;
113                         return cpu_to_physical_apicid(cpu);
114                 default:
115         }
116         return cpu_online_map;
117 }
118 #else
119 #define target_cpus() (0x01)
120 #endif
121 #endif