blob: 53adda099c968ba6b03583ac45f71eccdcf3bcc9 [file] [log] [blame]
Yinghai Luc7e79642008-07-25 02:17:33 -07001#ifndef __ASM_ES7000_APIC_H
2#define __ASM_ES7000_APIC_H
Linus Torvalds1da177e2005-04-16 15:20:36 -07003
Mike Travis4d9f9432009-01-05 17:09:41 -08004#include <linux/gfp.h>
5
Glauber de Oliveira Costacbe879f2008-03-19 14:25:19 -03006#define xapic_phys_to_log_apicid(cpu) per_cpu(x86_bios_cpu_apicid, cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007#define esr_disable (1)
8
Ingo Molnar7ed248d2009-01-28 03:43:47 +01009static inline int es7000_apic_id_registered(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070010{
Ingo Molnar7ed248d2009-01-28 03:43:47 +010011 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -070012}
13
Mike Travise7986732008-12-16 17:33:52 -080014static inline const cpumask_t *target_cpus_cluster(void)
Yinghai Luc7e79642008-07-25 02:17:33 -070015{
Mike Travise7986732008-12-16 17:33:52 -080016 return &CPU_MASK_ALL;
Linus Torvalds1da177e2005-04-16 15:20:36 -070017}
Linus Torvalds1da177e2005-04-16 15:20:36 -070018
Ingo Molnar0a9cc202009-01-28 04:30:40 +010019static inline const cpumask_t *es7000_target_cpus(void)
Yinghai Lub5fe3632008-11-18 08:14:14 -080020{
Mike Travise7986732008-12-16 17:33:52 -080021 return &cpumask_of_cpu(smp_processor_id());
Yinghai Lub5fe3632008-11-18 08:14:14 -080022}
23
24#define APIC_DFR_VALUE_CLUSTER (APIC_DFR_CLUSTER)
25#define INT_DELIVERY_MODE_CLUSTER (dest_LowestPrio)
26#define INT_DEST_MODE_CLUSTER (1) /* logical delivery broadcast to all procs */
27#define NO_BALANCE_IRQ_CLUSTER (1)
28
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#define APIC_DFR_VALUE (APIC_DFR_FLAT)
Yinghai Luc7e79642008-07-25 02:17:33 -070030#define NO_BALANCE_IRQ (0)
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#undef APIC_DEST_LOGICAL
32#define APIC_DEST_LOGICAL 0x0
Linus Torvalds1da177e2005-04-16 15:20:36 -070033
Linus Torvalds1da177e2005-04-16 15:20:36 -070034static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
Yinghai Luc7e79642008-07-25 02:17:33 -070035{
Linus Torvalds1da177e2005-04-16 15:20:36 -070036 return 0;
Yinghai Luc7e79642008-07-25 02:17:33 -070037}
38static inline unsigned long check_apicid_present(int bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -070039{
40 return physid_isset(bit, phys_cpu_present_map);
41}
42
43#define apicid_cluster(apicid) (apicid & 0xF0)
44
45static inline unsigned long calculate_ldr(int cpu)
46{
47 unsigned long id;
48 id = xapic_phys_to_log_apicid(cpu);
49 return (SET_APIC_LOGICAL_ID(id));
50}
51
52/*
53 * Set up the logical destination ID.
54 *
55 * Intel recommends to set DFR, LdR and TPR before enabling
56 * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
57 * document number 292116). So here it goes...
58 */
Yinghai Lub5fe3632008-11-18 08:14:14 -080059static inline void init_apic_ldr_cluster(void)
60{
61 unsigned long val;
62 int cpu = smp_processor_id();
63
64 apic_write(APIC_DFR, APIC_DFR_VALUE_CLUSTER);
65 val = calculate_ldr(cpu);
66 apic_write(APIC_LDR, val);
67}
68
Linus Torvalds1da177e2005-04-16 15:20:36 -070069static inline void init_apic_ldr(void)
70{
71 unsigned long val;
72 int cpu = smp_processor_id();
73
Maciej W. Rozycki593f4a72008-07-16 19:15:30 +010074 apic_write(APIC_DFR, APIC_DFR_VALUE);
Linus Torvalds1da177e2005-04-16 15:20:36 -070075 val = calculate_ldr(cpu);
Maciej W. Rozycki593f4a72008-07-16 19:15:30 +010076 apic_write(APIC_LDR, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -070077}
78
Linus Torvalds1da177e2005-04-16 15:20:36 -070079extern int apic_version [MAX_APICS];
Ingo Molnar3c43f032007-05-02 19:27:04 +020080static inline void setup_apic_routing(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070081{
Glauber de Oliveira Costacbe879f2008-03-19 14:25:19 -030082 int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id());
Mike Travise7986732008-12-16 17:33:52 -080083 printk("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n",
Yinghai Luc7e79642008-07-25 02:17:33 -070084 (apic_version[apic] == 0x14) ?
Mike Travise7986732008-12-16 17:33:52 -080085 "Physical Cluster" : "Logical Cluster",
Ingo Molnar0a9cc202009-01-28 04:30:40 +010086 nr_ioapics, cpus_addr(*es7000_target_cpus())[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -070087}
88
89static inline int multi_timer_check(int apic, int irq)
90{
91 return 0;
92}
93
94static inline int apicid_to_node(int logical_apicid)
95{
96 return 0;
97}
98
99
100static inline int cpu_present_to_apicid(int mps_cpu)
101{
102 if (!mps_cpu)
103 return boot_cpu_physical_apicid;
Mike Travise7986732008-12-16 17:33:52 -0800104 else if (mps_cpu < nr_cpu_ids)
Glauber de Oliveira Costacbe879f2008-03-19 14:25:19 -0300105 return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 else
107 return BAD_APICID;
108}
109
110static inline physid_mask_t apicid_to_cpu_present(int phys_apicid)
111{
112 static int id = 0;
113 physid_mask_t mask;
114 mask = physid_mask_of_physid(id);
115 ++id;
116 return mask;
117}
118
119extern u8 cpu_2_logical_apicid[];
120/* Mapping from cpu number to logical apicid */
121static inline int cpu_to_logical_apicid(int cpu)
122{
Andi Kleen874c4fe2006-09-26 10:52:26 +0200123#ifdef CONFIG_SMP
Mike Travise7986732008-12-16 17:33:52 -0800124 if (cpu >= nr_cpu_ids)
125 return BAD_APICID;
126 return (int)cpu_2_logical_apicid[cpu];
Andi Kleen874c4fe2006-09-26 10:52:26 +0200127#else
128 return logical_smp_processor_id();
129#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130}
131
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map)
133{
134 /* For clustered we don't have a good way to do this yet - hack */
135 return physids_promote(0xff);
136}
137
138
139static inline void setup_portio_remap(void)
140{
141}
142
143extern unsigned int boot_cpu_physical_apicid;
144static inline int check_phys_apicid_present(int cpu_physical_apicid)
145{
Yinghai Lu4c9961d2008-07-11 18:44:16 -0700146 boot_cpu_physical_apicid = read_apic_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147 return (1);
148}
149
Mike Travise7986732008-12-16 17:33:52 -0800150static inline unsigned int
151cpu_mask_to_apicid_cluster(const struct cpumask *cpumask)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152{
153 int num_bits_set;
154 int cpus_found = 0;
155 int cpu;
Yinghai Luc7e79642008-07-25 02:17:33 -0700156 int apicid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157
Mike Travise7986732008-12-16 17:33:52 -0800158 num_bits_set = cpumask_weight(cpumask);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159 /* Return id to all */
Mike Travis96289372008-12-31 18:08:46 -0800160 if (num_bits_set == nr_cpu_ids)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 return 0xFF;
Yinghai Luc7e79642008-07-25 02:17:33 -0700162 /*
163 * The cpus in the mask must all be on the apic cluster. If are not
Ingo Molnarfe402e12009-01-28 04:32:51 +0100164 * on the same apicid cluster return default value of target_cpus():
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 */
Mike Travise7986732008-12-16 17:33:52 -0800166 cpu = cpumask_first(cpumask);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 apicid = cpu_to_logical_apicid(cpu);
168 while (cpus_found < num_bits_set) {
Mike Travise7986732008-12-16 17:33:52 -0800169 if (cpumask_test_cpu(cpu, cpumask)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 int new_apicid = cpu_to_logical_apicid(cpu);
Yinghai Luc7e79642008-07-25 02:17:33 -0700171 if (apicid_cluster(apicid) !=
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 apicid_cluster(new_apicid)){
Harvey Harrisond5c003b2008-10-15 22:01:24 -0700173 printk ("%s: Not a valid mask!\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 return 0xFF;
Yinghai Lub5fe3632008-11-18 08:14:14 -0800175 }
176 apicid = new_apicid;
177 cpus_found++;
178 }
179 cpu++;
180 }
181 return apicid;
182}
183
Mike Travise7986732008-12-16 17:33:52 -0800184static inline unsigned int cpu_mask_to_apicid(const cpumask_t *cpumask)
Yinghai Lub5fe3632008-11-18 08:14:14 -0800185{
186 int num_bits_set;
187 int cpus_found = 0;
188 int cpu;
189 int apicid;
190
Mike Travise7986732008-12-16 17:33:52 -0800191 num_bits_set = cpus_weight(*cpumask);
Yinghai Lub5fe3632008-11-18 08:14:14 -0800192 /* Return id to all */
Mike Travis96289372008-12-31 18:08:46 -0800193 if (num_bits_set == nr_cpu_ids)
Yinghai Lub5fe3632008-11-18 08:14:14 -0800194 return cpu_to_logical_apicid(0);
195 /*
196 * The cpus in the mask must all be on the apic cluster. If are not
Ingo Molnarfe402e12009-01-28 04:32:51 +0100197 * on the same apicid cluster return default value of target_cpus():
Yinghai Lub5fe3632008-11-18 08:14:14 -0800198 */
Mike Travise7986732008-12-16 17:33:52 -0800199 cpu = first_cpu(*cpumask);
Yinghai Lub5fe3632008-11-18 08:14:14 -0800200 apicid = cpu_to_logical_apicid(cpu);
201 while (cpus_found < num_bits_set) {
Mike Travise7986732008-12-16 17:33:52 -0800202 if (cpu_isset(cpu, *cpumask)) {
Yinghai Lub5fe3632008-11-18 08:14:14 -0800203 int new_apicid = cpu_to_logical_apicid(cpu);
204 if (apicid_cluster(apicid) !=
205 apicid_cluster(new_apicid)){
206 printk ("%s: Not a valid mask!\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207 return cpu_to_logical_apicid(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 }
209 apicid = new_apicid;
210 cpus_found++;
211 }
212 cpu++;
213 }
214 return apicid;
215}
216
Mike Travisa775a382008-12-17 15:21:39 -0800217
218static inline unsigned int cpu_mask_to_apicid_and(const struct cpumask *inmask,
Mike Travis6eeb7c52008-12-16 17:33:55 -0800219 const struct cpumask *andmask)
Mike Travis95d313c2008-12-16 17:33:54 -0800220{
Mike Travisa775a382008-12-17 15:21:39 -0800221 int apicid = cpu_to_logical_apicid(0);
222 cpumask_var_t cpumask;
223
224 if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
225 return apicid;
226
227 cpumask_and(cpumask, inmask, andmask);
228 cpumask_and(cpumask, cpumask, cpu_online_mask);
Mike Travis96289372008-12-31 18:08:46 -0800229 apicid = cpu_mask_to_apicid(cpumask);
Mike Travis95d313c2008-12-16 17:33:54 -0800230
Mike Travisa775a382008-12-17 15:21:39 -0800231 free_cpumask_var(cpumask);
Mike Travis95d313c2008-12-16 17:33:54 -0800232 return apicid;
233}
234
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
236{
237 return cpuid_apic >> index_msb;
238}
239
Yinghai Luc7e79642008-07-25 02:17:33 -0700240#endif /* __ASM_ES7000_APIC_H */