mirror of https://gitee.com/openkylin/linux.git
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:
parent
c5f9ee3d66
commit
b5660ba76b
|
@ -346,7 +346,6 @@ config X86_EXTENDED_PLATFORM
|
||||||
for the following (non-PC) 32 bit x86 platforms:
|
for the following (non-PC) 32 bit x86 platforms:
|
||||||
Goldfish (Android emulator)
|
Goldfish (Android emulator)
|
||||||
AMD Elan
|
AMD Elan
|
||||||
NUMAQ (IBM/Sequent)
|
|
||||||
RDC R-321x SoC
|
RDC R-321x SoC
|
||||||
SGI 320/540 (Visual Workstation)
|
SGI 320/540 (Visual Workstation)
|
||||||
STA2X11-based (e.g. Northville)
|
STA2X11-based (e.g. Northville)
|
||||||
|
@ -487,32 +486,18 @@ config X86_32_NON_STANDARD
|
||||||
depends on X86_32 && SMP
|
depends on X86_32 && SMP
|
||||||
depends on X86_EXTENDED_PLATFORM
|
depends on X86_EXTENDED_PLATFORM
|
||||||
---help---
|
---help---
|
||||||
This option compiles in the NUMAQ, bigsmp, and STA2X11 default
|
This option compiles in the bigsmp and STA2X11 default
|
||||||
subarchitectures. It is intended for a generic binary kernel. If you
|
subarchitectures. It is intended for a generic binary
|
||||||
select them all, kernel will probe it one by one and will fallback to
|
kernel. If you select them all, kernel will probe it one by
|
||||||
default.
|
one and will fallback to default.
|
||||||
|
|
||||||
# Alphabetically sorted list of Non standard 32 bit platforms
|
# 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
|
config X86_SUPPORTS_MEMORY_FAILURE
|
||||||
def_bool y
|
def_bool y
|
||||||
# MCE code calls memory_failure():
|
# MCE code calls memory_failure():
|
||||||
depends on X86_MCE
|
depends on X86_MCE
|
||||||
# On 32-bit this adds too big of NODES_SHIFT and we run out of page flags:
|
# 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:
|
# On 32-bit SPARSEMEM adds too big of SECTIONS_WIDTH:
|
||||||
depends on X86_64 || !SPARSEMEM
|
depends on X86_64 || !SPARSEMEM
|
||||||
select ARCH_SUPPORTS_MEMORY_FAILURE
|
select ARCH_SUPPORTS_MEMORY_FAILURE
|
||||||
|
@ -783,7 +768,7 @@ config NR_CPUS
|
||||||
range 2 8192 if SMP && !MAXSMP && CPUMASK_OFFSTACK && X86_64
|
range 2 8192 if SMP && !MAXSMP && CPUMASK_OFFSTACK && X86_64
|
||||||
default "1" if !SMP
|
default "1" if !SMP
|
||||||
default "8192" if MAXSMP
|
default "8192" if MAXSMP
|
||||||
default "32" if SMP && (X86_NUMAQ || X86_BIGSMP)
|
default "32" if SMP && X86_BIGSMP
|
||||||
default "8" if SMP
|
default "8" if SMP
|
||||||
---help---
|
---help---
|
||||||
This allows you to specify the maximum number of CPUs which this
|
This allows you to specify the maximum number of CPUs which this
|
||||||
|
@ -1064,13 +1049,11 @@ config X86_CPUID
|
||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "High Memory Support"
|
prompt "High Memory Support"
|
||||||
default HIGHMEM64G if X86_NUMAQ
|
|
||||||
default HIGHMEM4G
|
default HIGHMEM4G
|
||||||
depends on X86_32
|
depends on X86_32
|
||||||
|
|
||||||
config NOHIGHMEM
|
config NOHIGHMEM
|
||||||
bool "off"
|
bool "off"
|
||||||
depends on !X86_NUMAQ
|
|
||||||
---help---
|
---help---
|
||||||
Linux can use up to 64 Gigabytes of physical memory on x86 systems.
|
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
|
However, the address space of 32-bit x86 processors is only 4
|
||||||
|
@ -1107,7 +1090,6 @@ config NOHIGHMEM
|
||||||
|
|
||||||
config HIGHMEM4G
|
config HIGHMEM4G
|
||||||
bool "4GB"
|
bool "4GB"
|
||||||
depends on !X86_NUMAQ
|
|
||||||
---help---
|
---help---
|
||||||
Select this if you have a 32-bit processor and between 1 and 4
|
Select this if you have a 32-bit processor and between 1 and 4
|
||||||
gigabytes of physical RAM.
|
gigabytes of physical RAM.
|
||||||
|
@ -1199,8 +1181,8 @@ config DIRECT_GBPAGES
|
||||||
config NUMA
|
config NUMA
|
||||||
bool "Numa Memory Allocation and Scheduler Support"
|
bool "Numa Memory Allocation and Scheduler Support"
|
||||||
depends on SMP
|
depends on SMP
|
||||||
depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || X86_BIGSMP))
|
depends on X86_64 || (X86_32 && HIGHMEM64G && X86_BIGSMP)
|
||||||
default y if (X86_NUMAQ || X86_BIGSMP)
|
default y if X86_BIGSMP
|
||||||
---help---
|
---help---
|
||||||
Enable NUMA (Non Uniform Memory Access) support.
|
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
|
For 64-bit this is recommended if the system is Intel Core i7
|
||||||
(or later), AMD Opteron, or EM64T NUMA.
|
(or later), AMD Opteron, or EM64T NUMA.
|
||||||
|
|
||||||
For 32-bit this is only needed on (rare) 32-bit-only platforms
|
For 32-bit this is only needed if you boot a 32-bit
|
||||||
that support NUMA topologies, such as NUMAQ, or if you boot a 32-bit
|
|
||||||
kernel on a 64-bit NUMA platform.
|
kernel on a 64-bit NUMA platform.
|
||||||
|
|
||||||
Otherwise, you should say N.
|
Otherwise, you should say N.
|
||||||
|
@ -1258,7 +1239,6 @@ config NODES_SHIFT
|
||||||
range 1 10
|
range 1 10
|
||||||
default "10" if MAXSMP
|
default "10" if MAXSMP
|
||||||
default "6" if X86_64
|
default "6" if X86_64
|
||||||
default "4" if X86_NUMAQ
|
|
||||||
default "3"
|
default "3"
|
||||||
depends on NEED_MULTIPLE_NODES
|
depends on NEED_MULTIPLE_NODES
|
||||||
---help---
|
---help---
|
||||||
|
|
|
@ -363,7 +363,7 @@ config X86_P6_NOP
|
||||||
|
|
||||||
config X86_TSC
|
config X86_TSC
|
||||||
def_bool y
|
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
|
config X86_CMPXCHG64
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
|
@ -11,9 +11,6 @@
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
extern struct pglist_data *node_data[];
|
extern struct pglist_data *node_data[];
|
||||||
#define NODE_DATA(nid) (node_data[nid])
|
#define NODE_DATA(nid) (node_data[nid])
|
||||||
|
|
||||||
#include <asm/numaq.h>
|
|
||||||
|
|
||||||
#endif /* CONFIG_NUMA */
|
#endif /* CONFIG_NUMA */
|
||||||
|
|
||||||
#ifdef CONFIG_DISCONTIGMEM
|
#ifdef CONFIG_DISCONTIGMEM
|
||||||
|
|
|
@ -25,12 +25,6 @@ extern int pic_mode;
|
||||||
|
|
||||||
extern unsigned int def_to_bigsmp;
|
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: */
|
#else /* CONFIG_X86_64: */
|
||||||
|
|
||||||
#define MAX_MP_BUSSES 256
|
#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
|
endif
|
||||||
|
|
||||||
# APIC probe will depend on the listing order here
|
# APIC probe will depend on the listing order here
|
||||||
obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
|
|
||||||
obj-$(CONFIG_X86_BIGSMP) += bigsmp_32.o
|
obj-$(CONFIG_X86_BIGSMP) += bigsmp_32.o
|
||||||
|
|
||||||
# For 32bit, probe_32 need to be listed last
|
# 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
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_X86_NUMAQ
|
|
||||||
numaq_tsc_disable();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
intel_smp_check(c);
|
intel_smp_check(c);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -687,10 +687,6 @@ static int __init dummy_numa_init(void)
|
||||||
void __init x86_numa_init(void)
|
void __init x86_numa_init(void)
|
||||||
{
|
{
|
||||||
if (!numa_off) {
|
if (!numa_off) {
|
||||||
#ifdef CONFIG_X86_NUMAQ
|
|
||||||
if (!numa_init(numaq_numa_init))
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_ACPI_NUMA
|
#ifdef CONFIG_ACPI_NUMA
|
||||||
if (!numa_init(x86_acpi_numa_init))
|
if (!numa_init(x86_acpi_numa_init))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -13,7 +13,6 @@ obj-y += legacy.o irq.o
|
||||||
|
|
||||||
obj-$(CONFIG_STA2X11) += sta2x11-fixup.o
|
obj-$(CONFIG_STA2X11) += sta2x11-fixup.o
|
||||||
|
|
||||||
obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
|
|
||||||
obj-$(CONFIG_X86_NUMACHIP) += numachip.o
|
obj-$(CONFIG_X86_NUMACHIP) += numachip.o
|
||||||
|
|
||||||
obj-$(CONFIG_X86_INTEL_MID) += intel_mid_pci.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;
|
|
||||||
}
|
|
Loading…
Reference in New Issue