diff options
Diffstat (limited to 'arch/x86/kernel/apic/x2apic_uv_x.c')
-rw-r--r-- | arch/x86/kernel/apic/x2apic_uv_x.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 1248318436e8..2bda69352976 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/timer.h> | 19 | #include <linux/timer.h> |
20 | #include <linux/cpu.h> | 20 | #include <linux/cpu.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/io.h> | ||
22 | 23 | ||
23 | #include <asm/uv/uv_mmrs.h> | 24 | #include <asm/uv/uv_mmrs.h> |
24 | #include <asm/uv/uv_hub.h> | 25 | #include <asm/uv/uv_hub.h> |
@@ -34,6 +35,17 @@ DEFINE_PER_CPU(int, x2apic_extra_bits); | |||
34 | 35 | ||
35 | static enum uv_system_type uv_system_type; | 36 | static enum uv_system_type uv_system_type; |
36 | 37 | ||
38 | static int early_get_nodeid(void) | ||
39 | { | ||
40 | union uvh_node_id_u node_id; | ||
41 | unsigned long *mmr; | ||
42 | |||
43 | mmr = early_ioremap(UV_LOCAL_MMR_BASE | UVH_NODE_ID, sizeof(*mmr)); | ||
44 | node_id.v = *mmr; | ||
45 | early_iounmap(mmr, sizeof(*mmr)); | ||
46 | return node_id.s.node_id; | ||
47 | } | ||
48 | |||
37 | static int uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | 49 | static int uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) |
38 | { | 50 | { |
39 | if (!strcmp(oem_id, "SGI")) { | 51 | if (!strcmp(oem_id, "SGI")) { |
@@ -42,6 +54,8 @@ static int uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
42 | else if (!strcmp(oem_table_id, "UVX")) | 54 | else if (!strcmp(oem_table_id, "UVX")) |
43 | uv_system_type = UV_X2APIC; | 55 | uv_system_type = UV_X2APIC; |
44 | else if (!strcmp(oem_table_id, "UVH")) { | 56 | else if (!strcmp(oem_table_id, "UVH")) { |
57 | __get_cpu_var(x2apic_extra_bits) = | ||
58 | early_get_nodeid() << (UV_APIC_PNODE_SHIFT - 1); | ||
45 | uv_system_type = UV_NON_UNIQUE_APIC; | 59 | uv_system_type = UV_NON_UNIQUE_APIC; |
46 | return 1; | 60 | return 1; |
47 | } | 61 | } |
@@ -549,7 +563,8 @@ void __init uv_system_init(void) | |||
549 | unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size; | 563 | unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size; |
550 | int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val; | 564 | int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val; |
551 | int max_pnode = 0; | 565 | int max_pnode = 0; |
552 | unsigned long mmr_base, present; | 566 | unsigned long mmr_base, present, paddr; |
567 | unsigned short pnode_mask; | ||
553 | 568 | ||
554 | map_low_mmrs(); | 569 | map_low_mmrs(); |
555 | 570 | ||
@@ -592,6 +607,7 @@ void __init uv_system_init(void) | |||
592 | } | 607 | } |
593 | } | 608 | } |
594 | 609 | ||
610 | pnode_mask = (1 << n_val) - 1; | ||
595 | node_id.v = uv_read_local_mmr(UVH_NODE_ID); | 611 | node_id.v = uv_read_local_mmr(UVH_NODE_ID); |
596 | gnode_upper = (((unsigned long)node_id.s.node_id) & | 612 | gnode_upper = (((unsigned long)node_id.s.node_id) & |
597 | ~((1 << n_val) - 1)) << m_val; | 613 | ~((1 << n_val) - 1)) << m_val; |
@@ -615,7 +631,7 @@ void __init uv_system_init(void) | |||
615 | uv_cpu_hub_info(cpu)->numa_blade_id = blade; | 631 | uv_cpu_hub_info(cpu)->numa_blade_id = blade; |
616 | uv_cpu_hub_info(cpu)->blade_processor_id = lcpu; | 632 | uv_cpu_hub_info(cpu)->blade_processor_id = lcpu; |
617 | uv_cpu_hub_info(cpu)->pnode = pnode; | 633 | uv_cpu_hub_info(cpu)->pnode = pnode; |
618 | uv_cpu_hub_info(cpu)->pnode_mask = (1 << n_val) - 1; | 634 | uv_cpu_hub_info(cpu)->pnode_mask = pnode_mask; |
619 | uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1; | 635 | uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1; |
620 | uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper; | 636 | uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper; |
621 | uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base; | 637 | uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base; |
@@ -631,6 +647,17 @@ void __init uv_system_init(void) | |||
631 | lcpu, blade); | 647 | lcpu, blade); |
632 | } | 648 | } |
633 | 649 | ||
650 | /* Add blade/pnode info for nodes without cpus */ | ||
651 | for_each_online_node(nid) { | ||
652 | if (uv_node_to_blade[nid] >= 0) | ||
653 | continue; | ||
654 | paddr = node_start_pfn(nid) << PAGE_SHIFT; | ||
655 | paddr = uv_soc_phys_ram_to_gpa(paddr); | ||
656 | pnode = (paddr >> m_val) & pnode_mask; | ||
657 | blade = boot_pnode_to_blade(pnode); | ||
658 | uv_node_to_blade[nid] = blade; | ||
659 | } | ||
660 | |||
634 | map_gru_high(max_pnode); | 661 | map_gru_high(max_pnode); |
635 | map_mmr_high(max_pnode); | 662 | map_mmr_high(max_pnode); |
636 | map_config_high(max_pnode); | 663 | map_config_high(max_pnode); |