k8-bus_64.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #include <linux/init.h>
  2. #include <linux/pci.h>
  3. #include <asm/pci-direct.h>
  4. #include <asm/mpspec.h>
  5. #include <linux/cpumask.h>
  6. #include <linux/topology.h>
  7. /*
  8. * This discovers the pcibus <-> node mapping on AMD K8.
  9. *
  10. * RED-PEN need to call this again on PCI hotplug
  11. * RED-PEN empty cpus get reported wrong
  12. */
  13. #define NODE_ID_REGISTER 0x60
  14. #define NODE_ID(dword) (dword & 0x07)
  15. #define LDT_BUS_NUMBER_REGISTER_0 0x94
  16. #define LDT_BUS_NUMBER_REGISTER_1 0xB4
  17. #define LDT_BUS_NUMBER_REGISTER_2 0xD4
  18. #define NR_LDT_BUS_NUMBER_REGISTERS 3
  19. #define SECONDARY_LDT_BUS_NUMBER(dword) ((dword >> 8) & 0xFF)
  20. #define SUBORDINATE_LDT_BUS_NUMBER(dword) ((dword >> 16) & 0xFF)
  21. #define PCI_DEVICE_ID_K8HTCONFIG 0x1100
  22. #ifdef CONFIG_NUMA
  23. #define BUS_NR 256
  24. static int mp_bus_to_node[BUS_NR];
  25. void set_mp_bus_to_node(int busnum, int node)
  26. {
  27. if (busnum >= 0 && busnum < BUS_NR)
  28. mp_bus_to_node[busnum] = node;
  29. }
  30. int get_mp_bus_to_node(int busnum)
  31. {
  32. int node = -1;
  33. if (busnum < 0 || busnum > (BUS_NR - 1))
  34. return node;
  35. node = mp_bus_to_node[busnum];
  36. /*
  37. * let numa_node_id to decide it later in dma_alloc_pages
  38. * if there is no ram on that node
  39. */
  40. if (node != -1 && !node_online(node))
  41. node = -1;
  42. return node;
  43. }
  44. #endif
  45. /**
  46. * early_fill_mp_bus_to_node()
  47. * called before pcibios_scan_root and pci_scan_bus
  48. * fills the mp_bus_to_cpumask array based according to the LDT Bus Number
  49. * Registers found in the K8 northbridge
  50. */
  51. __init static int
  52. early_fill_mp_bus_to_node(void)
  53. {
  54. #ifdef CONFIG_NUMA
  55. int i, j;
  56. unsigned slot;
  57. u32 ldtbus, nid;
  58. u32 id;
  59. static int lbnr[3] = {
  60. LDT_BUS_NUMBER_REGISTER_0,
  61. LDT_BUS_NUMBER_REGISTER_1,
  62. LDT_BUS_NUMBER_REGISTER_2
  63. };
  64. for (i = 0; i < BUS_NR; i++)
  65. mp_bus_to_node[i] = -1;
  66. if (!early_pci_allowed())
  67. return -1;
  68. for (slot = 0x18; slot < 0x20; slot++) {
  69. id = read_pci_config(0, slot, 0, PCI_VENDOR_ID);
  70. if (id != (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_K8HTCONFIG<<16)))
  71. break;
  72. nid = read_pci_config(0, slot, 0, NODE_ID_REGISTER);
  73. for (i = 0; i < NR_LDT_BUS_NUMBER_REGISTERS; i++) {
  74. ldtbus = read_pci_config(0, slot, 0, lbnr[i]);
  75. /*
  76. * if there are no busses hanging off of the current
  77. * ldt link then both the secondary and subordinate
  78. * bus number fields are set to 0.
  79. *
  80. * RED-PEN
  81. * This is slightly broken because it assumes
  82. * HT node IDs == Linux node ids, which is not always
  83. * true. However it is probably mostly true.
  84. */
  85. if (!(SECONDARY_LDT_BUS_NUMBER(ldtbus) == 0
  86. && SUBORDINATE_LDT_BUS_NUMBER(ldtbus) == 0)) {
  87. for (j = SECONDARY_LDT_BUS_NUMBER(ldtbus);
  88. j <= SUBORDINATE_LDT_BUS_NUMBER(ldtbus);
  89. j++) {
  90. int node = NODE_ID(nid);
  91. mp_bus_to_node[j] = (unsigned char)node;
  92. }
  93. }
  94. }
  95. }
  96. for (i = 0; i < BUS_NR; i++) {
  97. int node = mp_bus_to_node[i];
  98. if (node >= 0)
  99. printk(KERN_DEBUG "bus: %02x to node: %02x\n", i, node);
  100. }
  101. #endif
  102. return 0;
  103. }
  104. postcore_initcall(early_fill_mp_bus_to_node);