x86, UV: Support for SGI UV2 hub chip
Subsystems (2)
PATCH 1/1 x86, UV: Support for SGI UV2 hub chip
This patch adds support for a new version of the SGI UV hub chip. The hub chip is the node controller that connects multiple blades into a larger coherent SSI.
For the most part, UV2 is compatible with UV1. The majority of the changes are in the addresses of MMRs and in a few cases, the contents of MMRs. These changes are the result in changes in the system topology such as node configuration, processor types, maximum nodes, physical address sizes, etc.
--- arch/x86/include/asm/uv/uv_bau.h | 42 + arch/x86/include/asm/uv/uv_hub.h | 67 +- arch/x86/include/asm/uv/uv_mmrs.h | 1010 ++++++++++++++++++++++++++++++------- arch/x86/kernel/apic/x2apic_uv_x.c | 38 + arch/x86/platform/uv/tlb_uv.c | 162 ++++- arch/x86/platform/uv/uv_time.c | 16 6 files changed, 1074 insertions(+), 261 deletions(-)
arch/x86/include/asm/uv/uv_bau.h +38 -4
@@ -44,7 +44,10 @@#define UV_ACT_STATUS_SIZE 2#define UV_DISTRIBUTION_SIZE 256#define UV_SW_ACK_NPENDING 8 -#define UV_NET_ENDPOINT_INTD 0x38 +#define UV1_NET_ENDPOINT_INTD 0x38 +#define UV2_NET_ENDPOINT_INTD 0x28 +#define UV_NET_ENDPOINT_INTD (is_uv1_hub() ? \ + UV1_NET_ENDPOINT_INTD : UV2_NET_ENDPOINT_INTD)#define UV_DESC_BASE_PNODE_SHIFT 49#define UV_PAYLOADQ_PNODE_SHIFT 49#define UV_PTC_BASENAME "sgi_uv/ptc_statistics"
@@ -53,10 +56,22 @@#define UV_BAU_TUNABLES_FILE "bau_tunables"#define WHITESPACE " \t\n"#define uv_physnodeaddr (x) ((__pa((unsigned long)(x)) & uv_mmask)) -#define UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT 15 -#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT 16 -#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x0000000009UL + +/* [19:16] SOFT_ACK timeout period 19: 1 is urgency 7 17:16 1 is multiplier */ +/* +* UV2: Bit 19 selects between +* (0): 10 microsecond timebase and +* (1): 80 microseconds +* we're using 655us, similar to UV1: 65 units of 10us +*/ +#define UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD (9UL) +#define UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD (65*10UL) + +#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD (is_uv1_hub() ? \ + UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD : \ + UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD) +#define BAU_MISC_CONTROL_MULT_MASK 3#define UVH_AGING_PRESCALE_SEL 0x000000b000UL
@@ -76,6 +91,16 @@#define DESC_STATUS_ACTIVE 1#define DESC_STATUS_DESTINATION_TIMEOUT 2#define DESC_STATUS_SOURCE_TIMEOUT 3 +/* +* bits put together from HRP_LB_BAU_SB_ACTIVATION_STATUS_0/1/2 +* values 1 and 5 will not occur +*/ +#define UV2H_DESC_IDLE 0 +#define UV2H_DESC_DEST_TIMEOUT 2 +#define UV2H_DESC_DEST_STRONG_NACK 3 +#define UV2H_DESC_BUSY 4 +#define UV2H_DESC_SOURCE_TIMEOUT 6 +#define UV2H_DESC_DEST_PUT_ERR 7/* * delay for 'plugged' timeout retries, in microseconds
@@ -96,6 +121,15 @@#define UV_LB_SUBNODEID 0x10 +/* these two are the same for UV1 and UV2: */ +#define UV_SA_SHFT UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT +#define UV_SA_MASK UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK +/* 4 bits of software ack period */ +#define UV2_ACK_MASK 0x7UL +#define UV2_ACK_UNITS_SHFT 3 +#define UV2_LEG_SHFT UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT +#define UV2_EXT_SHFT UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT +/* * number of entries in the destination side payload queue */
arch/x86/include/asm/uv/uv_hub.h +54 -13
119 lines not on this page · raw message
arch/x86/include/asm/uv/uv_mmrs.h +821 -189
1,255 lines not on this page · raw message
arch/x86/kernel/apic/x2apic_uv_x.c +29 -9
@@ -89,6 +89,10 @@ static int __init early_get_pnodeid(void m_n_config.v =uv_early_read_mmr (UVH_RH_GAM_CONFIG_MMR ); uv_min_hub_revision_id = node_id.s.revision; +if (node_id.s.part_number ==UV2_HUB_PART_NUMBER ) + uv_min_hub_revision_id +=UV2_HUB_REVISION_BASE -1 ; + + uv_hub_info->hub_revision = uv_min_hub_revision_id; pnode = (node_id.s.node_id >>1 ) & ((1 << m_n_config.s.n_skt) -1 );return pnode; }
@@ -110,17 +114,23 @@ static void __init early_get_apic_pnode_*/ static void __init uv_set_apicid_hibit (void ) { -union uvh_lb_target_physical_apic_id_mask_u apicid_mask; +union uv1h_lb_target_physical_apic_id_mask_u apicid_mask; - apicid_mask.v =uv_early_read_mmr (UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK ); - uv_apicid_hibits = apicid_mask.s.bit_enables &UV_APICID_HIBIT_MASK ; +if (is_uv1_hub ()) { + apicid_mask.v =uv_early_read_mmr (UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK ); + uv_apicid_hibits = apicid_mask.s1.bit_enables &UV_APICID_HIBIT_MASK ; + } }static int __init uv_acpi_madt_oem_check (char *oem_id,char *oem_table_id) { -int pnodeid; +int pnodeid, is_uv1, is_uv2; -if (!strcmp (oem_id,"SGI" )) { + is_uv1 = !strcmp (oem_id,"SGI" ); + is_uv2 = !strcmp (oem_id,"SGI2" ); +if (is_uv1 || is_uv2) { + uv_hub_info->hub_revision = + is_uv1 ?UV1_HUB_REVISION_BASE :UV2_HUB_REVISION_BASE ; pnodeid =early_get_pnodeid ();early_get_apic_pnode_shift (); x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range;
@@ -477,12 +487,19 @@ static __init void map_mmr_high(int max_static __init void map_mmioh_high (int max_pnode) {union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh; -int shift =UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT ; +int shift; mmioh.v =uv_read_local_mmr (UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR ); -if (mmioh.s.enable) -map_high ("MMIOH" , mmioh.s.base, shift, mmioh.s.m_io, +if (is_uv1_hub () && mmioh.s1.enable) { + shift =UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT ; +map_high ("MMIOH" , mmioh.s1.base, shift, mmioh.s1.m_io, + max_pnode, map_uc); + } +if (is_uv2_hub () && mmioh.s2.enable) { + shift =UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT ; +map_high ("MMIOH" , mmioh.s2.base, shift, mmioh.s2.m_io, max_pnode, map_uc); + } }static __init void map_low_mmrs (void )
@@ -729,13 +746,14 @@ void __init uv_system_init(void)unsigned long mmr_base, present, paddr;unsigned short pnode_mask, pnode_io_mask; +printk ("UV: Found %s hub\n" ,is_uv1_hub () ?"UV1" :"UV2" );map_low_mmrs (); m_n_config.v =uv_read_local_mmr (UVH_RH_GAM_CONFIG_MMR ); m_val = m_n_config.s.m_skt; n_val = m_n_config.s.n_skt; mmioh.v =uv_read_local_mmr (UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR ); - n_io = mmioh.s.n_io; + n_io =is_uv1_hub () ? mmioh.s1.n_io : mmioh.s2.n_io; mmr_base =uv_read_local_mmr (UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR ) & ~UV_MMR_ENABLE ;
@@ -804,6 +822,8 @@ void __init uv_system_init(void)*/ uv_cpu_hub_info (cpu)->pnode_mask = pnode_mask;uv_cpu_hub_info (cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift; +uv_cpu_hub_info (cpu)->hub_revision = uv_hub_info->hub_revision; + pnode =uv_apicid_to_pnode (apicid); blade =boot_pnode_to_blade (pnode); lcpu = uv_blade_info[blade].nr_possible_cpus;
arch/x86/platform/uv/tlb_uv.c +120 -42
204 lines not on this page · raw message
arch/x86/platform/uv/uv_time.c +12 -4
@@ -99,8 +99,12 @@ static void uv_rtc_send_IPI(int cpu)/* Check for an RTC interrupt pending */ static int uv_intr_pending (int pnode) { -return uv_read_global_mmr64 (pnode,UVH_EVENT_OCCURRED0 ) & -UVH_EVENT_OCCURRED0_RTC1_MASK ; +if (is_uv1_hub ()) +return uv_read_global_mmr64 (pnode,UVH_EVENT_OCCURRED0 ) & +UV1H_EVENT_OCCURRED0_RTC1_MASK ; +else +return uv_read_global_mmr64 (pnode,UV2H_EVENT_OCCURRED2 ) & +UV2H_EVENT_OCCURRED2_RTC_1_MASK ; }/* Setup interrupt and return non-zero if early expiration occurred. */
@@ -114,8 +118,12 @@ static int uv_setup_intr(int cpu, u64 ex UVH_RTC1_INT_CONFIG_M_MASK);uv_write_global_mmr64 (pnode,UVH_INT_CMPB ,-1L ); -uv_write_global_mmr64 (pnode,UVH_EVENT_OCCURRED0_ALIAS , -UVH_EVENT_OCCURRED0_RTC1_MASK ); +if (is_uv1_hub ()) +uv_write_global_mmr64 (pnode,UVH_EVENT_OCCURRED0_ALIAS , +UV1H_EVENT_OCCURRED0_RTC1_MASK ); +else +uv_write_global_mmr64 (pnode,UV2H_EVENT_OCCURRED2_ALIAS , +UV2H_EVENT_OCCURRED2_RTC_1_MASK ); val = (X86_PLATFORM_IPI_VECTOR <<UVH_RTC1_INT_CONFIG_VECTOR_SHFT ) | ((u64 )apicid <<UVH_RTC1_INT_CONFIG_APIC_ID_SHFT );
arch/x86/platform/uv/tlb_uv.c static int uv_wait_completion(struct bau · line 443
Quoted 11 lines · Jack Steiner
arch/x86/platform/uv/tlb_uv.c +11
-0+/* +* Our retries may be blocked by all destination +* swack resources being consumed, and a timeout +* pending. In that case hardware returns the +* ERROR that looks like a destination timeout. +*/ +if (cycles_2_us (ttime - bcp->send_message) < + timeout_us) { + bcp->conseccompletes =0 ; +return FLUSH_RETRY_PLUGGED ; + }
This code is sick. Symptom: too long lines. Illness: it's too complex.
checkpatch warned you but you applied the wrong cure: you only addressed the symptom and broke the lines in an ugly way.
You need to pick another cure. One of the many options:
- eliminate many repetitive strings
- reduce indentation by the introduction of helper inlines
- sensible shortening of variable/field/definition names
... applies to this particular case and will solve the problem.
Note that there's other, similar incidents in this patch, please address all of them.
Thanks,
Ingo
This patch adds support for a new version of the SGI UV hub chip. The hub chip is the node controller that connects multiple blades into a larger coherent SSI.
For the most part, UV2 is compatible with UV1. The majority of the changes are in the addresses of MMRs and in a few cases, the contents of MMRs. These changes are the result in changes in the system topology such as node configuration, processor types, maximum nodes, physical address sizes, etc.
---
V2 - Fixed long lines in all files except for uv_mmrs.h. This file is
auto generated from verilog for the node controller. I'll send a followup patch later this month to fix this file so that it passes the checkpatch.pl checking.
- refactored the code in tlb_uv.c to reduce function sizes & complexity
arch/x86/include/asm/uv/uv_bau.h | 42 + arch/x86/include/asm/uv/uv_hub.h | 71 ++ arch/x86/include/asm/uv/uv_mmrs.h | 1010 ++++++++++++++++++++++++++++++------- arch/x86/kernel/apic/x2apic_uv_x.c | 40 + arch/x86/platform/uv/tlb_uv.c | 132 ++++ arch/x86/platform/uv/uv_time.c | 16 6 files changed, 1074 insertions(+), 237 deletions(-)
arch/x86/include/asm/uv/uv_bau.h +38 -4
@@ -44,7 +44,10 @@#define UV_ACT_STATUS_SIZE 2#define UV_DISTRIBUTION_SIZE 256#define UV_SW_ACK_NPENDING 8 -#define UV_NET_ENDPOINT_INTD 0x38 +#define UV1_NET_ENDPOINT_INTD 0x38 +#define UV2_NET_ENDPOINT_INTD 0x28 +#define UV_NET_ENDPOINT_INTD (is_uv1_hub() ? \ + UV1_NET_ENDPOINT_INTD : UV2_NET_ENDPOINT_INTD)#define UV_DESC_BASE_PNODE_SHIFT 49#define UV_PAYLOADQ_PNODE_SHIFT 49#define UV_PTC_BASENAME "sgi_uv/ptc_statistics"
@@ -53,10 +56,22 @@#define UV_BAU_TUNABLES_FILE "bau_tunables"#define WHITESPACE " \t\n"#define uv_physnodeaddr (x) ((__pa((unsigned long)(x)) & uv_mmask)) -#define UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT 15 -#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT 16 -#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x0000000009UL + +/* [19:16] SOFT_ACK timeout period 19: 1 is urgency 7 17:16 1 is multiplier */ +/* +* UV2: Bit 19 selects between +* (0): 10 microsecond timebase and +* (1): 80 microseconds +* we're using 655us, similar to UV1: 65 units of 10us +*/ +#define UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD (9UL) +#define UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD (65*10UL) + +#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD (is_uv1_hub() ? \ + UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD : \ + UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD) +#define BAU_MISC_CONTROL_MULT_MASK 3#define UVH_AGING_PRESCALE_SEL 0x000000b000UL
@@ -76,6 +91,16 @@#define DESC_STATUS_ACTIVE 1#define DESC_STATUS_DESTINATION_TIMEOUT 2#define DESC_STATUS_SOURCE_TIMEOUT 3 +/* +* bits put together from HRP_LB_BAU_SB_ACTIVATION_STATUS_0/1/2 +* values 1 and 5 will not occur +*/ +#define UV2H_DESC_IDLE 0 +#define UV2H_DESC_DEST_TIMEOUT 2 +#define UV2H_DESC_DEST_STRONG_NACK 3 +#define UV2H_DESC_BUSY 4 +#define UV2H_DESC_SOURCE_TIMEOUT 6 +#define UV2H_DESC_DEST_PUT_ERR 7/* * delay for 'plugged' timeout retries, in microseconds
@@ -96,6 +121,15 @@#define UV_LB_SUBNODEID 0x10 +/* these two are the same for UV1 and UV2: */ +#define UV_SA_SHFT UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT +#define UV_SA_MASK UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK +/* 4 bits of software ack period */ +#define UV2_ACK_MASK 0x7UL +#define UV2_ACK_UNITS_SHFT 3 +#define UV2_LEG_SHFT UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT +#define UV2_EXT_SHFT UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT +/* * number of entries in the destination side payload queue */
arch/x86/include/asm/uv/uv_hub.h +58 -13
123 lines not on this page · raw message
arch/x86/include/asm/uv/uv_mmrs.h +821 -189
1,255 lines not on this page · raw message
arch/x86/kernel/apic/x2apic_uv_x.c +31 -9
@@ -89,6 +89,10 @@ static int __init early_get_pnodeid(void m_n_config.v =uv_early_read_mmr (UVH_RH_GAM_CONFIG_MMR ); uv_min_hub_revision_id = node_id.s.revision; +if (node_id.s.part_number ==UV2_HUB_PART_NUMBER ) + uv_min_hub_revision_id +=UV2_HUB_REVISION_BASE -1 ; + + uv_hub_info->hub_revision = uv_min_hub_revision_id; pnode = (node_id.s.node_id >>1 ) & ((1 << m_n_config.s.n_skt) -1 );return pnode; }
@@ -110,17 +114,25 @@ static void __init early_get_apic_pnode_*/ static void __init uv_set_apicid_hibit (void ) { -union uvh_lb_target_physical_apic_id_mask_u apicid_mask; +union uv1h_lb_target_physical_apic_id_mask_u apicid_mask; - apicid_mask.v =uv_early_read_mmr (UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK ); - uv_apicid_hibits = apicid_mask.s.bit_enables &UV_APICID_HIBIT_MASK ; +if (is_uv1_hub ()) { + apicid_mask.v = +uv_early_read_mmr (UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK ); + uv_apicid_hibits = + apicid_mask.s1.bit_enables &UV_APICID_HIBIT_MASK ; + } }static int __init uv_acpi_madt_oem_check (char *oem_id,char *oem_table_id) { -int pnodeid; +int pnodeid, is_uv1, is_uv2; -if (!strcmp (oem_id,"SGI" )) { + is_uv1 = !strcmp (oem_id,"SGI" ); + is_uv2 = !strcmp (oem_id,"SGI2" ); +if (is_uv1 || is_uv2) { + uv_hub_info->hub_revision = + is_uv1 ?UV1_HUB_REVISION_BASE :UV2_HUB_REVISION_BASE ; pnodeid =early_get_pnodeid ();early_get_apic_pnode_shift (); x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range;
@@ -477,12 +489,19 @@ static __init void map_mmr_high(int max_static __init void map_mmioh_high (int max_pnode) {union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh; -int shift =UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT ; +int shift; mmioh.v =uv_read_local_mmr (UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR ); -if (mmioh.s.enable) -map_high ("MMIOH" , mmioh.s.base, shift, mmioh.s.m_io, +if (is_uv1_hub () && mmioh.s1.enable) { + shift =UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT ; +map_high ("MMIOH" , mmioh.s1.base, shift, mmioh.s1.m_io, + max_pnode, map_uc); + } +if (is_uv2_hub () && mmioh.s2.enable) { + shift =UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT ; +map_high ("MMIOH" , mmioh.s2.base, shift, mmioh.s2.m_io, max_pnode, map_uc); + } }static __init void map_low_mmrs (void )
@@ -729,13 +748,14 @@ void __init uv_system_init(void)unsigned long mmr_base, present, paddr;unsigned short pnode_mask, pnode_io_mask; +printk (KERN_INFO "UV: Found %s hub\n" ,is_uv1_hub () ?"UV1" :"UV2" );map_low_mmrs (); m_n_config.v =uv_read_local_mmr (UVH_RH_GAM_CONFIG_MMR ); m_val = m_n_config.s.m_skt; n_val = m_n_config.s.n_skt; mmioh.v =uv_read_local_mmr (UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR ); - n_io = mmioh.s.n_io; + n_io =is_uv1_hub () ? mmioh.s1.n_io : mmioh.s2.n_io; mmr_base =uv_read_local_mmr (UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR ) & ~UV_MMR_ENABLE ;
@@ -804,6 +824,8 @@ void __init uv_system_init(void)*/ uv_cpu_hub_info (cpu)->pnode_mask = pnode_mask;uv_cpu_hub_info (cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift; +uv_cpu_hub_info (cpu)->hub_revision = uv_hub_info->hub_revision; + pnode =uv_apicid_to_pnode (apicid); blade =boot_pnode_to_blade (pnode); lcpu = uv_blade_info[blade].nr_possible_cpus;
arch/x86/platform/uv/tlb_uv.c +114 -18
190 lines not on this page · raw message
arch/x86/platform/uv/uv_time.c +12 -4
@@ -99,8 +99,12 @@ static void uv_rtc_send_IPI(int cpu)/* Check for an RTC interrupt pending */ static int uv_intr_pending (int pnode) { -return uv_read_global_mmr64 (pnode,UVH_EVENT_OCCURRED0 ) & -UVH_EVENT_OCCURRED0_RTC1_MASK ; +if (is_uv1_hub ()) +return uv_read_global_mmr64 (pnode,UVH_EVENT_OCCURRED0 ) & +UV1H_EVENT_OCCURRED0_RTC1_MASK ; +else +return uv_read_global_mmr64 (pnode,UV2H_EVENT_OCCURRED2 ) & +UV2H_EVENT_OCCURRED2_RTC_1_MASK ; }/* Setup interrupt and return non-zero if early expiration occurred. */
@@ -114,8 +118,12 @@ static int uv_setup_intr(int cpu, u64 ex UVH_RTC1_INT_CONFIG_M_MASK);uv_write_global_mmr64 (pnode,UVH_INT_CMPB ,-1L ); -uv_write_global_mmr64 (pnode,UVH_EVENT_OCCURRED0_ALIAS , -UVH_EVENT_OCCURRED0_RTC1_MASK ); +if (is_uv1_hub ()) +uv_write_global_mmr64 (pnode,UVH_EVENT_OCCURRED0_ALIAS , +UV1H_EVENT_OCCURRED0_RTC1_MASK ); +else +uv_write_global_mmr64 (pnode,UV2H_EVENT_OCCURRED2_ALIAS , +UV2H_EVENT_OCCURRED2_RTC_1_MASK ); val = (X86_PLATFORM_IPI_VECTOR <<UVH_RTC1_INT_CONFIG_VECTOR_SHFT ) | ((u64 )apicid <<UVH_RTC1_INT_CONFIG_APIC_ID_SHFT );
[tip:x86/urgent] x86, UV: Add support for SGI UV2 hub chip
Commit-ID: 2a919596c16b4333af851ff473ebf96e289ab90c Gitweb: http://git.kernel.org/tip/2a919596c16b4333af851ff473ebf96e289ab90c Author: Jack Steiner <[email protected]> AuthorDate: Wed, 11 May 2011 12:50:28 -0500 Committer: Ingo Molnar <[email protected]> CommitDate: Wed, 25 May 2011 14:20:13 +0200
x86, UV: Add support for SGI UV2 hub chip
This patch adds support for a new version of the SGI UV hub chip. The hub chip is the node controller that connects multiple blades into a larger coherent SSI.
For the most part, UV2 is compatible with UV1. The majority of the changes are in the addresses of MMRs and in a few cases, the contents of MMRs. These changes are the result in changes in the system topology such as node configuration, processor types, maximum nodes, physical address sizes, etc.
--- arch/x86/include/asm/uv/uv_bau.h | 42 ++- arch/x86/include/asm/uv/uv_hub.h | 71 ++- arch/x86/include/asm/uv/uv_mmrs.h | 1012 +++++++++++++++++++++++++++++------- arch/x86/kernel/apic/x2apic_uv_x.c | 40 ++- arch/x86/platform/uv/tlb_uv.c | 132 ++++- arch/x86/platform/uv/uv_time.c | 16 +- 6 files changed, 1075 insertions(+), 238 deletions(-)
arch/x86/include/asm/uv/uv_bau.h +38 -4
@@ -44,7 +44,10 @@#define UV_ACT_STATUS_SIZE 2#define UV_DISTRIBUTION_SIZE 256#define UV_SW_ACK_NPENDING 8 -#define UV_NET_ENDPOINT_INTD 0x38 +#define UV1_NET_ENDPOINT_INTD 0x38 +#define UV2_NET_ENDPOINT_INTD 0x28 +#define UV_NET_ENDPOINT_INTD (is_uv1_hub() ? \ + UV1_NET_ENDPOINT_INTD : UV2_NET_ENDPOINT_INTD)#define UV_DESC_BASE_PNODE_SHIFT 49#define UV_PAYLOADQ_PNODE_SHIFT 49#define UV_PTC_BASENAME "sgi_uv/ptc_statistics"
@@ -53,10 +56,22 @@#define UV_BAU_TUNABLES_FILE "bau_tunables"#define WHITESPACE " \t\n"#define uv_physnodeaddr (x) ((__pa((unsigned long)(x)) & uv_mmask)) -#define UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT 15 -#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT 16 -#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x0000000009UL + +/* [19:16] SOFT_ACK timeout period 19: 1 is urgency 7 17:16 1 is multiplier */ +/* +* UV2: Bit 19 selects between +* (0): 10 microsecond timebase and +* (1): 80 microseconds +* we're using 655us, similar to UV1: 65 units of 10us +*/ +#define UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD (9UL) +#define UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD (65*10UL) + +#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD (is_uv1_hub() ? \ + UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD : \ + UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD) +#define BAU_MISC_CONTROL_MULT_MASK 3#define UVH_AGING_PRESCALE_SEL 0x000000b000UL
@@ -76,6 +91,16 @@#define DESC_STATUS_ACTIVE 1#define DESC_STATUS_DESTINATION_TIMEOUT 2#define DESC_STATUS_SOURCE_TIMEOUT 3 +/* +* bits put together from HRP_LB_BAU_SB_ACTIVATION_STATUS_0/1/2 +* values 1 and 5 will not occur +*/ +#define UV2H_DESC_IDLE 0 +#define UV2H_DESC_DEST_TIMEOUT 2 +#define UV2H_DESC_DEST_STRONG_NACK 3 +#define UV2H_DESC_BUSY 4 +#define UV2H_DESC_SOURCE_TIMEOUT 6 +#define UV2H_DESC_DEST_PUT_ERR 7/* * delay for 'plugged' timeout retries, in microseconds
@@ -96,6 +121,15 @@#define UV_LB_SUBNODEID 0x10 +/* these two are the same for UV1 and UV2: */ +#define UV_SA_SHFT UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT +#define UV_SA_MASK UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK +/* 4 bits of software ack period */ +#define UV2_ACK_MASK 0x7UL +#define UV2_ACK_UNITS_SHFT 3 +#define UV2_LEG_SHFT UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT +#define UV2_EXT_SHFT UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT +/* * number of entries in the destination side payload queue */
arch/x86/include/asm/uv/uv_hub.h +58 -13
123 lines not on this page · raw message
arch/x86/include/asm/uv/uv_mmrs.h +822 -190
1,256 lines not on this page · raw message
arch/x86/kernel/apic/x2apic_uv_x.c +31 -9
@@ -91,6 +91,10 @@ static int __init early_get_pnodeid(void) m_n_config.v =uv_early_read_mmr (UVH_RH_GAM_CONFIG_MMR ); uv_min_hub_revision_id = node_id.s.revision; +if (node_id.s.part_number ==UV2_HUB_PART_NUMBER ) + uv_min_hub_revision_id +=UV2_HUB_REVISION_BASE -1 ; + + uv_hub_info->hub_revision = uv_min_hub_revision_id; pnode = (node_id.s.node_id >>1 ) & ((1 << m_n_config.s.n_skt) -1 );return pnode; }
@@ -112,17 +116,25 @@ static void __init early_get_apic_pnode_shift(void)*/ static void __init uv_set_apicid_hibit (void ) { -union uvh_lb_target_physical_apic_id_mask_u apicid_mask; +union uv1h_lb_target_physical_apic_id_mask_u apicid_mask; - apicid_mask.v =uv_early_read_mmr (UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK ); - uv_apicid_hibits = apicid_mask.s.bit_enables &UV_APICID_HIBIT_MASK ; +if (is_uv1_hub ()) { + apicid_mask.v = +uv_early_read_mmr (UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK ); + uv_apicid_hibits = + apicid_mask.s1.bit_enables &UV_APICID_HIBIT_MASK ; + } }static int __init uv_acpi_madt_oem_check (char *oem_id,char *oem_table_id) { -int pnodeid; +int pnodeid, is_uv1, is_uv2; -if (!strcmp (oem_id,"SGI" )) { + is_uv1 = !strcmp (oem_id,"SGI" ); + is_uv2 = !strcmp (oem_id,"SGI2" ); +if (is_uv1 || is_uv2) { + uv_hub_info->hub_revision = + is_uv1 ?UV1_HUB_REVISION_BASE :UV2_HUB_REVISION_BASE ; pnodeid =early_get_pnodeid ();early_get_apic_pnode_shift (); x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range;
@@ -484,12 +496,19 @@ static __init void map_mmr_high(int max_pnode)static __init void map_mmioh_high (int max_pnode) {union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh; -int shift =UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT ; +int shift; mmioh.v =uv_read_local_mmr (UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR ); -if (mmioh.s.enable) -map_high ("MMIOH" , mmioh.s.base, shift, mmioh.s.m_io, +if (is_uv1_hub () && mmioh.s1.enable) { + shift =UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT ; +map_high ("MMIOH" , mmioh.s1.base, shift, mmioh.s1.m_io, + max_pnode, map_uc); + } +if (is_uv2_hub () && mmioh.s2.enable) { + shift =UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT ; +map_high ("MMIOH" , mmioh.s2.base, shift, mmioh.s2.m_io, max_pnode, map_uc); + } }static __init void map_low_mmrs (void )
@@ -736,13 +755,14 @@ void __init uv_system_init(void)unsigned long mmr_base, present, paddr;unsigned short pnode_mask, pnode_io_mask; +printk (KERN_INFO "UV: Found %s hub\n" ,is_uv1_hub () ?"UV1" :"UV2" );map_low_mmrs (); m_n_config.v =uv_read_local_mmr (UVH_RH_GAM_CONFIG_MMR ); m_val = m_n_config.s.m_skt; n_val = m_n_config.s.n_skt; mmioh.v =uv_read_local_mmr (UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR ); - n_io = mmioh.s.n_io; + n_io =is_uv1_hub () ? mmioh.s1.n_io : mmioh.s2.n_io; mmr_base =uv_read_local_mmr (UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR ) & ~UV_MMR_ENABLE ;
@@ -811,6 +831,8 @@ void __init uv_system_init(void)*/ uv_cpu_hub_info (cpu)->pnode_mask = pnode_mask;uv_cpu_hub_info (cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift; +uv_cpu_hub_info (cpu)->hub_revision = uv_hub_info->hub_revision; + pnode =uv_apicid_to_pnode (apicid); blade =boot_pnode_to_blade (pnode); lcpu = uv_blade_info[blade].nr_possible_cpus;
arch/x86/platform/uv/tlb_uv.c +114 -18
190 lines not on this page · raw message
arch/x86/platform/uv/uv_time.c +12 -4
@@ -99,8 +99,12 @@ static void uv_rtc_send_IPI(int cpu)/* Check for an RTC interrupt pending */ static int uv_intr_pending (int pnode) { -return uv_read_global_mmr64 (pnode,UVH_EVENT_OCCURRED0 ) & -UVH_EVENT_OCCURRED0_RTC1_MASK ; +if (is_uv1_hub ()) +return uv_read_global_mmr64 (pnode,UVH_EVENT_OCCURRED0 ) & +UV1H_EVENT_OCCURRED0_RTC1_MASK ; +else +return uv_read_global_mmr64 (pnode,UV2H_EVENT_OCCURRED2 ) & +UV2H_EVENT_OCCURRED2_RTC_1_MASK ; }/* Setup interrupt and return non-zero if early expiration occurred. */
@@ -114,8 +118,12 @@ static int uv_setup_intr(int cpu, u64 expires) UVH_RTC1_INT_CONFIG_M_MASK);uv_write_global_mmr64 (pnode,UVH_INT_CMPB ,-1L ); -uv_write_global_mmr64 (pnode,UVH_EVENT_OCCURRED0_ALIAS , -UVH_EVENT_OCCURRED0_RTC1_MASK ); +if (is_uv1_hub ()) +uv_write_global_mmr64 (pnode,UVH_EVENT_OCCURRED0_ALIAS , +UV1H_EVENT_OCCURRED0_RTC1_MASK ); +else +uv_write_global_mmr64 (pnode,UV2H_EVENT_OCCURRED2_ALIAS , +UV2H_EVENT_OCCURRED2_RTC_1_MASK ); val = (X86_PLATFORM_IPI_VECTOR <<UVH_RTC1_INT_CONFIG_VECTOR_SHFT ) | ((u64 )apicid <<UVH_RTC1_INT_CONFIG_APIC_ID_SHFT );