debuggers.hg

view xen/arch/ia64/linux-xen/iosapic.c @ 17977:11318234588e

[IA64] remove some #ifndef XEN using empty headerfiles.

move mm_numa.c from linux-xen to linux because now mm_numa.c is
identical to linux files.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Thu Jun 19 12:48:04 2008 +0900 (2008-06-19)
parents 2b0cbf3ef83f
children af8eaa3cf782
line source
1 /*
2 * I/O SAPIC support.
3 *
4 * Copyright (C) 1999 Intel Corp.
5 * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
6 * Copyright (C) 2000-2002 J.I. Lee <jung-ik.lee@intel.com>
7 * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co.
8 * David Mosberger-Tang <davidm@hpl.hp.com>
9 * Copyright (C) 1999 VA Linux Systems
10 * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
11 *
12 * 00/04/19 D. Mosberger Rewritten to mirror more closely the x86 I/O APIC code.
13 * In particular, we now have separate handlers for edge
14 * and level triggered interrupts.
15 * 00/10/27 Asit Mallick, Goutham Rao <goutham.rao@intel.com> IRQ vector allocation
16 * PCI to vector mapping, shared PCI interrupts.
17 * 00/10/27 D. Mosberger Document things a bit more to make them more understandable.
18 * Clean up much of the old IOSAPIC cruft.
19 * 01/07/27 J.I. Lee PCI irq routing, Platform/Legacy interrupts and fixes for
20 * ACPI S5(SoftOff) support.
21 * 02/01/23 J.I. Lee iosapic pgm fixes for PCI irq routing from _PRT
22 * 02/01/07 E. Focht <efocht@ess.nec.de> Redirectable interrupt vectors in
23 * iosapic_set_affinity(), initializations for
24 * /proc/irq/#/smp_affinity
25 * 02/04/02 P. Diefenbaugh Cleaned up ACPI PCI IRQ routing.
26 * 02/04/18 J.I. Lee bug fix in iosapic_init_pci_irq
27 * 02/04/30 J.I. Lee bug fix in find_iosapic to fix ACPI PCI IRQ to IOSAPIC mapping
28 * error
29 * 02/07/29 T. Kochi Allocate interrupt vectors dynamically
30 * 02/08/04 T. Kochi Cleaned up terminology (irq, global system interrupt, vector, etc.)
31 * 02/09/20 D. Mosberger Simplified by taking advantage of ACPI's pci_irq code.
32 * 03/02/19 B. Helgaas Make pcat_compat system-wide, not per-IOSAPIC.
33 * Remove iosapic_address & gsi_base from external interfaces.
34 * Rationalize __init/__devinit attributes.
35 * 04/12/04 Ashok Raj <ashok.raj@intel.com> Intel Corporation 2004
36 * Updated to work with irq migration necessary for CPU Hotplug
37 */
38 /*
39 * Here is what the interrupt logic between a PCI device and the kernel looks like:
40 *
41 * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC, INTD). The
42 * device is uniquely identified by its bus--, and slot-number (the function
43 * number does not matter here because all functions share the same interrupt
44 * lines).
45 *
46 * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC controller.
47 * Multiple interrupt lines may have to share the same IOSAPIC pin (if they're level
48 * triggered and use the same polarity). Each interrupt line has a unique Global
49 * System Interrupt (GSI) number which can be calculated as the sum of the controller's
50 * base GSI number and the IOSAPIC pin number to which the line connects.
51 *
52 * (3) The IOSAPIC uses an internal routing table entries (RTEs) to map the IOSAPIC pin
53 * into the IA-64 interrupt vector. This interrupt vector is then sent to the CPU.
54 *
55 * (4) The kernel recognizes an interrupt as an IRQ. The IRQ interface is used as
56 * architecture-independent interrupt handling mechanism in Linux. As an
57 * IRQ is a number, we have to have IA-64 interrupt vector number <-> IRQ number
58 * mapping. On smaller systems, we use one-to-one mapping between IA-64 vector and
59 * IRQ. A platform can implement platform_irq_to_vector(irq) and
60 * platform_local_vector_to_irq(vector) APIs to differentiate the mapping.
61 * Please see also include/asm-ia64/hw_irq.h for those APIs.
62 *
63 * To sum up, there are three levels of mappings involved:
64 *
65 * PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ
66 *
67 * Note: The term "IRQ" is loosely used everywhere in Linux kernel to describe interrupts.
68 * Now we use "IRQ" only for Linux IRQ's. ISA IRQ (isa_irq) is the only exception in this
69 * source code.
70 */
71 #include <linux/config.h>
73 #include <linux/acpi.h>
74 #include <linux/init.h>
75 #include <linux/irq.h>
76 #include <linux/kernel.h>
77 #include <linux/list.h>
78 #include <linux/pci.h>
79 #ifdef XEN
80 #include <xen/errno.h>
81 #endif
82 #include <linux/smp.h>
83 #include <linux/smp_lock.h>
84 #include <linux/string.h>
85 #include <linux/bootmem.h>
87 #include <asm/delay.h>
88 #include <asm/hw_irq.h>
89 #include <asm/io.h>
90 #include <asm/iosapic.h>
91 #include <asm/machvec.h>
92 #include <asm/processor.h>
93 #include <asm/ptrace.h>
94 #include <asm/system.h>
97 #undef DEBUG_INTERRUPT_ROUTING
99 #ifdef DEBUG_INTERRUPT_ROUTING
100 #define DBG(fmt...) printk(fmt)
101 #else
102 #define DBG(fmt...)
103 #endif
105 #define NR_PREALLOCATE_RTE_ENTRIES (PAGE_SIZE / sizeof(struct iosapic_rte_info))
106 #define RTE_PREALLOCATED (1)
108 static DEFINE_SPINLOCK(iosapic_lock);
110 /* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */
112 struct iosapic_rte_info {
113 struct list_head rte_list; /* node in list of RTEs sharing the same vector */
114 char __iomem *addr; /* base address of IOSAPIC */
115 unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */
116 char rte_index; /* IOSAPIC RTE index */
117 int refcnt; /* reference counter */
118 unsigned int flags; /* flags */
119 } ____cacheline_aligned;
121 static struct iosapic_intr_info {
122 struct list_head rtes; /* RTEs using this vector (empty => not an IOSAPIC interrupt) */
123 int count; /* # of RTEs that shares this vector */
124 u32 low32; /* current value of low word of Redirection table entry */
125 unsigned int dest; /* destination CPU physical ID */
126 unsigned char dmode : 3; /* delivery mode (see iosapic.h) */
127 unsigned char polarity: 1; /* interrupt polarity (see iosapic.h) */
128 unsigned char trigger : 1; /* trigger mode (see iosapic.h) */
129 } iosapic_intr_info[IA64_NUM_VECTORS];
131 static struct iosapic {
132 char __iomem *addr; /* base address of IOSAPIC */
133 unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */
134 unsigned short num_rte; /* number of RTE in this IOSAPIC */
135 int rtes_inuse; /* # of RTEs in use on this IOSAPIC */
136 #ifdef CONFIG_NUMA
137 unsigned short node; /* numa node association via pxm */
138 #endif
139 } iosapic_lists[NR_IOSAPICS];
141 static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */
143 static int iosapic_kmalloc_ok;
144 static LIST_HEAD(free_rte_list);
146 /*
147 * Find an IOSAPIC associated with a GSI
148 */
149 static inline int
150 find_iosapic (unsigned int gsi)
151 {
152 int i;
154 for (i = 0; i < NR_IOSAPICS; i++) {
155 if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte)
156 return i;
157 }
159 return -1;
160 }
162 static inline int
163 _gsi_to_vector (unsigned int gsi)
164 {
165 struct iosapic_intr_info *info;
166 struct iosapic_rte_info *rte;
168 for (info = iosapic_intr_info; info < iosapic_intr_info + IA64_NUM_VECTORS; ++info)
169 list_for_each_entry(rte, &info->rtes, rte_list)
170 if (rte->gsi_base + rte->rte_index == gsi)
171 return info - iosapic_intr_info;
172 return -1;
173 }
175 /*
176 * Translate GSI number to the corresponding IA-64 interrupt vector. If no
177 * entry exists, return -1.
178 */
179 inline int
180 gsi_to_vector (unsigned int gsi)
181 {
182 return _gsi_to_vector(gsi);
183 }
185 int
186 gsi_to_irq (unsigned int gsi)
187 {
188 unsigned long flags;
189 int irq;
190 /*
191 * XXX fix me: this assumes an identity mapping vetween IA-64 vector and Linux irq
192 * numbers...
193 */
194 spin_lock_irqsave(&iosapic_lock, flags);
195 {
196 irq = _gsi_to_vector(gsi);
197 }
198 spin_unlock_irqrestore(&iosapic_lock, flags);
200 return irq;
201 }
203 static struct iosapic_rte_info *gsi_vector_to_rte(unsigned int gsi, unsigned int vec)
204 {
205 struct iosapic_rte_info *rte;
207 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list)
208 if (rte->gsi_base + rte->rte_index == gsi)
209 return rte;
210 return NULL;
211 }
213 static void
214 set_rte (unsigned int gsi, unsigned int vector, unsigned int dest, int mask)
215 {
216 unsigned long pol, trigger, dmode;
217 u32 low32, high32;
218 char __iomem *addr;
219 int rte_index;
220 char redir;
221 struct iosapic_rte_info *rte;
223 DBG(KERN_DEBUG"IOSAPIC: routing vector %d to 0x%x\n", vector, dest);
225 rte = gsi_vector_to_rte(gsi, vector);
226 if (!rte)
227 return; /* not an IOSAPIC interrupt */
229 rte_index = rte->rte_index;
230 addr = rte->addr;
231 pol = iosapic_intr_info[vector].polarity;
232 trigger = iosapic_intr_info[vector].trigger;
233 dmode = iosapic_intr_info[vector].dmode;
235 redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0;
237 #ifdef CONFIG_SMP
238 {
239 unsigned int irq;
241 for (irq = 0; irq < NR_IRQS; ++irq)
242 if (irq_to_vector(irq) == vector) {
243 set_irq_affinity_info(irq, (int)(dest & 0xffff), redir);
244 break;
245 }
246 }
247 #endif
249 low32 = ((pol << IOSAPIC_POLARITY_SHIFT) |
250 (trigger << IOSAPIC_TRIGGER_SHIFT) |
251 (dmode << IOSAPIC_DELIVERY_SHIFT) |
252 ((mask ? 1 : 0) << IOSAPIC_MASK_SHIFT) |
253 vector);
255 /* dest contains both id and eid */
256 high32 = (dest << IOSAPIC_DEST_SHIFT);
258 iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32);
259 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
260 iosapic_intr_info[vector].low32 = low32;
261 iosapic_intr_info[vector].dest = dest;
262 }
264 static void
265 nop (unsigned int vector)
266 {
267 /* do nothing... */
268 }
270 void
271 kexec_disable_iosapic(void)
272 {
273 struct iosapic_intr_info *info;
274 struct iosapic_rte_info *rte;
275 u8 vec = 0;
276 for (info = iosapic_intr_info; info <
277 iosapic_intr_info + IA64_NUM_VECTORS; ++info, ++vec) {
278 list_for_each_entry(rte, &info->rtes,
279 rte_list) {
280 iosapic_write(rte->addr,
281 IOSAPIC_RTE_LOW(rte->rte_index),
282 IOSAPIC_MASK|vec);
283 iosapic_eoi(rte->addr, vec);
284 }
285 }
286 }
288 static void
289 mask_irq (unsigned int irq)
290 {
291 unsigned long flags;
292 char __iomem *addr;
293 u32 low32;
294 int rte_index;
295 ia64_vector vec = irq_to_vector(irq);
296 struct iosapic_rte_info *rte;
298 if (list_empty(&iosapic_intr_info[vec].rtes))
299 return; /* not an IOSAPIC interrupt! */
301 spin_lock_irqsave(&iosapic_lock, flags);
302 {
303 /* set only the mask bit */
304 low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK;
305 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) {
306 addr = rte->addr;
307 rte_index = rte->rte_index;
308 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
309 }
310 }
311 spin_unlock_irqrestore(&iosapic_lock, flags);
312 }
314 static void
315 unmask_irq (unsigned int irq)
316 {
317 unsigned long flags;
318 char __iomem *addr;
319 u32 low32;
320 int rte_index;
321 ia64_vector vec = irq_to_vector(irq);
322 struct iosapic_rte_info *rte;
324 if (list_empty(&iosapic_intr_info[vec].rtes))
325 return; /* not an IOSAPIC interrupt! */
327 spin_lock_irqsave(&iosapic_lock, flags);
328 {
329 low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK;
330 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) {
331 addr = rte->addr;
332 rte_index = rte->rte_index;
333 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
334 }
335 }
336 spin_unlock_irqrestore(&iosapic_lock, flags);
337 }
340 static void
341 iosapic_set_affinity (unsigned int irq, cpumask_t mask)
342 {
343 #ifdef CONFIG_SMP
344 unsigned long flags;
345 u32 high32, low32;
346 int dest, rte_index;
347 char __iomem *addr;
348 int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0;
349 ia64_vector vec;
350 struct iosapic_rte_info *rte;
352 irq &= (~IA64_IRQ_REDIRECTED);
353 vec = irq_to_vector(irq);
355 if (cpus_empty(mask))
356 return;
358 dest = cpu_physical_id(first_cpu(mask));
360 if (list_empty(&iosapic_intr_info[vec].rtes))
361 return; /* not an IOSAPIC interrupt */
363 set_irq_affinity_info(irq, dest, redir);
365 /* dest contains both id and eid */
366 high32 = dest << IOSAPIC_DEST_SHIFT;
368 spin_lock_irqsave(&iosapic_lock, flags);
369 {
370 low32 = iosapic_intr_info[vec].low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT);
372 if (redir)
373 /* change delivery mode to lowest priority */
374 low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT);
375 else
376 /* change delivery mode to fixed */
377 low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
379 iosapic_intr_info[vec].low32 = low32;
380 iosapic_intr_info[vec].dest = dest;
381 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) {
382 addr = rte->addr;
383 rte_index = rte->rte_index;
384 iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32);
385 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
386 }
387 }
388 spin_unlock_irqrestore(&iosapic_lock, flags);
389 #endif
390 }
392 /*
393 * Handlers for level-triggered interrupts.
394 */
396 static unsigned int
397 iosapic_startup_level_irq (unsigned int irq)
398 {
399 unmask_irq(irq);
400 return 0;
401 }
403 static void
404 iosapic_end_level_irq (unsigned int irq)
405 {
406 ia64_vector vec = irq_to_vector(irq);
407 struct iosapic_rte_info *rte;
409 move_irq(irq);
410 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list)
411 iosapic_eoi(rte->addr, vec);
412 }
414 #define iosapic_shutdown_level_irq mask_irq
415 #define iosapic_enable_level_irq unmask_irq
416 #define iosapic_disable_level_irq mask_irq
417 #define iosapic_ack_level_irq nop
419 struct hw_interrupt_type irq_type_iosapic_level = {
420 .typename = "IO-SAPIC-level",
421 .startup = iosapic_startup_level_irq,
422 .shutdown = iosapic_shutdown_level_irq,
423 .enable = iosapic_enable_level_irq,
424 .disable = iosapic_disable_level_irq,
425 .ack = iosapic_ack_level_irq,
426 .end = iosapic_end_level_irq,
427 .set_affinity = iosapic_set_affinity
428 };
430 /*
431 * Handlers for edge-triggered interrupts.
432 */
434 static unsigned int
435 iosapic_startup_edge_irq (unsigned int irq)
436 {
437 unmask_irq(irq);
438 /*
439 * IOSAPIC simply drops interrupts pended while the
440 * corresponding pin was masked, so we can't know if an
441 * interrupt is pending already. Let's hope not...
442 */
443 return 0;
444 }
446 static void
447 iosapic_ack_edge_irq (unsigned int irq)
448 {
449 irq_desc_t *idesc = irq_descp(irq);
451 move_irq(irq);
452 /*
453 * Once we have recorded IRQ_PENDING already, we can mask the
454 * interrupt for real. This prevents IRQ storms from unhandled
455 * devices.
456 */
457 if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) == (IRQ_PENDING|IRQ_DISABLED))
458 mask_irq(irq);
459 }
461 #define iosapic_enable_edge_irq unmask_irq
462 #define iosapic_disable_edge_irq nop
463 #define iosapic_end_edge_irq nop
465 struct hw_interrupt_type irq_type_iosapic_edge = {
466 .typename = "IO-SAPIC-edge",
467 .startup = iosapic_startup_edge_irq,
468 .shutdown = iosapic_disable_edge_irq,
469 .enable = iosapic_enable_edge_irq,
470 .disable = iosapic_disable_edge_irq,
471 .ack = iosapic_ack_edge_irq,
472 .end = iosapic_end_edge_irq,
473 .set_affinity = iosapic_set_affinity
474 };
476 unsigned int
477 iosapic_version (char __iomem *addr)
478 {
479 /*
480 * IOSAPIC Version Register return 32 bit structure like:
481 * {
482 * unsigned int version : 8;
483 * unsigned int reserved1 : 8;
484 * unsigned int max_redir : 8;
485 * unsigned int reserved2 : 8;
486 * }
487 */
488 return iosapic_read(addr, IOSAPIC_VERSION);
489 }
491 static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long pol)
492 {
493 int i, vector = -1, min_count = -1;
494 struct iosapic_intr_info *info;
496 /*
497 * shared vectors for edge-triggered interrupts are not
498 * supported yet
499 */
500 if (trigger == IOSAPIC_EDGE)
501 return -1;
503 for (i = IA64_FIRST_DEVICE_VECTOR; i <= IA64_LAST_DEVICE_VECTOR; i++) {
504 info = &iosapic_intr_info[i];
505 if (info->trigger == trigger && info->polarity == pol &&
506 (info->dmode == IOSAPIC_FIXED || info->dmode == IOSAPIC_LOWEST_PRIORITY)) {
507 if (min_count == -1 || info->count < min_count) {
508 vector = i;
509 min_count = info->count;
510 }
511 }
512 }
514 return vector;
515 }
517 /*
518 * if the given vector is already owned by other,
519 * assign a new vector for the other and make the vector available
520 */
521 static void __init
522 iosapic_reassign_vector (int vector)
523 {
524 int new_vector;
526 if (!list_empty(&iosapic_intr_info[vector].rtes)) {
527 new_vector = assign_irq_vector(AUTO_ASSIGN);
528 if (new_vector < 0)
529 panic("%s: out of interrupt vectors!\n", __FUNCTION__);
530 printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector);
531 memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
532 sizeof(struct iosapic_intr_info));
533 INIT_LIST_HEAD(&iosapic_intr_info[new_vector].rtes);
534 list_move(iosapic_intr_info[vector].rtes.next, &iosapic_intr_info[new_vector].rtes);
535 memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info));
536 iosapic_intr_info[vector].low32 = IOSAPIC_MASK;
537 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes);
538 }
539 }
541 static struct iosapic_rte_info *iosapic_alloc_rte (void)
542 {
543 int i;
544 struct iosapic_rte_info *rte;
545 int preallocated = 0;
547 if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) {
548 #ifdef XEN
549 rte = xmalloc_bytes(sizeof(struct iosapic_rte_info) * NR_PREALLOCATE_RTE_ENTRIES);
550 #else
551 rte = alloc_bootmem(sizeof(struct iosapic_rte_info) * NR_PREALLOCATE_RTE_ENTRIES);
552 #endif
553 if (!rte)
554 return NULL;
555 for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++)
556 list_add(&rte->rte_list, &free_rte_list);
557 }
559 if (!list_empty(&free_rte_list)) {
560 rte = list_entry(free_rte_list.next, struct iosapic_rte_info, rte_list);
561 list_del(&rte->rte_list);
562 preallocated++;
563 } else {
564 rte = kmalloc(sizeof(struct iosapic_rte_info), GFP_ATOMIC);
565 if (!rte)
566 return NULL;
567 }
569 memset(rte, 0, sizeof(struct iosapic_rte_info));
570 if (preallocated)
571 rte->flags |= RTE_PREALLOCATED;
573 return rte;
574 }
576 static void iosapic_free_rte (struct iosapic_rte_info *rte)
577 {
578 if (rte->flags & RTE_PREALLOCATED)
579 list_add_tail(&rte->rte_list, &free_rte_list);
580 else
581 kfree(rte);
582 }
584 static inline int vector_is_shared (int vector)
585 {
586 return (iosapic_intr_info[vector].count > 1);
587 }
589 static int
590 register_intr (unsigned int gsi, int vector, unsigned char delivery,
591 unsigned long polarity, unsigned long trigger)
592 {
593 irq_desc_t *idesc;
594 struct hw_interrupt_type *irq_type;
595 int rte_index;
596 int index;
597 unsigned long gsi_base;
598 void __iomem *iosapic_address;
599 struct iosapic_rte_info *rte;
601 index = find_iosapic(gsi);
602 if (index < 0) {
603 printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", __FUNCTION__, gsi);
604 return -ENODEV;
605 }
607 iosapic_address = iosapic_lists[index].addr;
608 gsi_base = iosapic_lists[index].gsi_base;
610 rte = gsi_vector_to_rte(gsi, vector);
611 if (!rte) {
612 rte = iosapic_alloc_rte();
613 if (!rte) {
614 printk(KERN_WARNING "%s: cannot allocate memory\n", __FUNCTION__);
615 return -ENOMEM;
616 }
618 rte_index = gsi - gsi_base;
619 rte->rte_index = rte_index;
620 rte->addr = iosapic_address;
621 rte->gsi_base = gsi_base;
622 rte->refcnt++;
623 list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes);
624 iosapic_intr_info[vector].count++;
625 iosapic_lists[index].rtes_inuse++;
626 }
627 else if (vector_is_shared(vector)) {
628 struct iosapic_intr_info *info = &iosapic_intr_info[vector];
629 if (info->trigger != trigger || info->polarity != polarity) {
630 printk (KERN_WARNING "%s: cannot override the interrupt\n", __FUNCTION__);
631 return -EINVAL;
632 }
633 }
635 iosapic_intr_info[vector].polarity = polarity;
636 iosapic_intr_info[vector].dmode = delivery;
637 iosapic_intr_info[vector].trigger = trigger;
639 if (trigger == IOSAPIC_EDGE)
640 irq_type = &irq_type_iosapic_edge;
641 else
642 irq_type = &irq_type_iosapic_level;
644 idesc = irq_descp(vector);
645 if (idesc->handler != irq_type) {
646 if (idesc->handler != &no_irq_type)
647 printk(KERN_WARNING "%s: changing vector %d from %s to %s\n",
648 __FUNCTION__, vector, idesc->handler->typename, irq_type->typename);
649 idesc->handler = irq_type;
650 }
651 return 0;
652 }
654 static unsigned int
655 get_target_cpu (unsigned int gsi, int vector)
656 {
657 #ifdef CONFIG_SMP
658 static int cpu = -1;
660 /*
661 * In case of vector shared by multiple RTEs, all RTEs that
662 * share the vector need to use the same destination CPU.
663 */
664 if (!list_empty(&iosapic_intr_info[vector].rtes))
665 return iosapic_intr_info[vector].dest;
667 /*
668 * If the platform supports redirection via XTP, let it
669 * distribute interrupts.
670 */
671 if (smp_int_redirect & SMP_IRQ_REDIRECTION)
672 return cpu_physical_id(smp_processor_id());
674 /*
675 * Some interrupts (ACPI SCI, for instance) are registered
676 * before the BSP is marked as online.
677 */
678 if (!cpu_online(smp_processor_id()))
679 return cpu_physical_id(smp_processor_id());
681 #ifdef CONFIG_NUMA
682 {
683 int num_cpus, cpu_index, iosapic_index, numa_cpu, i = 0;
684 cpumask_t cpu_mask;
686 iosapic_index = find_iosapic(gsi);
687 if (iosapic_index < 0 ||
688 iosapic_lists[iosapic_index].node == MAX_NUMNODES)
689 goto skip_numa_setup;
691 cpu_mask = node_to_cpumask(iosapic_lists[iosapic_index].node);
693 for_each_cpu_mask(numa_cpu, cpu_mask) {
694 if (!cpu_online(numa_cpu))
695 cpu_clear(numa_cpu, cpu_mask);
696 }
698 num_cpus = cpus_weight(cpu_mask);
700 if (!num_cpus)
701 goto skip_numa_setup;
703 /* Use vector assigment to distribute across cpus in node */
704 cpu_index = vector % num_cpus;
706 for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++)
707 numa_cpu = next_cpu(numa_cpu, cpu_mask);
709 if (numa_cpu != NR_CPUS)
710 return cpu_physical_id(numa_cpu);
711 }
712 skip_numa_setup:
713 #endif
714 /*
715 * Otherwise, round-robin interrupt vectors across all the
716 * processors. (It'd be nice if we could be smarter in the
717 * case of NUMA.)
718 */
719 do {
720 if (++cpu >= NR_CPUS)
721 cpu = 0;
722 } while (!cpu_online(cpu));
724 return cpu_physical_id(cpu);
725 #else
726 return cpu_physical_id(smp_processor_id());
727 #endif
728 }
730 /*
731 * ACPI can describe IOSAPIC interrupts via static tables and namespace
732 * methods. This provides an interface to register those interrupts and
733 * program the IOSAPIC RTE.
734 */
735 int
736 iosapic_register_intr (unsigned int gsi,
737 unsigned long polarity, unsigned long trigger)
738 {
739 int vector, mask = 1, err;
740 unsigned int dest;
741 unsigned long flags;
742 struct iosapic_rte_info *rte;
743 u32 low32;
744 again:
745 /*
746 * If this GSI has already been registered (i.e., it's a
747 * shared interrupt, or we lost a race to register it),
748 * don't touch the RTE.
749 */
750 spin_lock_irqsave(&iosapic_lock, flags);
751 {
752 vector = gsi_to_vector(gsi);
753 if (vector > 0) {
754 rte = gsi_vector_to_rte(gsi, vector);
755 rte->refcnt++;
756 spin_unlock_irqrestore(&iosapic_lock, flags);
757 return vector;
758 }
759 }
760 spin_unlock_irqrestore(&iosapic_lock, flags);
762 /* If vector is running out, we try to find a sharable vector */
763 vector = assign_irq_vector(AUTO_ASSIGN);
764 if (vector < 0) {
765 vector = iosapic_find_sharable_vector(trigger, polarity);
766 if (vector < 0)
767 return -ENOSPC;
768 }
770 spin_lock_irqsave(&irq_descp(vector)->lock, flags);
771 spin_lock(&iosapic_lock);
772 {
773 if (gsi_to_vector(gsi) > 0) {
774 if (list_empty(&iosapic_intr_info[vector].rtes))
775 free_irq_vector(vector);
776 spin_unlock(&iosapic_lock);
777 spin_unlock_irqrestore(&irq_descp(vector)->lock, flags);
778 goto again;
779 }
781 dest = get_target_cpu(gsi, vector);
782 err = register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
783 polarity, trigger);
784 if (err < 0) {
785 spin_unlock(&iosapic_lock);
786 spin_unlock_irqrestore(&irq_descp(vector)->lock, flags);
787 return err;
788 }
790 /*
791 * If the vector is shared and already unmasked for
792 * other interrupt sources, don't mask it.
793 */
794 low32 = iosapic_intr_info[vector].low32;
795 if (vector_is_shared(vector) && !(low32 & IOSAPIC_MASK))
796 mask = 0;
797 set_rte(gsi, vector, dest, mask);
798 }
799 spin_unlock(&iosapic_lock);
800 spin_unlock_irqrestore(&irq_descp(vector)->lock, flags);
802 printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n",
803 gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
804 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
805 cpu_logical_id(dest), dest, vector);
807 return vector;
808 }
810 void
811 iosapic_unregister_intr (unsigned int gsi)
812 {
813 unsigned long flags;
814 int irq, vector, index;
815 irq_desc_t *idesc;
816 u32 low32;
817 unsigned long trigger, polarity;
818 unsigned int dest;
819 struct iosapic_rte_info *rte;
821 /*
822 * If the irq associated with the gsi is not found,
823 * iosapic_unregister_intr() is unbalanced. We need to check
824 * this again after getting locks.
825 */
826 irq = gsi_to_irq(gsi);
827 if (irq < 0) {
828 printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi);
829 WARN_ON(1);
830 return;
831 }
832 vector = irq_to_vector(irq);
834 idesc = irq_descp(irq);
835 spin_lock_irqsave(&idesc->lock, flags);
836 spin_lock(&iosapic_lock);
837 {
838 if ((rte = gsi_vector_to_rte(gsi, vector)) == NULL) {
839 printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi);
840 WARN_ON(1);
841 goto out;
842 }
844 if (--rte->refcnt > 0)
845 goto out;
847 /* Mask the interrupt */
848 low32 = iosapic_intr_info[vector].low32 | IOSAPIC_MASK;
849 iosapic_write(rte->addr, IOSAPIC_RTE_LOW(rte->rte_index), low32);
851 /* Remove the rte entry from the list */
852 list_del(&rte->rte_list);
853 iosapic_intr_info[vector].count--;
854 iosapic_free_rte(rte);
855 index = find_iosapic(gsi);
856 iosapic_lists[index].rtes_inuse--;
857 WARN_ON(iosapic_lists[index].rtes_inuse < 0);
859 trigger = iosapic_intr_info[vector].trigger;
860 polarity = iosapic_intr_info[vector].polarity;
861 dest = iosapic_intr_info[vector].dest;
862 printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d unregistered\n",
863 gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
864 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
865 cpu_logical_id(dest), dest, vector);
867 if (list_empty(&iosapic_intr_info[vector].rtes)) {
868 /* Sanity check */
869 BUG_ON(iosapic_intr_info[vector].count);
871 /* Clear the interrupt controller descriptor */
872 idesc->handler = &no_irq_type;
874 /* Clear the interrupt information */
875 memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info));
876 iosapic_intr_info[vector].low32 |= IOSAPIC_MASK;
877 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes);
879 if (idesc->action) {
880 printk(KERN_ERR "interrupt handlers still exist on IRQ %u\n", irq);
881 WARN_ON(1);
882 }
884 /* Free the interrupt vector */
885 free_irq_vector(vector);
886 }
887 }
888 out:
889 spin_unlock(&iosapic_lock);
890 spin_unlock_irqrestore(&idesc->lock, flags);
891 }
893 /*
894 * ACPI calls this when it finds an entry for a platform interrupt.
895 * Note that the irq_base and IOSAPIC address must be set in iosapic_init().
896 */
897 int __init
898 iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
899 int iosapic_vector, u16 eid, u16 id,
900 unsigned long polarity, unsigned long trigger)
901 {
902 static const char * const name[] = {"unknown", "PMI", "INIT", "CPEI"};
903 unsigned char delivery;
904 int vector, mask = 0;
905 unsigned int dest = ((id << 8) | eid) & 0xffff;
907 switch (int_type) {
908 case ACPI_INTERRUPT_PMI:
909 vector = iosapic_vector;
910 /*
911 * since PMI vector is alloc'd by FW(ACPI) not by kernel,
912 * we need to make sure the vector is available
913 */
914 iosapic_reassign_vector(vector);
915 delivery = IOSAPIC_PMI;
916 break;
917 case ACPI_INTERRUPT_INIT:
918 vector = assign_irq_vector(AUTO_ASSIGN);
919 if (vector < 0)
920 panic("%s: out of interrupt vectors!\n", __FUNCTION__);
921 delivery = IOSAPIC_INIT;
922 break;
923 case ACPI_INTERRUPT_CPEI:
924 vector = IA64_CPE_VECTOR;
925 delivery = IOSAPIC_LOWEST_PRIORITY;
926 mask = 1;
927 break;
928 default:
929 printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type 0x%x\n", int_type);
930 return -1;
931 }
933 register_intr(gsi, vector, delivery, polarity, trigger);
935 printk(KERN_INFO "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n",
936 int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown",
937 int_type, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
938 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
939 cpu_logical_id(dest), dest, vector);
941 set_rte(gsi, vector, dest, mask);
942 return vector;
943 }
946 /*
947 * ACPI calls this when it finds an entry for a legacy ISA IRQ override.
948 * Note that the gsi_base and IOSAPIC address must be set in iosapic_init().
949 */
950 void __init
951 iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
952 unsigned long polarity,
953 unsigned long trigger)
954 {
955 int vector;
956 unsigned int dest = cpu_physical_id(smp_processor_id());
958 vector = isa_irq_to_vector(isa_irq);
960 register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger);
962 DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n",
963 isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level",
964 polarity == IOSAPIC_POL_HIGH ? "high" : "low",
965 cpu_logical_id(dest), dest, vector);
967 set_rte(gsi, vector, dest, 1);
968 }
970 void __init
971 iosapic_system_init (int system_pcat_compat)
972 {
973 int vector;
975 for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) {
976 iosapic_intr_info[vector].low32 = IOSAPIC_MASK;
977 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); /* mark as unused */
978 }
980 pcat_compat = system_pcat_compat;
981 if (pcat_compat) {
982 /*
983 * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support
984 * enabled.
985 */
986 printk(KERN_INFO "%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__);
987 outb(0xff, 0xA1);
988 outb(0xff, 0x21);
989 }
990 }
992 static inline int
993 iosapic_alloc (void)
994 {
995 int index;
997 for (index = 0; index < NR_IOSAPICS; index++)
998 if (!iosapic_lists[index].addr)
999 return index;
1001 printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__);
1002 return -1;
1005 static inline void
1006 iosapic_free (int index)
1008 memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0]));
1011 static inline int
1012 iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver)
1014 int index;
1015 unsigned int gsi_end, base, end;
1017 /* check gsi range */
1018 gsi_end = gsi_base + ((ver >> 16) & 0xff);
1019 for (index = 0; index < NR_IOSAPICS; index++) {
1020 if (!iosapic_lists[index].addr)
1021 continue;
1023 base = iosapic_lists[index].gsi_base;
1024 end = base + iosapic_lists[index].num_rte - 1;
1026 if (gsi_base < base && gsi_end < base)
1027 continue;/* OK */
1029 if (gsi_base > end && gsi_end > end)
1030 continue; /* OK */
1032 return -EBUSY;
1034 return 0;
1037 int __devinit
1038 iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
1040 int num_rte, err, index;
1041 unsigned int isa_irq, ver;
1042 char __iomem *addr;
1043 unsigned long flags;
1045 spin_lock_irqsave(&iosapic_lock, flags);
1047 addr = ioremap(phys_addr, 0);
1048 ver = iosapic_version(addr);
1050 if ((err = iosapic_check_gsi_range(gsi_base, ver))) {
1051 iounmap(addr);
1052 spin_unlock_irqrestore(&iosapic_lock, flags);
1053 return err;
1056 /*
1057 * The MAX_REDIR register holds the highest input pin
1058 * number (starting from 0).
1059 * We add 1 so that we can use it for number of pins (= RTEs)
1060 */
1061 num_rte = ((ver >> 16) & 0xff) + 1;
1063 index = iosapic_alloc();
1064 iosapic_lists[index].addr = addr;
1065 iosapic_lists[index].gsi_base = gsi_base;
1066 iosapic_lists[index].num_rte = num_rte;
1067 #ifdef CONFIG_NUMA
1068 iosapic_lists[index].node = MAX_NUMNODES;
1069 #endif
1071 spin_unlock_irqrestore(&iosapic_lock, flags);
1073 if ((gsi_base == 0) && pcat_compat) {
1074 /*
1075 * Map the legacy ISA devices into the IOSAPIC data. Some of these may
1076 * get reprogrammed later on with data from the ACPI Interrupt Source
1077 * Override table.
1078 */
1079 for (isa_irq = 0; isa_irq < 16; ++isa_irq)
1080 iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
1082 return 0;
1085 #ifdef CONFIG_HOTPLUG
1086 int
1087 iosapic_remove (unsigned int gsi_base)
1089 int index, err = 0;
1090 unsigned long flags;
1092 spin_lock_irqsave(&iosapic_lock, flags);
1094 index = find_iosapic(gsi_base);
1095 if (index < 0) {
1096 printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n",
1097 __FUNCTION__, gsi_base);
1098 goto out;
1101 if (iosapic_lists[index].rtes_inuse) {
1102 err = -EBUSY;
1103 printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n",
1104 __FUNCTION__, gsi_base);
1105 goto out;
1108 iounmap(iosapic_lists[index].addr);
1109 iosapic_free(index);
1111 out:
1112 spin_unlock_irqrestore(&iosapic_lock, flags);
1113 return err;
1115 #endif /* CONFIG_HOTPLUG */
1117 #ifdef CONFIG_NUMA
1118 void __devinit
1119 map_iosapic_to_node(unsigned int gsi_base, int node)
1121 int index;
1123 index = find_iosapic(gsi_base);
1124 if (index < 0) {
1125 printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n",
1126 __FUNCTION__, gsi_base);
1127 return;
1129 iosapic_lists[index].node = node;
1130 return;
1132 #endif
1134 #ifndef XEN
1135 static int __init iosapic_enable_kmalloc (void)
1137 iosapic_kmalloc_ok = 1;
1138 return 0;
1140 core_initcall (iosapic_enable_kmalloc);
1141 #endif
1143 #ifdef XEN
1144 /* nop for now */
1145 void set_irq_affinity_info(unsigned int irq, int hwid, int redir) {}
1147 static int iosapic_physbase_to_id(unsigned long physbase)
1149 int i;
1150 unsigned long addr = physbase | __IA64_UNCACHED_OFFSET;
1152 for (i = 0; i < NR_IOSAPICS; i++) {
1153 if ((unsigned long)(iosapic_lists[i].addr) == addr)
1154 return i;
1157 return -1;
1160 int iosapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval)
1162 int id;
1163 unsigned long flags;
1165 if ((id = (iosapic_physbase_to_id(physbase))) < 0)
1166 return id;
1168 spin_lock_irqsave(&iosapic_lock, flags);
1169 *pval = iosapic_read(iosapic_lists[id].addr, reg);
1170 spin_unlock_irqrestore(&iosapic_lock, flags);
1172 return 0;
1175 int iosapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
1177 unsigned int id, gsi, vec, xen_vec, dest, high32;
1178 char rte_index;
1179 struct iosapic *ios;
1180 struct iosapic_intr_info *info;
1181 struct rte_entry rte;
1182 unsigned long flags;
1184 if ((id = (iosapic_physbase_to_id(physbase))) < 0)
1185 return -EINVAL;
1186 ios = &iosapic_lists[id];
1188 /* Only handle first half of RTE update */
1189 if ((reg < 0x10) || (reg & 1))
1190 return 0;
1192 rte.val = val;
1193 rte_index = IOSAPIC_RTEINDEX(reg);
1194 vec = rte.lo.vector;
1195 #if 0
1196 /* Take PMI/NMI/INIT/EXTINT handled by xen */
1197 if (rte.delivery_mode > IOSAPIC_LOWEST_PRIORITY) {
1198 printk("Attempt to write IOSAPIC dest mode owned by xen!\n");
1199 printk("IOSAPIC/PIN = (%d/%d), lo = 0x%x\n",
1200 id, rte_index, val);
1201 return -EINVAL;
1203 #endif
1205 /* Sanity check. Vector should be allocated before this update */
1206 if ((rte_index > ios->num_rte) ||
1207 ((vec > IA64_FIRST_DEVICE_VECTOR) &&
1208 (vec < IA64_LAST_DEVICE_VECTOR) &&
1209 (!test_bit(vec - IA64_FIRST_DEVICE_VECTOR, ia64_vector_mask))))
1210 return -EINVAL;
1212 gsi = ios->gsi_base + rte_index;
1213 xen_vec = gsi_to_vector(gsi);
1214 if (xen_vec >= 0 && test_bit(xen_vec, ia64_xen_vector)) {
1215 printk("WARN: GSI %d in use by Xen.\n", gsi);
1216 return -EINVAL;
1218 info = &iosapic_intr_info[vec];
1219 spin_lock_irqsave(&irq_descp(vec)->lock, flags);
1220 spin_lock(&iosapic_lock);
1221 if (!gsi_vector_to_rte(gsi, vec)) {
1222 register_intr(gsi, vec, IOSAPIC_LOWEST_PRIORITY,
1223 rte.lo.polarity, rte.lo.trigger);
1224 } else if (vector_is_shared(vec)) {
1225 if ((info->trigger != rte.lo.trigger) ||
1226 (info->polarity != rte.lo.polarity)) {
1227 printk("WARN: can't override shared interrupt vec\n");
1228 printk("IOSAPIC/PIN = (%d/%d), ori = 0x%x, new = 0x%x\n",
1229 id, rte_index, info->low32, rte.val);
1230 spin_unlock(&iosapic_lock);
1231 spin_unlock_irqrestore(&irq_descp(vec)->lock, flags);
1232 return -EINVAL;
1235 /* If the vector is shared and already unmasked for other
1236 * interrupt sources, don't mask it.
1238 * Same check may also apply to single gsi pin, which may
1239 * be shared by devices belonging to different domain. But
1240 * let's see how to act later on demand.
1241 */
1242 if (!(info->low32 & IOSAPIC_MASK))
1243 rte.lo.mask = 0;
1246 /* time to update physical RTE */
1247 dest = cpu_physical_id(smp_processor_id());
1248 high32 = (dest << IOSAPIC_DEST_SHIFT);
1249 iosapic_write(iosapic_lists[id].addr, reg + 1, high32);
1250 iosapic_write(iosapic_lists[id].addr, reg, rte.val);
1251 info->low32 = rte.val;
1252 info->dest = dest;
1253 spin_unlock(&iosapic_lock);
1254 spin_unlock_irqrestore(&irq_descp(vec)->lock, flags);
1255 return 0;
1257 #endif /* XEN */