lkml.org 
[lkml]   [2016]   [May]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[tip:x86/platform] x86/platform/UV: Prep for UV4 MMR updates
    Commit-ID:  c443c03dd0d97620022483be6705ff611695a29c
    Gitweb: http://git.kernel.org/tip/c443c03dd0d97620022483be6705ff611695a29c
    Author: Mike Travis <travis@sgi.com>
    AuthorDate: Fri, 29 Apr 2016 16:54:07 -0500
    Committer: Ingo Molnar <mingo@kernel.org>
    CommitDate: Wed, 4 May 2016 08:48:47 +0200

    x86/platform/UV: Prep for UV4 MMR updates

    Cleanup patch to rearrange code and modify some defines so the next
    patch, the new UV4 MMR definitions can be merged cleanly.

    * Clean up the M/N related address constants (M is # of address bits per
    blade, N is the # of blade selection bits per SSI/partition).

    * Fix the lookup of the alias overlay addresses and NMI definitions to
    allow for flexibility in newer UV architecture types.

    Tested-by: John Estabrook <estabrook@sgi.com>
    Tested-by: Gary Kroening <gfk@sgi.com>
    Tested-by: Nathan Zimmer <nzimmer@sgi.com>
    Signed-off-by: Mike Travis <travis@sgi.com>
    Reviewed-by: Dimitri Sivanich <sivanich@sgi.com>
    Cc: Andrew Banman <abanman@sgi.com>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    Cc: Andy Lutomirski <luto@amacapital.net>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Brian Gerst <brgerst@gmail.com>
    Cc: Denys Vlasenko <dvlasenk@redhat.com>
    Cc: H. Peter Anvin <hpa@zytor.com>
    Cc: Len Brown <len.brown@intel.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Russ Anderson <rja@sgi.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Link: http://lkml.kernel.org/r/20160429215403.401604203@asylum.americas.sgi.com
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    ---
    arch/x86/include/asm/uv/uv_hub.h | 5 +
    arch/x86/kernel/apic/x2apic_uv_x.c | 208 ++++++++++++++++++++++---------------
    2 files changed, 129 insertions(+), 84 deletions(-)

    diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
    index 6660c09a..ffbc1c7 100644
    --- a/arch/x86/include/asm/uv/uv_hub.h
    +++ b/arch/x86/include/asm/uv/uv_hub.h
    @@ -635,9 +635,14 @@ extern void uv_nmi_setup(void);
    /* Newer SMM NMI handler, not present in all systems */
    #define UVH_NMI_MMRX UVH_EVENT_OCCURRED0
    #define UVH_NMI_MMRX_CLEAR UVH_EVENT_OCCURRED0_ALIAS
    +
    +#ifdef UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT
    +#define UVH_NMI_MMRX_SHIFT UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT
    +#else
    #define UVH_NMI_MMRX_SHIFT (is_uv1_hub() ? \
    UV1H_EVENT_OCCURRED0_EXTIO_INT0_SHFT :\
    UVXH_EVENT_OCCURRED0_EXTIO_INT0_SHFT)
    +#endif
    #define UVH_NMI_MMRX_TYPE "EXTIO_INT0"

    /* Non-zero indicates newer SMM NMI handler present */
    diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
    index 85c3849..3853c7b 100644
    --- a/arch/x86/kernel/apic/x2apic_uv_x.c
    +++ b/arch/x86/kernel/apic/x2apic_uv_x.c
    @@ -460,45 +460,38 @@ static __init int boot_pnode_to_blade(int pnode)
    BUG();
    }

    -struct redir_addr {
    - unsigned long redirect;
    - unsigned long alias;
    -};
    -
    +#define UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_LENGTH 3
    #define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT

    -static __initdata struct redir_addr redir_addrs[] = {
    - {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR},
    - {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR},
    - {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR},
    -};
    -
    -static unsigned char get_n_lshift(int m_val)
    -{
    - union uv3h_gr0_gam_gr_config_u m_gr_config;
    -
    - if (is_uv1_hub())
    - return m_val;
    -
    - if (is_uv2_hub())
    - return m_val == 40 ? 40 : 39;
    -
    - m_gr_config.v = uv_read_local_mmr(UV3H_GR0_GAM_GR_CONFIG);
    - return m_gr_config.s3.m_skt;
    -}
    -
    static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size)
    {
    union uvh_rh_gam_alias210_overlay_config_2_mmr_u alias;
    union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect;
    + unsigned long m_redirect;
    + unsigned long m_overlay;
    int i;

    - for (i = 0; i < ARRAY_SIZE(redir_addrs); i++) {
    - alias.v = uv_read_local_mmr(redir_addrs[i].alias);
    + for (i = 0; i < UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_LENGTH; i++) {
    + switch (i) {
    + case 0:
    + m_redirect = UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR;
    + m_overlay = UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR;
    + break;
    + case 1:
    + m_redirect = UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR;
    + m_overlay = UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR;
    + break;
    + case 2:
    + m_redirect = UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR;
    + m_overlay = UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR;
    + break;
    + }
    + alias.v = uv_read_local_mmr(m_overlay);
    if (alias.s.enable && alias.s.base == 0) {
    *size = (1UL << alias.s.m_alias);
    - redirect.v = uv_read_local_mmr(redir_addrs[i].redirect);
    - *base = (unsigned long)redirect.s.dest_base << DEST_SHIFT;
    + redirect.v = uv_read_local_mmr(m_redirect);
    + *base = (unsigned long)redirect.s.dest_base
    + << DEST_SHIFT;
    return;
    }
    }
    @@ -561,6 +554,8 @@ static __init void map_gru_high(int max_pnode)
    {
    union uvh_rh_gam_gru_overlay_config_mmr_u gru;
    int shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT;
    + unsigned long mask = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK;
    + unsigned long base;

    gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR);
    if (!gru.s.enable) {
    @@ -572,8 +567,9 @@ static __init void map_gru_high(int max_pnode)
    map_gru_distributed(gru.v);
    return;
    }
    - map_high("GRU", gru.s.base, shift, shift, max_pnode, map_wb);
    - gru_start_paddr = ((u64)gru.s.base << shift);
    + base = (gru.v & mask) >> shift;
    + map_high("GRU", base, shift, shift, max_pnode, map_wb);
    + gru_start_paddr = ((u64)base << shift);
    gru_end_paddr = gru_start_paddr + (1UL << shift) * (max_pnode + 1);
    }

    @@ -888,16 +884,89 @@ void uv_cpu_init(void)
    set_x2apic_extra_bits(uv_hub_info->pnode);
    }

    -void __init uv_system_init(void)
    +struct mn {
    + unsigned char m_val;
    + unsigned char n_val;
    + unsigned char m_shift;
    + unsigned char n_lshift;
    +};
    +
    +static void get_mn(struct mn *mnp)
    {
    - union uvh_rh_gam_config_mmr_u m_n_config;
    + union uvh_rh_gam_config_mmr_u m_n_config;
    + union uv3h_gr0_gam_gr_config_u m_gr_config;
    +
    + m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR);
    + mnp->n_val = m_n_config.s.n_skt;
    + if (is_uv4_hub()) {
    + mnp->m_val = 0;
    + mnp->n_lshift = 0;
    + } else if (is_uv3_hub()) {
    + mnp->m_val = m_n_config.s3.m_skt;
    + m_gr_config.v = uv_read_local_mmr(UV3H_GR0_GAM_GR_CONFIG);
    + mnp->n_lshift = m_gr_config.s3.m_skt;
    + } else if (is_uv2_hub()) {
    + mnp->m_val = m_n_config.s2.m_skt;
    + mnp->n_lshift = mnp->m_val == 40 ? 40 : 39;
    + } else if (is_uv1_hub()) {
    + mnp->m_val = m_n_config.s1.m_skt;
    + mnp->n_lshift = mnp->m_val;
    + }
    + mnp->m_shift = mnp->m_val ? 64 - mnp->m_val : 0;
    +}
    +
    +void __init uv_init_hub_info(struct uv_hub_info_s *hub_info)
    +{
    + struct mn mn = {0}; /* avoid unitialized warnings */
    union uvh_node_id_u node_id;
    - unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size;
    - int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val;
    - int gnode_extra, min_pnode = 999999, max_pnode = -1;
    - unsigned long mmr_base, present, paddr;
    - unsigned short pnode_mask;
    - unsigned char n_lshift;
    +
    + get_mn(&mn);
    + hub_info->m_val = mn.m_val;
    + hub_info->n_val = mn.n_val;
    + hub_info->m_shift = mn.m_shift;
    + hub_info->n_lshift = mn.n_lshift;
    +
    + hub_info->hub_revision = uv_hub_info->hub_revision;
    + hub_info->pnode_mask = (1 << mn.n_val) - 1;
    + hub_info->gpa_mask = (1UL << (mn.m_val + mn.n_val)) - 1;
    +
    + node_id.v = uv_read_local_mmr(UVH_NODE_ID);
    + hub_info->gnode_extra =
    + (node_id.s.node_id & ~((1 << mn.n_val) - 1)) >> 1;
    +
    + hub_info->gnode_upper =
    + ((unsigned long)hub_info->gnode_extra << mn.m_val);
    +
    + hub_info->global_mmr_base =
    + uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) &
    + ~UV_MMR_ENABLE;
    +
    + get_lowmem_redirect(
    + &hub_info->lowmem_remap_base, &hub_info->lowmem_remap_top);
    +
    + hub_info->apic_pnode_shift = uvh_apicid.s.pnode_shift;
    +
    + /* show system specific info */
    + pr_info("UV: N:%d M:%d m_shift:%d n_lshift:%d\n",
    + hub_info->n_val, hub_info->m_val,
    + hub_info->m_shift, hub_info->n_lshift);
    +
    + pr_info("UV: pnode_mask:0x%x gpa_mask:0x%lx apic_pns:%d\n",
    + hub_info->pnode_mask, hub_info->gpa_mask,
    + hub_info->apic_pnode_shift);
    +
    + pr_info("UV: gnode_upper:0x%lx gnode_extra:0x%x\n",
    + hub_info->gnode_upper, hub_info->gnode_extra);
    +
    + pr_info("UV: global MMR base 0x%lx\n", hub_info->global_mmr_base);
    +
    +}
    +
    +void __init uv_system_init(void)
    +{
    + struct uv_hub_info_s hub_info = {0};
    + int bytes, nid, cpu, pnode, blade, i, j;
    + int min_pnode = 999999, max_pnode = -1;
    char *hub = is_uv4_hub() ? "UV400" :
    is_uv3_hub() ? "UV300" :
    is_uv2_hub() ? "UV2000/3000" :
    @@ -913,23 +982,7 @@ void __init uv_system_init(void)
    if (is_uv1_hub())
    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;
    - pnode_mask = (1 << n_val) - 1;
    - n_lshift = get_n_lshift(m_val);
    - mmr_base =
    - uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) &
    - ~UV_MMR_ENABLE;
    -
    - node_id.v = uv_read_local_mmr(UVH_NODE_ID);
    - gnode_extra = (node_id.s.node_id & ~((1 << n_val) - 1)) >> 1;
    - gnode_upper = ((unsigned long)gnode_extra << m_val);
    - pr_info("UV: N:%d M:%d pnode_mask:0x%x gnode_upper/extra:0x%lx/0x%x n_lshift 0x%x\n",
    - n_val, m_val, pnode_mask, gnode_upper, gnode_extra,
    - n_lshift);
    -
    - pr_info("UV: global MMR base 0x%lx\n", mmr_base);
    + uv_init_hub_info(&hub_info);

    for(i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++)
    uv_possible_blades +=
    @@ -937,8 +990,9 @@ void __init uv_system_init(void)

    /* uv_num_possible_blades() is really the hub count */
    pr_info("UV: Found %d blades, %d hubs\n",
    - is_uv1_hub() ? uv_num_possible_blades() :
    - (uv_num_possible_blades() + 1) / 2,
    + is_uv1_hub() ?
    + uv_num_possible_blades() :
    + (uv_num_possible_blades() + 1) / 2,
    uv_num_possible_blades());

    bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades();
    @@ -948,7 +1002,6 @@ void __init uv_system_init(void)
    for (blade = 0; blade < uv_num_possible_blades(); blade++)
    uv_blade_info[blade].memory_nid = -1;

    - get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size);

    bytes = sizeof(uv_node_to_blade[0]) * num_possible_nodes();
    uv_node_to_blade = kmalloc(bytes, GFP_KERNEL);
    @@ -962,11 +1015,12 @@ void __init uv_system_init(void)

    blade = 0;
    for (i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) {
    - present = uv_read_local_mmr(UVH_NODE_PRESENT_TABLE + i * 8);
    + unsigned long present =
    + uv_read_local_mmr(UVH_NODE_PRESENT_TABLE + i * 8);
    for (j = 0; j < 64; j++) {
    if (!test_bit(j, &present))
    continue;
    - pnode = (i * 64 + j) & pnode_mask;
    + pnode = (i * 64 + j) & hub_info.pnode_mask;
    uv_blade_info[blade].pnode = pnode;
    uv_blade_info[blade].nr_possible_cpus = 0;
    uv_blade_info[blade].nr_online_cpus = 0;
    @@ -980,49 +1034,35 @@ void __init uv_system_init(void)
    uv_bios_init();
    uv_bios_get_sn_info(0, &uv_type, &sn_partition_id, &sn_coherency_id,
    &sn_region_size, &system_serial_number);
    + hub_info.coherency_domain_number = sn_coherency_id;
    uv_rtc_init();

    for_each_present_cpu(cpu) {
    int apicid = per_cpu(x86_cpu_to_apicid, cpu);
    + int nodeid = cpu_to_node(cpu);
    + int lcpu;

    - nid = cpu_to_node(cpu);
    - /*
    - * apic_pnode_shift must be set before calling uv_apicid_to_pnode();
    - */
    - 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;
    -
    - uv_cpu_hub_info(cpu)->m_shift = 64 - m_val;
    - uv_cpu_hub_info(cpu)->n_lshift = n_lshift;
    -
    + *uv_cpu_hub_info(cpu) = hub_info; /* common hub values */
    pnode = uv_apicid_to_pnode(apicid);
    blade = boot_pnode_to_blade(pnode);
    lcpu = uv_blade_info[blade].nr_possible_cpus;
    uv_blade_info[blade].nr_possible_cpus++;

    /* Any node on the blade, else will contain -1. */
    - uv_blade_info[blade].memory_nid = nid;
    + uv_blade_info[blade].memory_nid = nodeid;

    - uv_cpu_hub_info(cpu)->lowmem_remap_base = lowmem_redir_base;
    - uv_cpu_hub_info(cpu)->lowmem_remap_top = lowmem_redir_size;
    - uv_cpu_hub_info(cpu)->m_val = m_val;
    - uv_cpu_hub_info(cpu)->n_val = n_val;
    uv_cpu_hub_info(cpu)->numa_blade_id = blade;
    - uv_cpu_hub_info(cpu)->blade_processor_id = lcpu;
    uv_cpu_hub_info(cpu)->pnode = pnode;
    - uv_cpu_hub_info(cpu)->gpa_mask = (1UL << (m_val + n_val)) - 1;
    - uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
    - uv_cpu_hub_info(cpu)->gnode_extra = gnode_extra;
    - uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
    - uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id;
    uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid);
    - uv_node_to_blade[nid] = blade;
    + uv_cpu_hub_info(cpu)->blade_processor_id = lcpu;
    + uv_node_to_blade[nodeid] = blade;
    uv_cpu_to_blade[cpu] = blade;
    }

    /* Add blade/pnode info for nodes without cpus */
    for_each_online_node(nid) {
    + unsigned long paddr;
    +
    if (uv_node_to_blade[nid] >= 0)
    continue;
    paddr = node_start_pfn(nid) << PAGE_SHIFT;
    \
     
     \ /
      Last update: 2016-05-04 09:41    [W:4.376 / U:0.216 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site