genapic_cluster.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * Copyright 2004 James Cleverdon, IBM.
  3. * Subject to the GNU Public License, v.2
  4. *
  5. * Clustered APIC subarch code. Up to 255 CPUs, physical delivery.
  6. * (A more realistic maximum is around 230 CPUs.)
  7. *
  8. * Hacked for x86-64 by James Cleverdon from i386 architecture code by
  9. * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
  10. * James Cleverdon.
  11. */
  12. #include <linux/config.h>
  13. #include <linux/threads.h>
  14. #include <linux/cpumask.h>
  15. #include <linux/string.h>
  16. #include <linux/kernel.h>
  17. #include <linux/ctype.h>
  18. #include <linux/init.h>
  19. #include <asm/smp.h>
  20. #include <asm/ipi.h>
  21. /*
  22. * Set up the logical destination ID.
  23. *
  24. * Intel recommends to set DFR, LDR and TPR before enabling
  25. * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
  26. * document number 292116). So here it goes...
  27. */
  28. static void cluster_init_apic_ldr(void)
  29. {
  30. unsigned long val, id;
  31. long i, count;
  32. u8 lid;
  33. u8 my_id = hard_smp_processor_id();
  34. u8 my_cluster = APIC_CLUSTER(my_id);
  35. /* Create logical APIC IDs by counting CPUs already in cluster. */
  36. for (count = 0, i = NR_CPUS; --i >= 0; ) {
  37. lid = x86_cpu_to_log_apicid[i];
  38. if (lid != BAD_APICID && APIC_CLUSTER(lid) == my_cluster)
  39. ++count;
  40. }
  41. /*
  42. * We only have a 4 wide bitmap in cluster mode. There's no way
  43. * to get above 60 CPUs and still give each one it's own bit.
  44. * But, we're using physical IRQ delivery, so we don't care.
  45. * Use bit 3 for the 4th through Nth CPU in each cluster.
  46. */
  47. if (count >= XAPIC_DEST_CPUS_SHIFT)
  48. count = 3;
  49. id = my_cluster | (1UL << count);
  50. x86_cpu_to_log_apicid[smp_processor_id()] = id;
  51. apic_write_around(APIC_DFR, APIC_DFR_CLUSTER);
  52. val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
  53. val |= SET_APIC_LOGICAL_ID(id);
  54. apic_write_around(APIC_LDR, val);
  55. }
  56. /* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */
  57. static cpumask_t cluster_target_cpus(void)
  58. {
  59. return cpumask_of_cpu(0);
  60. }
  61. static void cluster_send_IPI_mask(cpumask_t mask, int vector)
  62. {
  63. send_IPI_mask_sequence(mask, vector);
  64. }
  65. static void cluster_send_IPI_allbutself(int vector)
  66. {
  67. cpumask_t mask = cpu_online_map;
  68. int me = get_cpu(); /* Ensure we are not preempted when we clear */
  69. cpu_clear(me, mask);
  70. if (!cpus_empty(mask))
  71. cluster_send_IPI_mask(mask, vector);
  72. put_cpu();
  73. }
  74. static void cluster_send_IPI_all(int vector)
  75. {
  76. cluster_send_IPI_mask(cpu_online_map, vector);
  77. }
  78. static int cluster_apic_id_registered(void)
  79. {
  80. return 1;
  81. }
  82. static unsigned int cluster_cpu_mask_to_apicid(cpumask_t cpumask)
  83. {
  84. int cpu;
  85. /*
  86. * We're using fixed IRQ delivery, can only return one phys APIC ID.
  87. * May as well be the first.
  88. */
  89. cpu = first_cpu(cpumask);
  90. if ((unsigned)cpu < NR_CPUS)
  91. return x86_cpu_to_apicid[cpu];
  92. else
  93. return BAD_APICID;
  94. }
  95. /* cpuid returns the value latched in the HW at reset, not the APIC ID
  96. * register's value. For any box whose BIOS changes APIC IDs, like
  97. * clustered APIC systems, we must use hard_smp_processor_id.
  98. *
  99. * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
  100. */
  101. static unsigned int phys_pkg_id(int index_msb)
  102. {
  103. return hard_smp_processor_id() >> index_msb;
  104. }
  105. struct genapic apic_cluster = {
  106. .name = "clustered",
  107. .int_delivery_mode = dest_Fixed,
  108. .int_dest_mode = (APIC_DEST_PHYSICAL != 0),
  109. .int_delivery_dest = APIC_DEST_PHYSICAL | APIC_DM_FIXED,
  110. .target_cpus = cluster_target_cpus,
  111. .apic_id_registered = cluster_apic_id_registered,
  112. .init_apic_ldr = cluster_init_apic_ldr,
  113. .send_IPI_all = cluster_send_IPI_all,
  114. .send_IPI_allbutself = cluster_send_IPI_allbutself,
  115. .send_IPI_mask = cluster_send_IPI_mask,
  116. .cpu_mask_to_apicid = cluster_cpu_mask_to_apicid,
  117. .phys_pkg_id = phys_pkg_id,
  118. };