x86, platforms: Remove NUMAQ
The NUMAQ support seems to be unmaintained, remove it. Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Cc: David Rientjes <rientjes@google.com> Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> Link: http://lkml.kernel.org/r/n/530CFD6C.7040705@zytor.com
This commit is contained in:
Родитель
c5f9ee3d66
Коммит
b5660ba76b
|
@ -346,7 +346,6 @@ config X86_EXTENDED_PLATFORM
|
|||
for the following (non-PC) 32 bit x86 platforms:
|
||||
Goldfish (Android emulator)
|
||||
AMD Elan
|
||||
NUMAQ (IBM/Sequent)
|
||||
RDC R-321x SoC
|
||||
SGI 320/540 (Visual Workstation)
|
||||
STA2X11-based (e.g. Northville)
|
||||
|
@ -487,32 +486,18 @@ config X86_32_NON_STANDARD
|
|||
depends on X86_32 && SMP
|
||||
depends on X86_EXTENDED_PLATFORM
|
||||
---help---
|
||||
This option compiles in the NUMAQ, bigsmp, and STA2X11 default
|
||||
subarchitectures. It is intended for a generic binary kernel. If you
|
||||
select them all, kernel will probe it one by one and will fallback to
|
||||
default.
|
||||
This option compiles in the bigsmp and STA2X11 default
|
||||
subarchitectures. It is intended for a generic binary
|
||||
kernel. If you select them all, kernel will probe it one by
|
||||
one and will fallback to default.
|
||||
|
||||
# Alphabetically sorted list of Non standard 32 bit platforms
|
||||
|
||||
config X86_NUMAQ
|
||||
bool "NUMAQ (IBM/Sequent)"
|
||||
depends on X86_32_NON_STANDARD
|
||||
depends on PCI
|
||||
select NUMA
|
||||
select X86_MPPARSE
|
||||
---help---
|
||||
This option is used for getting Linux to run on a NUMAQ (IBM/Sequent)
|
||||
NUMA multiquad box. This changes the way that processors are
|
||||
bootstrapped, and uses Clustered Logical APIC addressing mode instead
|
||||
of Flat Logical. You will need a new lynxer.elf file to flash your
|
||||
firmware with - send email to <Martin.Bligh@us.ibm.com>.
|
||||
|
||||
config X86_SUPPORTS_MEMORY_FAILURE
|
||||
def_bool y
|
||||
# MCE code calls memory_failure():
|
||||
depends on X86_MCE
|
||||
# On 32-bit this adds too big of NODES_SHIFT and we run out of page flags:
|
||||
depends on !X86_NUMAQ
|
||||
# On 32-bit SPARSEMEM adds too big of SECTIONS_WIDTH:
|
||||
depends on X86_64 || !SPARSEMEM
|
||||
select ARCH_SUPPORTS_MEMORY_FAILURE
|
||||
|
@ -783,7 +768,7 @@ config NR_CPUS
|
|||
range 2 8192 if SMP && !MAXSMP && CPUMASK_OFFSTACK && X86_64
|
||||
default "1" if !SMP
|
||||
default "8192" if MAXSMP
|
||||
default "32" if SMP && (X86_NUMAQ || X86_BIGSMP)
|
||||
default "32" if SMP && X86_BIGSMP
|
||||
default "8" if SMP
|
||||
---help---
|
||||
This allows you to specify the maximum number of CPUs which this
|
||||
|
@ -1064,13 +1049,11 @@ config X86_CPUID
|
|||
|
||||
choice
|
||||
prompt "High Memory Support"
|
||||
default HIGHMEM64G if X86_NUMAQ
|
||||
default HIGHMEM4G
|
||||
depends on X86_32
|
||||
|
||||
config NOHIGHMEM
|
||||
bool "off"
|
||||
depends on !X86_NUMAQ
|
||||
---help---
|
||||
Linux can use up to 64 Gigabytes of physical memory on x86 systems.
|
||||
However, the address space of 32-bit x86 processors is only 4
|
||||
|
@ -1107,7 +1090,6 @@ config NOHIGHMEM
|
|||
|
||||
config HIGHMEM4G
|
||||
bool "4GB"
|
||||
depends on !X86_NUMAQ
|
||||
---help---
|
||||
Select this if you have a 32-bit processor and between 1 and 4
|
||||
gigabytes of physical RAM.
|
||||
|
@ -1199,8 +1181,8 @@ config DIRECT_GBPAGES
|
|||
config NUMA
|
||||
bool "Numa Memory Allocation and Scheduler Support"
|
||||
depends on SMP
|
||||
depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || X86_BIGSMP))
|
||||
default y if (X86_NUMAQ || X86_BIGSMP)
|
||||
depends on X86_64 || (X86_32 && HIGHMEM64G && X86_BIGSMP)
|
||||
default y if X86_BIGSMP
|
||||
---help---
|
||||
Enable NUMA (Non Uniform Memory Access) support.
|
||||
|
||||
|
@ -1211,8 +1193,7 @@ config NUMA
|
|||
For 64-bit this is recommended if the system is Intel Core i7
|
||||
(or later), AMD Opteron, or EM64T NUMA.
|
||||
|
||||
For 32-bit this is only needed on (rare) 32-bit-only platforms
|
||||
that support NUMA topologies, such as NUMAQ, or if you boot a 32-bit
|
||||
For 32-bit this is only needed if you boot a 32-bit
|
||||
kernel on a 64-bit NUMA platform.
|
||||
|
||||
Otherwise, you should say N.
|
||||
|
@ -1258,7 +1239,6 @@ config NODES_SHIFT
|
|||
range 1 10
|
||||
default "10" if MAXSMP
|
||||
default "6" if X86_64
|
||||
default "4" if X86_NUMAQ
|
||||
default "3"
|
||||
depends on NEED_MULTIPLE_NODES
|
||||
---help---
|
||||
|
|
|
@ -363,7 +363,7 @@ config X86_P6_NOP
|
|||
|
||||
config X86_TSC
|
||||
def_bool y
|
||||
depends on ((MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) && !X86_NUMAQ) || X86_64
|
||||
depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) || X86_64
|
||||
|
||||
config X86_CMPXCHG64
|
||||
def_bool y
|
||||
|
|
|
@ -11,9 +11,6 @@
|
|||
#ifdef CONFIG_NUMA
|
||||
extern struct pglist_data *node_data[];
|
||||
#define NODE_DATA(nid) (node_data[nid])
|
||||
|
||||
#include <asm/numaq.h>
|
||||
|
||||
#endif /* CONFIG_NUMA */
|
||||
|
||||
#ifdef CONFIG_DISCONTIGMEM
|
||||
|
|
|
@ -25,12 +25,6 @@ extern int pic_mode;
|
|||
|
||||
extern unsigned int def_to_bigsmp;
|
||||
|
||||
#ifdef CONFIG_X86_NUMAQ
|
||||
extern int mp_bus_id_to_node[MAX_MP_BUSSES];
|
||||
extern int mp_bus_id_to_local[MAX_MP_BUSSES];
|
||||
extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
|
||||
#endif
|
||||
|
||||
#else /* CONFIG_X86_64: */
|
||||
|
||||
#define MAX_MP_BUSSES 256
|
||||
|
|
|
@ -1,171 +0,0 @@
|
|||
/*
|
||||
* Written by: Patricia Gaughen, IBM Corporation
|
||||
*
|
||||
* Copyright (C) 2002, IBM Corp.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* Send feedback to <gone@us.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef _ASM_X86_NUMAQ_H
|
||||
#define _ASM_X86_NUMAQ_H
|
||||
|
||||
#ifdef CONFIG_X86_NUMAQ
|
||||
|
||||
extern int found_numaq;
|
||||
extern int numaq_numa_init(void);
|
||||
extern int pci_numaq_init(void);
|
||||
|
||||
extern void *xquad_portio;
|
||||
|
||||
#define XQUAD_PORTIO_BASE 0xfe400000
|
||||
#define XQUAD_PORTIO_QUAD 0x40000 /* 256k per quad. */
|
||||
#define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port)
|
||||
|
||||
/*
|
||||
* SYS_CFG_DATA_PRIV_ADDR, struct eachquadmem, and struct sys_cfg_data are the
|
||||
*/
|
||||
#define SYS_CFG_DATA_PRIV_ADDR 0x0009d000 /* place for scd in private
|
||||
quad space */
|
||||
|
||||
/*
|
||||
* Communication area for each processor on lynxer-processor tests.
|
||||
*
|
||||
* NOTE: If you change the size of this eachproc structure you need
|
||||
* to change the definition for EACH_QUAD_SIZE.
|
||||
*/
|
||||
struct eachquadmem {
|
||||
unsigned int priv_mem_start; /* Starting address of this */
|
||||
/* quad's private memory. */
|
||||
/* This is always 0. */
|
||||
/* In MB. */
|
||||
unsigned int priv_mem_size; /* Size of this quad's */
|
||||
/* private memory. */
|
||||
/* In MB. */
|
||||
unsigned int low_shrd_mem_strp_start;/* Starting address of this */
|
||||
/* quad's low shared block */
|
||||
/* (untranslated). */
|
||||
/* In MB. */
|
||||
unsigned int low_shrd_mem_start; /* Starting address of this */
|
||||
/* quad's low shared memory */
|
||||
/* (untranslated). */
|
||||
/* In MB. */
|
||||
unsigned int low_shrd_mem_size; /* Size of this quad's low */
|
||||
/* shared memory. */
|
||||
/* In MB. */
|
||||
unsigned int lmmio_copb_start; /* Starting address of this */
|
||||
/* quad's local memory */
|
||||
/* mapped I/O in the */
|
||||
/* compatibility OPB. */
|
||||
/* In MB. */
|
||||
unsigned int lmmio_copb_size; /* Size of this quad's local */
|
||||
/* memory mapped I/O in the */
|
||||
/* compatibility OPB. */
|
||||
/* In MB. */
|
||||
unsigned int lmmio_nopb_start; /* Starting address of this */
|
||||
/* quad's local memory */
|
||||
/* mapped I/O in the */
|
||||
/* non-compatibility OPB. */
|
||||
/* In MB. */
|
||||
unsigned int lmmio_nopb_size; /* Size of this quad's local */
|
||||
/* memory mapped I/O in the */
|
||||
/* non-compatibility OPB. */
|
||||
/* In MB. */
|
||||
unsigned int io_apic_0_start; /* Starting address of I/O */
|
||||
/* APIC 0. */
|
||||
unsigned int io_apic_0_sz; /* Size I/O APIC 0. */
|
||||
unsigned int io_apic_1_start; /* Starting address of I/O */
|
||||
/* APIC 1. */
|
||||
unsigned int io_apic_1_sz; /* Size I/O APIC 1. */
|
||||
unsigned int hi_shrd_mem_start; /* Starting address of this */
|
||||
/* quad's high shared memory.*/
|
||||
/* In MB. */
|
||||
unsigned int hi_shrd_mem_size; /* Size of this quad's high */
|
||||
/* shared memory. */
|
||||
/* In MB. */
|
||||
unsigned int mps_table_addr; /* Address of this quad's */
|
||||
/* MPS tables from BIOS, */
|
||||
/* in system space.*/
|
||||
unsigned int lcl_MDC_pio_addr; /* Port-I/O address for */
|
||||
/* local access of MDC. */
|
||||
unsigned int rmt_MDC_mmpio_addr; /* MM-Port-I/O address for */
|
||||
/* remote access of MDC. */
|
||||
unsigned int mm_port_io_start; /* Starting address of this */
|
||||
/* quad's memory mapped Port */
|
||||
/* I/O space. */
|
||||
unsigned int mm_port_io_size; /* Size of this quad's memory*/
|
||||
/* mapped Port I/O space. */
|
||||
unsigned int mm_rmt_io_apic_start; /* Starting address of this */
|
||||
/* quad's memory mapped */
|
||||
/* remote I/O APIC space. */
|
||||
unsigned int mm_rmt_io_apic_size; /* Size of this quad's memory*/
|
||||
/* mapped remote I/O APIC */
|
||||
/* space. */
|
||||
unsigned int mm_isa_start; /* Starting address of this */
|
||||
/* quad's memory mapped ISA */
|
||||
/* space (contains MDC */
|
||||
/* memory space). */
|
||||
unsigned int mm_isa_size; /* Size of this quad's memory*/
|
||||
/* mapped ISA space (contains*/
|
||||
/* MDC memory space). */
|
||||
unsigned int rmt_qmi_addr; /* Remote addr to access QMI.*/
|
||||
unsigned int lcl_qmi_addr; /* Local addr to access QMI. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Note: This structure must be NOT be changed unless the multiproc and
|
||||
* OS are changed to reflect the new structure.
|
||||
*/
|
||||
struct sys_cfg_data {
|
||||
unsigned int quad_id;
|
||||
unsigned int bsp_proc_id; /* Boot Strap Processor in this quad. */
|
||||
unsigned int scd_version; /* Version number of this table. */
|
||||
unsigned int first_quad_id;
|
||||
unsigned int quads_present31_0; /* 1 bit for each quad */
|
||||
unsigned int quads_present63_32; /* 1 bit for each quad */
|
||||
unsigned int config_flags;
|
||||
unsigned int boot_flags;
|
||||
unsigned int csr_start_addr; /* Absolute value (not in MB) */
|
||||
unsigned int csr_size; /* Absolute value (not in MB) */
|
||||
unsigned int lcl_apic_start_addr; /* Absolute value (not in MB) */
|
||||
unsigned int lcl_apic_size; /* Absolute value (not in MB) */
|
||||
unsigned int low_shrd_mem_base; /* 0 or 512MB or 1GB */
|
||||
unsigned int low_shrd_mem_quad_offset; /* 0,128M,256M,512M,1G */
|
||||
/* may not be totally populated */
|
||||
unsigned int split_mem_enbl; /* 0 for no low shared memory */
|
||||
unsigned int mmio_sz; /* Size of total system memory mapped I/O */
|
||||
/* (in MB). */
|
||||
unsigned int quad_spin_lock; /* Spare location used for quad */
|
||||
/* bringup. */
|
||||
unsigned int nonzero55; /* For checksumming. */
|
||||
unsigned int nonzeroaa; /* For checksumming. */
|
||||
unsigned int scd_magic_number;
|
||||
unsigned int system_type;
|
||||
unsigned int checksum;
|
||||
/*
|
||||
* memory configuration area for each quad
|
||||
*/
|
||||
struct eachquadmem eq[MAX_NUMNODES]; /* indexed by quad id */
|
||||
};
|
||||
|
||||
void numaq_tsc_disable(void);
|
||||
|
||||
#endif /* CONFIG_X86_NUMAQ */
|
||||
#endif /* _ASM_X86_NUMAQ_H */
|
||||
|
|
@ -18,7 +18,6 @@ obj-y += apic_flat_64.o
|
|||
endif
|
||||
|
||||
# APIC probe will depend on the listing order here
|
||||
obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
|
||||
obj-$(CONFIG_X86_BIGSMP) += bigsmp_32.o
|
||||
|
||||
# For 32bit, probe_32 need to be listed last
|
||||
|
|
|
@ -1,524 +0,0 @@
|
|||
/*
|
||||
* Written by: Patricia Gaughen, IBM Corporation
|
||||
*
|
||||
* Copyright (C) 2002, IBM Corp.
|
||||
* Copyright (C) 2009, Red Hat, Inc., Ingo Molnar
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
||||
* NON INFRINGEMENT. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* Send feedback to <gone@us.ibm.com>
|
||||
*/
|
||||
#include <linux/nodemask.h>
|
||||
#include <linux/topology.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/threads.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mmzone.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/numa.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/processor.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/mpspec.h>
|
||||
#include <asm/numaq.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/apic.h>
|
||||
#include <asm/e820.h>
|
||||
#include <asm/ipi.h>
|
||||
|
||||
int found_numaq;
|
||||
|
||||
/*
|
||||
* Have to match translation table entries to main table entries by counter
|
||||
* hence the mpc_record variable .... can't see a less disgusting way of
|
||||
* doing this ....
|
||||
*/
|
||||
struct mpc_trans {
|
||||
unsigned char mpc_type;
|
||||
unsigned char trans_len;
|
||||
unsigned char trans_type;
|
||||
unsigned char trans_quad;
|
||||
unsigned char trans_global;
|
||||
unsigned char trans_local;
|
||||
unsigned short trans_reserved;
|
||||
};
|
||||
|
||||
static int mpc_record;
|
||||
|
||||
static struct mpc_trans *translation_table[MAX_MPC_ENTRY];
|
||||
|
||||
int mp_bus_id_to_node[MAX_MP_BUSSES];
|
||||
int mp_bus_id_to_local[MAX_MP_BUSSES];
|
||||
int quad_local_to_mp_bus_id[NR_CPUS/4][4];
|
||||
|
||||
|
||||
static inline void numaq_register_node(int node, struct sys_cfg_data *scd)
|
||||
{
|
||||
struct eachquadmem *eq = scd->eq + node;
|
||||
u64 start = (u64)(eq->hi_shrd_mem_start - eq->priv_mem_size) << 20;
|
||||
u64 end = (u64)(eq->hi_shrd_mem_start + eq->hi_shrd_mem_size) << 20;
|
||||
int ret;
|
||||
|
||||
node_set(node, numa_nodes_parsed);
|
||||
ret = numa_add_memblk(node, start, end);
|
||||
BUG_ON(ret < 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: smp_dump_qct()
|
||||
*
|
||||
* Description: gets memory layout from the quad config table. This
|
||||
* function also updates numa_nodes_parsed with the nodes (quads) present.
|
||||
*/
|
||||
static void __init smp_dump_qct(void)
|
||||
{
|
||||
struct sys_cfg_data *scd;
|
||||
int node;
|
||||
|
||||
scd = (void *)__va(SYS_CFG_DATA_PRIV_ADDR);
|
||||
|
||||
for_each_node(node) {
|
||||
if (scd->quads_present31_0 & (1 << node))
|
||||
numaq_register_node(node, scd);
|
||||
}
|
||||
}
|
||||
|
||||
void numaq_tsc_disable(void)
|
||||
{
|
||||
if (!found_numaq)
|
||||
return;
|
||||
|
||||
if (num_online_nodes() > 1) {
|
||||
printk(KERN_DEBUG "NUMAQ: disabling TSC\n");
|
||||
setup_clear_cpu_cap(X86_FEATURE_TSC);
|
||||
}
|
||||
}
|
||||
|
||||
static void __init numaq_tsc_init(void)
|
||||
{
|
||||
numaq_tsc_disable();
|
||||
}
|
||||
|
||||
static inline int generate_logical_apicid(int quad, int phys_apicid)
|
||||
{
|
||||
return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1);
|
||||
}
|
||||
|
||||
/* x86_quirks member */
|
||||
static int mpc_apic_id(struct mpc_cpu *m)
|
||||
{
|
||||
int quad = translation_table[mpc_record]->trans_quad;
|
||||
int logical_apicid = generate_logical_apicid(quad, m->apicid);
|
||||
|
||||
printk(KERN_DEBUG
|
||||
"Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n",
|
||||
m->apicid, (m->cpufeature & CPU_FAMILY_MASK) >> 8,
|
||||
(m->cpufeature & CPU_MODEL_MASK) >> 4,
|
||||
m->apicver, quad, logical_apicid);
|
||||
|
||||
return logical_apicid;
|
||||
}
|
||||
|
||||
/* x86_quirks member */
|
||||
static void mpc_oem_bus_info(struct mpc_bus *m, char *name)
|
||||
{
|
||||
int quad = translation_table[mpc_record]->trans_quad;
|
||||
int local = translation_table[mpc_record]->trans_local;
|
||||
|
||||
mp_bus_id_to_node[m->busid] = quad;
|
||||
mp_bus_id_to_local[m->busid] = local;
|
||||
|
||||
printk(KERN_INFO "Bus #%d is %s (node %d)\n", m->busid, name, quad);
|
||||
}
|
||||
|
||||
/* x86_quirks member */
|
||||
static void mpc_oem_pci_bus(struct mpc_bus *m)
|
||||
{
|
||||
int quad = translation_table[mpc_record]->trans_quad;
|
||||
int local = translation_table[mpc_record]->trans_local;
|
||||
|
||||
quad_local_to_mp_bus_id[quad][local] = m->busid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from mpparse code.
|
||||
* mode = 0: prescan
|
||||
* mode = 1: one mpc entry scanned
|
||||
*/
|
||||
static void numaq_mpc_record(unsigned int mode)
|
||||
{
|
||||
if (!mode)
|
||||
mpc_record = 0;
|
||||
else
|
||||
mpc_record++;
|
||||
}
|
||||
|
||||
static void __init MP_translation_info(struct mpc_trans *m)
|
||||
{
|
||||
printk(KERN_INFO
|
||||
"Translation: record %d, type %d, quad %d, global %d, local %d\n",
|
||||
mpc_record, m->trans_type, m->trans_quad, m->trans_global,
|
||||
m->trans_local);
|
||||
|
||||
if (mpc_record >= MAX_MPC_ENTRY)
|
||||
printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n");
|
||||
else
|
||||
translation_table[mpc_record] = m; /* stash this for later */
|
||||
|
||||
if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad))
|
||||
node_set_online(m->trans_quad);
|
||||
}
|
||||
|
||||
static int __init mpf_checksum(unsigned char *mp, int len)
|
||||
{
|
||||
int sum = 0;
|
||||
|
||||
while (len--)
|
||||
sum += *mp++;
|
||||
|
||||
return sum & 0xFF;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read/parse the MPC oem tables
|
||||
*/
|
||||
static void __init smp_read_mpc_oem(struct mpc_table *mpc)
|
||||
{
|
||||
struct mpc_oemtable *oemtable = (void *)(long)mpc->oemptr;
|
||||
int count = sizeof(*oemtable); /* the header size */
|
||||
unsigned char *oemptr = ((unsigned char *)oemtable) + count;
|
||||
|
||||
mpc_record = 0;
|
||||
printk(KERN_INFO
|
||||
"Found an OEM MPC table at %8p - parsing it...\n", oemtable);
|
||||
|
||||
if (memcmp(oemtable->signature, MPC_OEM_SIGNATURE, 4)) {
|
||||
printk(KERN_WARNING
|
||||
"SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
|
||||
oemtable->signature[0], oemtable->signature[1],
|
||||
oemtable->signature[2], oemtable->signature[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mpf_checksum((unsigned char *)oemtable, oemtable->length)) {
|
||||
printk(KERN_WARNING "SMP oem mptable: checksum error!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
while (count < oemtable->length) {
|
||||
switch (*oemptr) {
|
||||
case MP_TRANSLATION:
|
||||
{
|
||||
struct mpc_trans *m = (void *)oemptr;
|
||||
|
||||
MP_translation_info(m);
|
||||
oemptr += sizeof(*m);
|
||||
count += sizeof(*m);
|
||||
++mpc_record;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printk(KERN_WARNING
|
||||
"Unrecognised OEM table entry type! - %d\n",
|
||||
(int)*oemptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static __init void early_check_numaq(void)
|
||||
{
|
||||
/*
|
||||
* get boot-time SMP configuration:
|
||||
*/
|
||||
if (smp_found_config)
|
||||
early_get_smp_config();
|
||||
|
||||
if (found_numaq) {
|
||||
x86_init.mpparse.mpc_record = numaq_mpc_record;
|
||||
x86_init.mpparse.setup_ioapic_ids = x86_init_noop;
|
||||
x86_init.mpparse.mpc_apic_id = mpc_apic_id;
|
||||
x86_init.mpparse.smp_read_mpc_oem = smp_read_mpc_oem;
|
||||
x86_init.mpparse.mpc_oem_pci_bus = mpc_oem_pci_bus;
|
||||
x86_init.mpparse.mpc_oem_bus_info = mpc_oem_bus_info;
|
||||
x86_init.timers.tsc_pre_init = numaq_tsc_init;
|
||||
x86_init.pci.init = pci_numaq_init;
|
||||
}
|
||||
}
|
||||
|
||||
int __init numaq_numa_init(void)
|
||||
{
|
||||
early_check_numaq();
|
||||
if (!found_numaq)
|
||||
return -ENOENT;
|
||||
smp_dump_qct();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define NUMAQ_APIC_DFR_VALUE (APIC_DFR_CLUSTER)
|
||||
|
||||
static inline unsigned int numaq_get_apic_id(unsigned long x)
|
||||
{
|
||||
return (x >> 24) & 0x0F;
|
||||
}
|
||||
|
||||
static inline void numaq_send_IPI_mask(const struct cpumask *mask, int vector)
|
||||
{
|
||||
default_send_IPI_mask_sequence_logical(mask, vector);
|
||||
}
|
||||
|
||||
static inline void numaq_send_IPI_allbutself(int vector)
|
||||
{
|
||||
default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector);
|
||||
}
|
||||
|
||||
static inline void numaq_send_IPI_all(int vector)
|
||||
{
|
||||
numaq_send_IPI_mask(cpu_online_mask, vector);
|
||||
}
|
||||
|
||||
#define NUMAQ_TRAMPOLINE_PHYS_LOW (0x8)
|
||||
#define NUMAQ_TRAMPOLINE_PHYS_HIGH (0xa)
|
||||
|
||||
/*
|
||||
* Because we use NMIs rather than the INIT-STARTUP sequence to
|
||||
* bootstrap the CPUs, the APIC may be in a weird state. Kick it:
|
||||
*/
|
||||
static inline void numaq_smp_callin_clear_local_apic(void)
|
||||
{
|
||||
clear_local_APIC();
|
||||
}
|
||||
|
||||
static inline const struct cpumask *numaq_target_cpus(void)
|
||||
{
|
||||
return cpu_all_mask;
|
||||
}
|
||||
|
||||
static unsigned long numaq_check_apicid_used(physid_mask_t *map, int apicid)
|
||||
{
|
||||
return physid_isset(apicid, *map);
|
||||
}
|
||||
|
||||
static inline unsigned long numaq_check_apicid_present(int bit)
|
||||
{
|
||||
return physid_isset(bit, phys_cpu_present_map);
|
||||
}
|
||||
|
||||
static inline int numaq_apic_id_registered(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline void numaq_init_apic_ldr(void)
|
||||
{
|
||||
/* Already done in NUMA-Q firmware */
|
||||
}
|
||||
|
||||
static inline void numaq_setup_apic_routing(void)
|
||||
{
|
||||
printk(KERN_INFO
|
||||
"Enabling APIC mode: NUMA-Q. Using %d I/O APICs\n",
|
||||
nr_ioapics);
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip adding the timer int on secondary nodes, which causes
|
||||
* a small but painful rift in the time-space continuum.
|
||||
*/
|
||||
static inline int numaq_multi_timer_check(int apic, int irq)
|
||||
{
|
||||
return apic != 0 && irq == 0;
|
||||
}
|
||||
|
||||
static inline void numaq_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
|
||||
{
|
||||
/* We don't have a good way to do this yet - hack */
|
||||
return physids_promote(0xFUL, retmap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Supporting over 60 cpus on NUMA-Q requires a locality-dependent
|
||||
* cpu to APIC ID relation to properly interact with the intelligent
|
||||
* mode of the cluster controller.
|
||||
*/
|
||||
static inline int numaq_cpu_present_to_apicid(int mps_cpu)
|
||||
{
|
||||
if (mps_cpu < 60)
|
||||
return ((mps_cpu >> 2) << 4) | (1 << (mps_cpu & 0x3));
|
||||
else
|
||||
return BAD_APICID;
|
||||
}
|
||||
|
||||
static inline int numaq_apicid_to_node(int logical_apicid)
|
||||
{
|
||||
return logical_apicid >> 4;
|
||||
}
|
||||
|
||||
static int numaq_numa_cpu_node(int cpu)
|
||||
{
|
||||
int logical_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
|
||||
|
||||
if (logical_apicid != BAD_APICID)
|
||||
return numaq_apicid_to_node(logical_apicid);
|
||||
return NUMA_NO_NODE;
|
||||
}
|
||||
|
||||
static void numaq_apicid_to_cpu_present(int logical_apicid, physid_mask_t *retmap)
|
||||
{
|
||||
int node = numaq_apicid_to_node(logical_apicid);
|
||||
int cpu = __ffs(logical_apicid & 0xf);
|
||||
|
||||
physid_set_mask_of_physid(cpu + 4*node, retmap);
|
||||
}
|
||||
|
||||
/* Where the IO area was mapped on multiquad, always 0 otherwise */
|
||||
void *xquad_portio;
|
||||
|
||||
static inline int numaq_check_phys_apicid_present(int phys_apicid)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We use physical apicids here, not logical, so just return the default
|
||||
* physical broadcast to stop people from breaking us
|
||||
*/
|
||||
static int
|
||||
numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
|
||||
const struct cpumask *andmask,
|
||||
unsigned int *apicid)
|
||||
{
|
||||
*apicid = 0x0F;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */
|
||||
static inline int numaq_phys_pkg_id(int cpuid_apic, int index_msb)
|
||||
{
|
||||
return cpuid_apic >> index_msb;
|
||||
}
|
||||
|
||||
static int
|
||||
numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
|
||||
{
|
||||
if (strncmp(oem, "IBM NUMA", 8))
|
||||
printk(KERN_ERR "Warning! Not a NUMA-Q system!\n");
|
||||
else
|
||||
found_numaq = 1;
|
||||
|
||||
return found_numaq;
|
||||
}
|
||||
|
||||
static int probe_numaq(void)
|
||||
{
|
||||
/* already know from get_memcfg_numaq() */
|
||||
return found_numaq;
|
||||
}
|
||||
|
||||
static void numaq_setup_portio_remap(void)
|
||||
{
|
||||
int num_quads = num_online_nodes();
|
||||
|
||||
if (num_quads <= 1)
|
||||
return;
|
||||
|
||||
printk(KERN_INFO
|
||||
"Remapping cross-quad port I/O for %d quads\n", num_quads);
|
||||
|
||||
xquad_portio = ioremap(XQUAD_PORTIO_BASE, num_quads*XQUAD_PORTIO_QUAD);
|
||||
|
||||
printk(KERN_INFO
|
||||
"xquad_portio vaddr 0x%08lx, len %08lx\n",
|
||||
(u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD);
|
||||
}
|
||||
|
||||
/* Use __refdata to keep false positive warning calm. */
|
||||
static struct apic __refdata apic_numaq = {
|
||||
|
||||
.name = "NUMAQ",
|
||||
.probe = probe_numaq,
|
||||
.acpi_madt_oem_check = NULL,
|
||||
.apic_id_valid = default_apic_id_valid,
|
||||
.apic_id_registered = numaq_apic_id_registered,
|
||||
|
||||
.irq_delivery_mode = dest_LowestPrio,
|
||||
/* physical delivery on LOCAL quad: */
|
||||
.irq_dest_mode = 0,
|
||||
|
||||
.target_cpus = numaq_target_cpus,
|
||||
.disable_esr = 1,
|
||||
.dest_logical = APIC_DEST_LOGICAL,
|
||||
.check_apicid_used = numaq_check_apicid_used,
|
||||
.check_apicid_present = numaq_check_apicid_present,
|
||||
|
||||
.vector_allocation_domain = flat_vector_allocation_domain,
|
||||
.init_apic_ldr = numaq_init_apic_ldr,
|
||||
|
||||
.ioapic_phys_id_map = numaq_ioapic_phys_id_map,
|
||||
.setup_apic_routing = numaq_setup_apic_routing,
|
||||
.multi_timer_check = numaq_multi_timer_check,
|
||||
.cpu_present_to_apicid = numaq_cpu_present_to_apicid,
|
||||
.apicid_to_cpu_present = numaq_apicid_to_cpu_present,
|
||||
.setup_portio_remap = numaq_setup_portio_remap,
|
||||
.check_phys_apicid_present = numaq_check_phys_apicid_present,
|
||||
.enable_apic_mode = NULL,
|
||||
.phys_pkg_id = numaq_phys_pkg_id,
|
||||
.mps_oem_check = numaq_mps_oem_check,
|
||||
|
||||
.get_apic_id = numaq_get_apic_id,
|
||||
.set_apic_id = NULL,
|
||||
.apic_id_mask = 0x0F << 24,
|
||||
|
||||
.cpu_mask_to_apicid_and = numaq_cpu_mask_to_apicid_and,
|
||||
|
||||
.send_IPI_mask = numaq_send_IPI_mask,
|
||||
.send_IPI_mask_allbutself = NULL,
|
||||
.send_IPI_allbutself = numaq_send_IPI_allbutself,
|
||||
.send_IPI_all = numaq_send_IPI_all,
|
||||
.send_IPI_self = default_send_IPI_self,
|
||||
|
||||
.wakeup_secondary_cpu = wakeup_secondary_cpu_via_nmi,
|
||||
.trampoline_phys_low = NUMAQ_TRAMPOLINE_PHYS_LOW,
|
||||
.trampoline_phys_high = NUMAQ_TRAMPOLINE_PHYS_HIGH,
|
||||
|
||||
/* We don't do anything here because we use NMI's to boot instead */
|
||||
.wait_for_init_deassert = false,
|
||||
.smp_callin_clear_local_apic = numaq_smp_callin_clear_local_apic,
|
||||
.inquire_remote_apic = NULL,
|
||||
|
||||
.read = native_apic_mem_read,
|
||||
.write = native_apic_mem_write,
|
||||
.eoi_write = native_apic_mem_write,
|
||||
.icr_read = native_apic_icr_read,
|
||||
.icr_write = native_apic_icr_write,
|
||||
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
|
||||
|
||||
.x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid,
|
||||
.x86_32_numa_cpu_node = numaq_numa_cpu_node,
|
||||
};
|
||||
|
||||
apic_driver(apic_numaq);
|
|
@ -267,10 +267,6 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_NUMAQ
|
||||
numaq_tsc_disable();
|
||||
#endif
|
||||
|
||||
intel_smp_check(c);
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -687,10 +687,6 @@ static int __init dummy_numa_init(void)
|
|||
void __init x86_numa_init(void)
|
||||
{
|
||||
if (!numa_off) {
|
||||
#ifdef CONFIG_X86_NUMAQ
|
||||
if (!numa_init(numaq_numa_init))
|
||||
return;
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI_NUMA
|
||||
if (!numa_init(x86_acpi_numa_init))
|
||||
return;
|
||||
|
|
|
@ -13,7 +13,6 @@ obj-y += legacy.o irq.o
|
|||
|
||||
obj-$(CONFIG_STA2X11) += sta2x11-fixup.o
|
||||
|
||||
obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
|
||||
obj-$(CONFIG_X86_NUMACHIP) += numachip.o
|
||||
|
||||
obj-$(CONFIG_X86_INTEL_MID) += intel_mid_pci.o
|
||||
|
|
|
@ -1,165 +0,0 @@
|
|||
/*
|
||||
* numaq_32.c - Low-level PCI access for NUMA-Q machines
|
||||
*/
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/nodemask.h>
|
||||
#include <asm/apic.h>
|
||||
#include <asm/mpspec.h>
|
||||
#include <asm/pci_x86.h>
|
||||
#include <asm/numaq.h>
|
||||
|
||||
#define BUS2QUAD(global) (mp_bus_id_to_node[global])
|
||||
|
||||
#define BUS2LOCAL(global) (mp_bus_id_to_local[global])
|
||||
|
||||
#define QUADLOCAL2BUS(quad,local) (quad_local_to_mp_bus_id[quad][local])
|
||||
|
||||
#define PCI_CONF1_MQ_ADDRESS(bus, devfn, reg) \
|
||||
(0x80000000 | (BUS2LOCAL(bus) << 16) | (devfn << 8) | (reg & ~3))
|
||||
|
||||
static void write_cf8(unsigned bus, unsigned devfn, unsigned reg)
|
||||
{
|
||||
unsigned val = PCI_CONF1_MQ_ADDRESS(bus, devfn, reg);
|
||||
if (xquad_portio)
|
||||
writel(val, XQUAD_PORT_ADDR(0xcf8, BUS2QUAD(bus)));
|
||||
else
|
||||
outl(val, 0xCF8);
|
||||
}
|
||||
|
||||
static int pci_conf1_mq_read(unsigned int seg, unsigned int bus,
|
||||
unsigned int devfn, int reg, int len, u32 *value)
|
||||
{
|
||||
unsigned long flags;
|
||||
void *adr __iomem = XQUAD_PORT_ADDR(0xcfc, BUS2QUAD(bus));
|
||||
|
||||
WARN_ON(seg);
|
||||
if (!value || (bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255))
|
||||
return -EINVAL;
|
||||
|
||||
raw_spin_lock_irqsave(&pci_config_lock, flags);
|
||||
|
||||
write_cf8(bus, devfn, reg);
|
||||
|
||||
switch (len) {
|
||||
case 1:
|
||||
if (xquad_portio)
|
||||
*value = readb(adr + (reg & 3));
|
||||
else
|
||||
*value = inb(0xCFC + (reg & 3));
|
||||
break;
|
||||
case 2:
|
||||
if (xquad_portio)
|
||||
*value = readw(adr + (reg & 2));
|
||||
else
|
||||
*value = inw(0xCFC + (reg & 2));
|
||||
break;
|
||||
case 4:
|
||||
if (xquad_portio)
|
||||
*value = readl(adr);
|
||||
else
|
||||
*value = inl(0xCFC);
|
||||
break;
|
||||
}
|
||||
|
||||
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pci_conf1_mq_write(unsigned int seg, unsigned int bus,
|
||||
unsigned int devfn, int reg, int len, u32 value)
|
||||
{
|
||||
unsigned long flags;
|
||||
void *adr __iomem = XQUAD_PORT_ADDR(0xcfc, BUS2QUAD(bus));
|
||||
|
||||
WARN_ON(seg);
|
||||
if ((bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255))
|
||||
return -EINVAL;
|
||||
|
||||
raw_spin_lock_irqsave(&pci_config_lock, flags);
|
||||
|
||||
write_cf8(bus, devfn, reg);
|
||||
|
||||
switch (len) {
|
||||
case 1:
|
||||
if (xquad_portio)
|
||||
writeb(value, adr + (reg & 3));
|
||||
else
|
||||
outb((u8)value, 0xCFC + (reg & 3));
|
||||
break;
|
||||
case 2:
|
||||
if (xquad_portio)
|
||||
writew(value, adr + (reg & 2));
|
||||
else
|
||||
outw((u16)value, 0xCFC + (reg & 2));
|
||||
break;
|
||||
case 4:
|
||||
if (xquad_portio)
|
||||
writel(value, adr + reg);
|
||||
else
|
||||
outl((u32)value, 0xCFC);
|
||||
break;
|
||||
}
|
||||
|
||||
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef PCI_CONF1_MQ_ADDRESS
|
||||
|
||||
static const struct pci_raw_ops pci_direct_conf1_mq = {
|
||||
.read = pci_conf1_mq_read,
|
||||
.write = pci_conf1_mq_write
|
||||
};
|
||||
|
||||
|
||||
static void pci_fixup_i450nx(struct pci_dev *d)
|
||||
{
|
||||
/*
|
||||
* i450NX -- Find and scan all secondary buses on all PXB's.
|
||||
*/
|
||||
int pxb, reg;
|
||||
u8 busno, suba, subb;
|
||||
int quad = BUS2QUAD(d->bus->number);
|
||||
|
||||
dev_info(&d->dev, "searching for i450NX host bridges\n");
|
||||
reg = 0xd0;
|
||||
for(pxb=0; pxb<2; pxb++) {
|
||||
pci_read_config_byte(d, reg++, &busno);
|
||||
pci_read_config_byte(d, reg++, &suba);
|
||||
pci_read_config_byte(d, reg++, &subb);
|
||||
dev_dbg(&d->dev, "i450NX PXB %d: %02x/%02x/%02x\n",
|
||||
pxb, busno, suba, subb);
|
||||
if (busno) {
|
||||
/* Bus A */
|
||||
pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, busno));
|
||||
}
|
||||
if (suba < subb) {
|
||||
/* Bus B */
|
||||
pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, suba+1));
|
||||
}
|
||||
}
|
||||
pcibios_last_bus = -1;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx);
|
||||
|
||||
int __init pci_numaq_init(void)
|
||||
{
|
||||
int quad;
|
||||
|
||||
raw_pci_ops = &pci_direct_conf1_mq;
|
||||
|
||||
pcibios_scan_root(0);
|
||||
if (num_online_nodes() > 1)
|
||||
for_each_online_node(quad) {
|
||||
if (quad == 0)
|
||||
continue;
|
||||
printk("Scanning PCI bus %d for quad %d\n",
|
||||
QUADLOCAL2BUS(quad,0), quad);
|
||||
pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, 0));
|
||||
}
|
||||
return 0;
|
||||
}
|
Загрузка…
Ссылка в новой задаче