mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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
					
				
					 11 changed files with 9 additions and 908 deletions
				
			
		| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in a new issue