ipi.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #ifndef _ASM_X86_IPI_H
  2. #define _ASM_X86_IPI_H
  3. #ifdef CONFIG_X86_LOCAL_APIC
  4. /*
  5. * Copyright 2004 James Cleverdon, IBM.
  6. * Subject to the GNU Public License, v.2
  7. *
  8. * Generic APIC InterProcessor Interrupt code.
  9. *
  10. * Moved to include file by James Cleverdon from
  11. * arch/x86-64/kernel/smp.c
  12. *
  13. * Copyrights from kernel/smp.c:
  14. *
  15. * (c) 1995 Alan Cox, Building #3 <alan@redhat.com>
  16. * (c) 1998-99, 2000 Ingo Molnar <mingo@redhat.com>
  17. * (c) 2002,2003 Andi Kleen, SuSE Labs.
  18. * Subject to the GNU Public License, v.2
  19. */
  20. #include <asm/hw_irq.h>
  21. #include <asm/apic.h>
  22. #include <asm/smp.h>
  23. /*
  24. * the following functions deal with sending IPIs between CPUs.
  25. *
  26. * We use 'broadcast', CPU->CPU IPIs and self-IPIs too.
  27. */
  28. static inline unsigned int __prepare_ICR(unsigned int shortcut, int vector,
  29. unsigned int dest)
  30. {
  31. unsigned int icr = shortcut | dest;
  32. switch (vector) {
  33. default:
  34. icr |= APIC_DM_FIXED | vector;
  35. break;
  36. case NMI_VECTOR:
  37. icr |= APIC_DM_NMI;
  38. break;
  39. }
  40. return icr;
  41. }
  42. static inline int __prepare_ICR2(unsigned int mask)
  43. {
  44. return SET_APIC_DEST_FIELD(mask);
  45. }
  46. static inline void __xapic_wait_icr_idle(void)
  47. {
  48. while (native_apic_mem_read(APIC_ICR) & APIC_ICR_BUSY)
  49. cpu_relax();
  50. }
  51. void __default_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int dest);
  52. /*
  53. * This is used to send an IPI with no shorthand notation (the destination is
  54. * specified in bits 56 to 63 of the ICR).
  55. */
  56. void __default_send_IPI_dest_field(unsigned int mask, int vector, unsigned int dest);
  57. extern void default_send_IPI_single(int cpu, int vector);
  58. extern void default_send_IPI_single_phys(int cpu, int vector);
  59. extern void default_send_IPI_mask_sequence_phys(const struct cpumask *mask,
  60. int vector);
  61. extern void default_send_IPI_mask_allbutself_phys(const struct cpumask *mask,
  62. int vector);
  63. /* Avoid include hell */
  64. #define NMI_VECTOR 0x02
  65. extern int no_broadcast;
  66. static inline void __default_local_send_IPI_allbutself(int vector)
  67. {
  68. if (no_broadcast || vector == NMI_VECTOR)
  69. apic->send_IPI_mask_allbutself(cpu_online_mask, vector);
  70. else
  71. __default_send_IPI_shortcut(APIC_DEST_ALLBUT, vector, apic->dest_logical);
  72. }
  73. static inline void __default_local_send_IPI_all(int vector)
  74. {
  75. if (no_broadcast || vector == NMI_VECTOR)
  76. apic->send_IPI_mask(cpu_online_mask, vector);
  77. else
  78. __default_send_IPI_shortcut(APIC_DEST_ALLINC, vector, apic->dest_logical);
  79. }
  80. #ifdef CONFIG_X86_32
  81. extern void default_send_IPI_mask_sequence_logical(const struct cpumask *mask,
  82. int vector);
  83. extern void default_send_IPI_mask_allbutself_logical(const struct cpumask *mask,
  84. int vector);
  85. extern void default_send_IPI_mask_logical(const struct cpumask *mask,
  86. int vector);
  87. extern void default_send_IPI_allbutself(int vector);
  88. extern void default_send_IPI_all(int vector);
  89. extern void default_send_IPI_self(int vector);
  90. #endif
  91. #endif
  92. #endif /* _ASM_X86_IPI_H */