Skip to content

Commit

Permalink
Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/tip/tip

* 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86: Skip cpus with apic-ids >= 255 in !x2apic_mode
  x86, x2apic: Allow "nox2apic" to disable x2apic mode setup by BIOS
  x86, x2apic: Fallback to xapic when BIOS doesn't setup interrupt-remapping
  x86, acpi: Skip acpi x2apic entries if the x2apic feature is not present
  x86, apic: Add probe() for apic_flat
  x86: Simplify code by removing a !SMP #ifdefs from 'struct cpuinfo_x86'
  x86: Convert per-cpu counter icr_read_retry_count into a member of irq_stat
  x86: Add per-cpu stat counter for APIC ICR read tries
  pci, x86/io-apic: Allow PCI_IOAPIC to be user configurable on x86
  x86: Fix the !CONFIG_NUMA build of the new CPU ID fixup code support
  x86: Add NumaChip support
  x86: Add x86_init platform override to fix up NUMA core numbering
  x86: Make flat_init_apic_ldr() available
  • Loading branch information
Linus Torvalds committed Jan 6, 2012
2 parents 376613e + c284b42 commit 67b0243
Show file tree
Hide file tree
Showing 29 changed files with 639 additions and 76 deletions.
13 changes: 13 additions & 0 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ config X86_EXTENDED_PLATFORM

If you enable this option then you'll be able to select support
for the following (non-PC) 64 bit x86 platforms:
Numascale NumaChip
ScaleMP vSMP
SGI Ultraviolet

Expand All @@ -350,6 +351,18 @@ config X86_EXTENDED_PLATFORM
endif
# This is an alphabetically sorted list of 64 bit extended platforms
# Please maintain the alphabetic order if and when there are additions
config X86_NUMACHIP
bool "Numascale NumaChip"
depends on X86_64
depends on X86_EXTENDED_PLATFORM
depends on NUMA
depends on SMP
depends on X86_X2APIC
depends on !EDAC_AMD64
---help---
Adds support for Numascale NumaChip large-SMP systems. Needed to
enable more than ~168 cores.
If you don't have one of these, you should say N here.

config X86_VSMP
bool "ScaleMP vSMP"
Expand Down
6 changes: 6 additions & 0 deletions arch/x86/include/asm/apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ static inline u64 native_x2apic_icr_read(void)
}

extern int x2apic_phys;
extern int x2apic_preenabled;
extern void check_x2apic(void);
extern void enable_x2apic(void);
extern void x2apic_icr_write(u32 low, u32 id);
Expand All @@ -198,6 +199,9 @@ static inline void x2apic_force_phys(void)
x2apic_phys = 1;
}
#else
static inline void disable_x2apic(void)
{
}
static inline void check_x2apic(void)
{
}
Expand All @@ -212,6 +216,7 @@ static inline void x2apic_force_phys(void)
{
}

#define nox2apic 0
#define x2apic_preenabled 0
#define x2apic_supported() 0
#endif
Expand Down Expand Up @@ -410,6 +415,7 @@ extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);
#endif

#ifdef CONFIG_X86_LOCAL_APIC

static inline u32 apic_read(u32 reg)
{
return apic->read(reg);
Expand Down
7 changes: 7 additions & 0 deletions arch/x86/include/asm/apic_flat_64.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef _ASM_X86_APIC_FLAT_64_H
#define _ASM_X86_APIC_FLAT_64_H

extern void flat_init_apic_ldr(void);

#endif

1 change: 1 addition & 0 deletions arch/x86/include/asm/apicdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@

#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
#define APIC_BASE_MSR 0x800
#define XAPIC_ENABLE (1UL << 11)
#define X2APIC_ENABLE (1UL << 10)

#ifdef CONFIG_X86_32
Expand Down
1 change: 1 addition & 0 deletions arch/x86/include/asm/hardirq.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ typedef struct {
#ifdef CONFIG_X86_LOCAL_APIC
unsigned int apic_timer_irqs; /* arch dependent */
unsigned int irq_spurious_count;
unsigned int icr_read_retry_count;
#endif
unsigned int x86_platform_ipis; /* arch dependent */
unsigned int apic_perf_irqs;
Expand Down
167 changes: 167 additions & 0 deletions arch/x86/include/asm/numachip/numachip_csr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Numascale NumaConnect-Specific Header file
*
* Copyright (C) 2011 Numascale AS. All rights reserved.
*
* Send feedback to <support@numascale.com>
*
*/

#ifndef _ASM_X86_NUMACHIP_NUMACHIP_CSR_H
#define _ASM_X86_NUMACHIP_NUMACHIP_CSR_H

#include <linux/numa.h>
#include <linux/percpu.h>
#include <linux/io.h>
#include <linux/swab.h>
#include <asm/types.h>
#include <asm/processor.h>

#define CSR_NODE_SHIFT 16
#define CSR_NODE_BITS(p) (((unsigned long)(p)) << CSR_NODE_SHIFT)
#define CSR_NODE_MASK 0x0fff /* 4K nodes */

/* 32K CSR space, b15 indicates geo/non-geo */
#define CSR_OFFSET_MASK 0x7fffUL

/* Global CSR space covers all 4K possible nodes with 64K CSR space per node */
#define NUMACHIP_GCSR_BASE 0x3fff00000000ULL
#define NUMACHIP_GCSR_LIM 0x3fff0fffffffULL
#define NUMACHIP_GCSR_SIZE (NUMACHIP_GCSR_LIM - NUMACHIP_GCSR_BASE + 1)

/*
* Local CSR space starts in global CSR space with "nodeid" = 0xfff0, however
* when using the direct mapping on x86_64, both start and size needs to be
* aligned with PMD_SIZE which is 2M
*/
#define NUMACHIP_LCSR_BASE 0x3ffffe000000ULL
#define NUMACHIP_LCSR_LIM 0x3fffffffffffULL
#define NUMACHIP_LCSR_SIZE (NUMACHIP_LCSR_LIM - NUMACHIP_LCSR_BASE + 1)

static inline void *gcsr_address(int node, unsigned long offset)
{
return __va(NUMACHIP_GCSR_BASE | (1UL << 15) |
CSR_NODE_BITS(node & CSR_NODE_MASK) | (offset & CSR_OFFSET_MASK));
}

static inline void *lcsr_address(unsigned long offset)
{
return __va(NUMACHIP_LCSR_BASE | (1UL << 15) |
CSR_NODE_BITS(0xfff0) | (offset & CSR_OFFSET_MASK));
}

static inline unsigned int read_gcsr(int node, unsigned long offset)
{
return swab32(readl(gcsr_address(node, offset)));
}

static inline void write_gcsr(int node, unsigned long offset, unsigned int val)
{
writel(swab32(val), gcsr_address(node, offset));
}

static inline unsigned int read_lcsr(unsigned long offset)
{
return swab32(readl(lcsr_address(offset)));
}

static inline void write_lcsr(unsigned long offset, unsigned int val)
{
writel(swab32(val), lcsr_address(offset));
}

/* ========================================================================= */
/* CSR_G0_STATE_CLEAR */
/* ========================================================================= */

#define CSR_G0_STATE_CLEAR (0x000 + (0 << 12))
union numachip_csr_g0_state_clear {
unsigned int v;
struct numachip_csr_g0_state_clear_s {
unsigned int _state:2;
unsigned int _rsvd_2_6:5;
unsigned int _lost:1;
unsigned int _rsvd_8_31:24;
} s;
};

/* ========================================================================= */
/* CSR_G0_NODE_IDS */
/* ========================================================================= */

#define CSR_G0_NODE_IDS (0x008 + (0 << 12))
union numachip_csr_g0_node_ids {
unsigned int v;
struct numachip_csr_g0_node_ids_s {
unsigned int _initialid:16;
unsigned int _nodeid:12;
unsigned int _rsvd_28_31:4;
} s;
};

/* ========================================================================= */
/* CSR_G3_EXT_IRQ_GEN */
/* ========================================================================= */

#define CSR_G3_EXT_IRQ_GEN (0x030 + (3 << 12))
union numachip_csr_g3_ext_irq_gen {
unsigned int v;
struct numachip_csr_g3_ext_irq_gen_s {
unsigned int _vector:8;
unsigned int _msgtype:3;
unsigned int _index:5;
unsigned int _destination_apic_id:16;
} s;
};

/* ========================================================================= */
/* CSR_G3_EXT_IRQ_STATUS */
/* ========================================================================= */

#define CSR_G3_EXT_IRQ_STATUS (0x034 + (3 << 12))
union numachip_csr_g3_ext_irq_status {
unsigned int v;
struct numachip_csr_g3_ext_irq_status_s {
unsigned int _result:32;
} s;
};

/* ========================================================================= */
/* CSR_G3_EXT_IRQ_DEST */
/* ========================================================================= */

#define CSR_G3_EXT_IRQ_DEST (0x038 + (3 << 12))
union numachip_csr_g3_ext_irq_dest {
unsigned int v;
struct numachip_csr_g3_ext_irq_dest_s {
unsigned int _irq:8;
unsigned int _rsvd_8_31:24;
} s;
};

/* ========================================================================= */
/* CSR_G3_NC_ATT_MAP_SELECT */
/* ========================================================================= */

#define CSR_G3_NC_ATT_MAP_SELECT (0x7fc + (3 << 12))
union numachip_csr_g3_nc_att_map_select {
unsigned int v;
struct numachip_csr_g3_nc_att_map_select_s {
unsigned int _upper_address_bits:4;
unsigned int _select_ram:4;
unsigned int _rsvd_8_31:24;
} s;
};

/* ========================================================================= */
/* CSR_G3_NC_ATT_MAP_SELECT_0-255 */
/* ========================================================================= */

#define CSR_G3_NC_ATT_MAP_SELECT_0 (0x800 + (3 << 12))

#endif /* _ASM_X86_NUMACHIP_NUMACHIP_CSR_H */

2 changes: 0 additions & 2 deletions arch/x86/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ struct cpuinfo_x86 {
u16 apicid;
u16 initial_apicid;
u16 x86_clflush_size;
#ifdef CONFIG_SMP
/* number of cores as seen by the OS: */
u16 booted_cores;
/* Physical processor id: */
Expand All @@ -110,7 +109,6 @@ struct cpuinfo_x86 {
u8 compute_unit_id;
/* Index into per_cpu list: */
u16 cpu_index;
#endif
u32 microcode;
} __attribute__((__aligned__(SMP_CACHE_BYTES)));

Expand Down
3 changes: 3 additions & 0 deletions arch/x86/include/asm/x86_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
struct mpc_bus;
struct mpc_cpu;
struct mpc_table;
struct cpuinfo_x86;

/**
* struct x86_init_mpparse - platform specific mpparse ops
Expand Down Expand Up @@ -147,6 +148,7 @@ struct x86_init_ops {
*/
struct x86_cpuinit_ops {
void (*setup_percpu_clockev)(void);
void (*fixup_cpu_id)(struct cpuinfo_x86 *c, int node);
};

/**
Expand Down Expand Up @@ -186,5 +188,6 @@ extern struct x86_msi_ops x86_msi;

extern void x86_init_noop(void);
extern void x86_init_uint_noop(unsigned int unused);
extern void x86_default_fixup_cpu_id(struct cpuinfo_x86 *c, int node);

#endif
10 changes: 8 additions & 2 deletions arch/x86/kernel/acpi/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ static int __init
acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
{
struct acpi_madt_local_x2apic *processor = NULL;
int apic_id;
u8 enabled;

processor = (struct acpi_madt_local_x2apic *)header;

Expand All @@ -227,6 +229,8 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)

acpi_table_print_madt_entry(header);

apic_id = processor->local_apic_id;
enabled = processor->lapic_flags & ACPI_MADT_ENABLED;
#ifdef CONFIG_X86_X2APIC
/*
* We need to register disabled CPU as well to permit
Expand All @@ -235,8 +239,10 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
* to not preallocating memory for all NR_CPUS
* when we use CPU hotplug.
*/
acpi_register_lapic(processor->local_apic_id, /* APIC ID */
processor->lapic_flags & ACPI_MADT_ENABLED);
if (!cpu_has_x2apic && (apic_id >= 0xff) && enabled)
printk(KERN_WARNING PREFIX "x2apic entry ignored\n");
else
acpi_register_lapic(apic_id, enabled);
#else
printk(KERN_WARNING PREFIX "x2apic entry ignored\n");
#endif
Expand Down
8 changes: 2 additions & 6 deletions arch/x86/kernel/amd_nb.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,14 @@ int amd_get_subcaches(int cpu)
{
struct pci_dev *link = node_to_amd_nb(amd_get_nb_id(cpu))->link;
unsigned int mask;
int cuid = 0;
int cuid;

if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING))
return 0;

pci_read_config_dword(link, 0x1d4, &mask);

#ifdef CONFIG_SMP
cuid = cpu_data(cpu).compute_unit_id;
#endif
return (mask >> (4 * cuid)) & 0xf;
}

Expand All @@ -141,7 +139,7 @@ int amd_set_subcaches(int cpu, int mask)
static unsigned int reset, ban;
struct amd_northbridge *nb = node_to_amd_nb(amd_get_nb_id(cpu));
unsigned int reg;
int cuid = 0;
int cuid;

if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING) || mask > 0xf)
return -EINVAL;
Expand All @@ -159,9 +157,7 @@ int amd_set_subcaches(int cpu, int mask)
pci_write_config_dword(nb->misc, 0x1b8, reg & ~0x180000);
}

#ifdef CONFIG_SMP
cuid = cpu_data(cpu).compute_unit_id;
#endif
mask <<= 4 * cuid;
mask |= (0xf ^ (1 << cuid)) << 26;

Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/apic/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ obj-$(CONFIG_SMP) += ipi.o

ifeq ($(CONFIG_X86_64),y)
# APIC probe will depend on the listing order here
obj-$(CONFIG_X86_NUMACHIP) += apic_numachip.o
obj-$(CONFIG_X86_UV) += x2apic_uv_x.o
obj-$(CONFIG_X86_X2APIC) += x2apic_phys.o
obj-$(CONFIG_X86_X2APIC) += x2apic_cluster.o
Expand Down
Loading

0 comments on commit 67b0243

Please sign in to comment.