genapic_cluster.c 3.6 KB

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