probe_32.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Default generic APIC driver. This handles up to 8 CPUs.
  4. *
  5. * Copyright 2003 Andi Kleen, SuSE Labs.
  6. *
  7. * Generic x86 APIC driver probe layer.
  8. */
  9. #include <linux/export.h>
  10. #include <linux/errno.h>
  11. #include <linux/smp.h>
  12. #include <xen/xen.h>
  13. #include <asm/io_apic.h>
  14. #include <asm/apic.h>
  15. #include <asm/acpi.h>
  16. #include "local.h"
  17. static u32 default_get_apic_id(u32 x)
  18. {
  19. unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
  20. if (APIC_XAPIC(ver) || boot_cpu_has(X86_FEATURE_EXTD_APICID))
  21. return (x >> 24) & 0xFF;
  22. else
  23. return (x >> 24) & 0x0F;
  24. }
  25. /* should be called last. */
  26. static int probe_default(void)
  27. {
  28. return 1;
  29. }
  30. static struct apic apic_default __ro_after_init = {
  31. .name = "default",
  32. .probe = probe_default,
  33. .dest_mode_logical = true,
  34. .disable_esr = 0,
  35. .init_apic_ldr = default_init_apic_ldr,
  36. .cpu_present_to_apicid = default_cpu_present_to_apicid,
  37. .max_apic_id = 0xFE,
  38. .get_apic_id = default_get_apic_id,
  39. .calc_dest_apicid = apic_flat_calc_apicid,
  40. .send_IPI = default_send_IPI_single,
  41. .send_IPI_mask = default_send_IPI_mask_logical,
  42. .send_IPI_mask_allbutself = default_send_IPI_mask_allbutself_logical,
  43. .send_IPI_allbutself = default_send_IPI_allbutself,
  44. .send_IPI_all = default_send_IPI_all,
  45. .send_IPI_self = default_send_IPI_self,
  46. .read = native_apic_mem_read,
  47. .write = native_apic_mem_write,
  48. .eoi = native_apic_mem_eoi,
  49. .icr_read = native_apic_icr_read,
  50. .icr_write = native_apic_icr_write,
  51. .wait_icr_idle = apic_mem_wait_icr_idle,
  52. .safe_wait_icr_idle = apic_mem_wait_icr_idle_timeout,
  53. };
  54. apic_driver(apic_default);
  55. struct apic *apic __ro_after_init = &apic_default;
  56. EXPORT_SYMBOL_GPL(apic);
  57. static int cmdline_apic __initdata;
  58. static int __init parse_apic(char *arg)
  59. {
  60. struct apic **drv;
  61. if (!arg)
  62. return -EINVAL;
  63. for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
  64. if (!strcmp((*drv)->name, arg)) {
  65. apic_install_driver(*drv);
  66. cmdline_apic = 1;
  67. return 0;
  68. }
  69. }
  70. /* Parsed again by __setup for debug/verbose */
  71. return 0;
  72. }
  73. early_param("apic", parse_apic);
  74. void __init x86_32_probe_bigsmp_early(void)
  75. {
  76. if (nr_cpu_ids <= 8 || xen_pv_domain())
  77. return;
  78. if (IS_ENABLED(CONFIG_X86_BIGSMP)) {
  79. switch (boot_cpu_data.x86_vendor) {
  80. case X86_VENDOR_INTEL:
  81. if (!APIC_XAPIC(boot_cpu_apic_version))
  82. break;
  83. /* P4 and above */
  84. fallthrough;
  85. case X86_VENDOR_HYGON:
  86. case X86_VENDOR_AMD:
  87. if (apic_bigsmp_possible(cmdline_apic))
  88. return;
  89. break;
  90. }
  91. }
  92. pr_info("Limiting to 8 possible CPUs\n");
  93. set_nr_cpu_ids(8);
  94. }
  95. void __init x86_32_install_bigsmp(void)
  96. {
  97. if (nr_cpu_ids > 8 && !xen_pv_domain())
  98. apic_bigsmp_force();
  99. }
  100. void __init x86_32_probe_apic(void)
  101. {
  102. if (!cmdline_apic) {
  103. struct apic **drv;
  104. for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
  105. if ((*drv)->probe()) {
  106. apic_install_driver(*drv);
  107. break;
  108. }
  109. }
  110. /* Not visible without early console */
  111. if (drv == __apicdrivers_end)
  112. panic("Didn't find an APIC driver");
  113. }
  114. }