Commit 9828805c authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] es7000 subarch update for generic arch

From: "Protasevich, Natalie" <Natalie.Protasevich@UNISYS.com>

This is ES7000 sub architecture update.  It makes ES7000 a part of the
generic architecture, so the single compiled kernel will be able to choose
a correct set of parameters, routines ("genapic"), and a boot path.  It
uses criteria provided by the subarch for platform identification.  In case
of ES7000, it is a unique product/vendor string in the ACPI/MP OEM table,
and server control registers.  The patch is confined to only es7000 subarch
and generic subarch.  It was tested on ES7000 as well as generic Intel 8x
Xeon system.  Andi Kleen has reviewed the changes.
parent 1dd5cc77
...@@ -102,10 +102,10 @@ config X86_VISWS ...@@ -102,10 +102,10 @@ config X86_VISWS
and vice versa. See <file:Documentation/sgi-visws.txt> for details. and vice versa. See <file:Documentation/sgi-visws.txt> for details.
config X86_GENERICARCH config X86_GENERICARCH
bool "Generic architecture (Summit, bigsmp, default)" bool "Generic architecture (Summit, bigsmp, ES7000, default)"
depends on SMP depends on SMP
help help
This option compiles in the Summit, bigsmp, default subarchitectures. This option compiles in the Summit, bigsmp, ES7000, default subarchitectures.
It is intended for a generic binary kernel. It is intended for a generic binary kernel.
config X86_ES7000 config X86_ES7000
......
...@@ -92,7 +92,8 @@ core-$(CONFIG_X86_GENERICARCH) += arch/i386/mach-generic/ ...@@ -92,7 +92,8 @@ core-$(CONFIG_X86_GENERICARCH) += arch/i386/mach-generic/
# ES7000 subarch support # ES7000 subarch support
mflags-$(CONFIG_X86_ES7000) := -Iinclude/asm-i386/mach-es7000 mflags-$(CONFIG_X86_ES7000) := -Iinclude/asm-i386/mach-es7000
mcore-$(CONFIG_X86_ES7000) := mach-es7000 mcore-$(CONFIG_X86_ES7000) := mach-default
core-$(CONFIG_X86_ES7000) := arch/i386/mach-es7000/
# default subarch .h files # default subarch .h files
mflags-y += -Iinclude/asm-i386/mach-default mflags-y += -Iinclude/asm-i386/mach-default
......
...@@ -2,4 +2,5 @@ ...@@ -2,4 +2,5 @@
# Makefile for the linux kernel. # Makefile for the linux kernel.
# #
obj-y := setup.o topology.o es7000.o obj-$(CONFIG_X86_ES7000) := es7000plat.o
obj-$(CONFIG_X86_GENERICARCH) := es7000plat.o
...@@ -104,7 +104,7 @@ struct mip_reg { ...@@ -104,7 +104,7 @@ struct mip_reg {
#define MIP_SW_APIC 0x1020b #define MIP_SW_APIC 0x1020b
#define MIP_FUNC(VALUE) (VALUE & 0xff) #define MIP_FUNC(VALUE) (VALUE & 0xff)
extern void parse_unisys_oem (char *oemptr, int oem_entries); extern int parse_unisys_oem (char *oemptr, int oem_entries);
extern int find_unisys_acpi_oem_table(unsigned long *oem_addr, int *length); extern int find_unisys_acpi_oem_table(unsigned long *oem_addr, int *length);
extern int es7000_start_cpu(int cpu, unsigned long eip); extern int es7000_start_cpu(int cpu, unsigned long eip);
extern void es7000_sw_apic(void); extern void es7000_sw_apic(void);
/* /*
* Written by: Garry Forsgren, Unisys Corporation * Written by: Garry Forsgren, Unisys Corporation
* Natalie Protasevich, Unisys Corporation * Natalie Protasevich, Unisys Corporation
* This file contains the code to configure and interface * This file contains the code to configure and interface
* with Unisys ES7000 series hardware system manager. * with Unisys ES7000 series hardware system manager.
* *
* Copyright (c) 2003 Unisys Corporation. All Rights Reserved. * Copyright (c) 2003 Unisys Corporation. All Rights Reserved.
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* with this program; if not, write the Free Software Foundation, Inc., 59 * with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA. * Temple Place - Suite 330, Boston MA 02111-1307, USA.
* *
* Contact information: Unisys Corporation, Township Line & Union Meeting * Contact information: Unisys Corporation, Township Line & Union Meeting
* Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or: * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or:
* *
* http://www.unisys.com * http://www.unisys.com
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
*/ */
volatile unsigned long *psai = NULL; volatile unsigned long *psai = NULL;
struct mip_reg *mip_reg; struct mip_reg *mip_reg;
struct mip_reg *host_reg; struct mip_reg *host_reg;
int mip_port; int mip_port;
unsigned long mip_addr, host_addr; unsigned long mip_addr, host_addr;
...@@ -55,14 +55,14 @@ unsigned long mip_addr, host_addr; ...@@ -55,14 +55,14 @@ unsigned long mip_addr, host_addr;
* Parse the OEM Table * Parse the OEM Table
*/ */
void __init int __init
parse_unisys_oem (char *oemptr, int oem_entries) parse_unisys_oem (char *oemptr, int oem_entries)
{ {
int i; int i;
int success = 0; int success = 0;
unsigned char type, size; unsigned char type, size;
unsigned long val; unsigned long val;
char *tp = NULL; char *tp = NULL;
struct psai *psaip = NULL; struct psai *psaip = NULL;
struct mip_reg_info *mi; struct mip_reg_info *mi;
struct mip_reg *host, *mip; struct mip_reg *host, *mip;
...@@ -87,9 +87,9 @@ parse_unisys_oem (char *oemptr, int oem_entries) ...@@ -87,9 +87,9 @@ parse_unisys_oem (char *oemptr, int oem_entries)
mip_addr = val; mip_addr = val;
mip = (struct mip_reg *)val; mip = (struct mip_reg *)val;
mip_reg = __va(mip); mip_reg = __va(mip);
Dprintk("es7000_mipcfg: host_reg = 0x%lx \n", Dprintk("es7000_mipcfg: host_reg = 0x%lx \n",
(unsigned long)host_reg); (unsigned long)host_reg);
Dprintk("es7000_mipcfg: mip_reg = 0x%lx \n", Dprintk("es7000_mipcfg: mip_reg = 0x%lx \n",
(unsigned long)mip_reg); (unsigned long)mip_reg);
success++; success++;
break; break;
...@@ -117,11 +117,11 @@ parse_unisys_oem (char *oemptr, int oem_entries) ...@@ -117,11 +117,11 @@ parse_unisys_oem (char *oemptr, int oem_entries)
printk("\nEnabling ES7000 specific features...\n"); printk("\nEnabling ES7000 specific features...\n");
es7000_plat = 1; es7000_plat = 1;
} }
return; return es7000_plat;
} }
int __init int __init
find_unisys_acpi_oem_table(unsigned long *oem_addr, int *length) find_unisys_acpi_oem_table(unsigned long *oem_addr, int *length)
{ {
struct acpi_table_rsdp *rsdp = NULL; struct acpi_table_rsdp *rsdp = NULL;
unsigned long rsdp_phys = 0; unsigned long rsdp_phys = 0;
...@@ -180,7 +180,7 @@ es7000_spin(int n) ...@@ -180,7 +180,7 @@ es7000_spin(int n)
{ {
int i = 0; int i = 0;
while (i++ < n) while (i++ < n)
rep_nop(); rep_nop();
} }
...@@ -221,7 +221,7 @@ es7000_mip_write(struct mip_reg *mip_reg) ...@@ -221,7 +221,7 @@ es7000_mip_write(struct mip_reg *mip_reg)
return status; return status;
} }
int int
es7000_start_cpu(int cpu, unsigned long eip) es7000_start_cpu(int cpu, unsigned long eip)
{ {
unsigned long vect = 0, psaival = 0; unsigned long vect = 0, psaival = 0;
...@@ -241,7 +241,7 @@ es7000_start_cpu(int cpu, unsigned long eip) ...@@ -241,7 +241,7 @@ es7000_start_cpu(int cpu, unsigned long eip)
} }
int int
es7000_stop_cpu(int cpu) es7000_stop_cpu(int cpu)
{ {
int startup; int startup;
...@@ -273,7 +273,7 @@ es7000_sw_apic() ...@@ -273,7 +273,7 @@ es7000_sw_apic()
es7000_mip_reg.off_0 = MIP_SW_APIC; es7000_mip_reg.off_0 = MIP_SW_APIC;
es7000_mip_reg.off_38 = (MIP_VALID); es7000_mip_reg.off_38 = (MIP_VALID);
while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0) while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0)
printk("es7000_sw_apic: command failed, status = %x\n", printk("es7000_sw_apic: command failed, status = %x\n",
mip_status); mip_status);
return; return;
} }
......
/*
* Machine specific setup for es7000
*/
#include <linux/config.h>
#include <linux/smp.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/acpi.h>
#include <asm/arch_hooks.h>
/**
* pre_intr_init_hook - initialisation prior to setting up interrupt vectors
*
* Description:
* Perform any necessary interrupt initialisation prior to setting up
* the "ordinary" interrupt call gates. For legacy reasons, the ISA
* interrupts should be initialised here if the machine emulates a PC
* in any way.
**/void __init pre_intr_init_hook(void)
{
init_ISA_irqs();
}
/*
* IRQ2 is cascade interrupt to second interrupt controller
*/
static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL};
/**
* intr_init_hook - post gate setup interrupt initialisation
*
* Description:
* Fill in any interrupts that may have been left out by the general
* init_IRQ() routine. interrupts having to do with the machine rather
* than the devices on the I/O bus (like APIC interrupts in intel MP
* systems) are started here.
**/
void __init intr_init_hook(void)
{
#ifdef CONFIG_X86_LOCAL_APIC
apic_intr_init();
#endif
if (!acpi_ioapic)
setup_irq(2, &irq2);
}
/**
* pre_setup_arch_hook - hook called prior to any setup_arch() execution
*
* Description:
* generally used to activate any machine specific identification
* routines that may be needed before setup_arch() runs. On VISWS
* this is used to get the board revision and type.
**/
void __init pre_setup_arch_hook(void)
{
}
/**
* trap_init_hook - initialise system specific traps
*
* Description:
* Called as the final act of trap_init(). Used in VISWS to initialise
* the various board specific APIC traps.
**/
void __init trap_init_hook(void)
{
}
static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
/**
* time_init_hook - do any specific initialisations for the system timer.
*
* Description:
* Must plug the system timer interrupt source at HZ into the IRQ listed
* in irq_vectors.h:TIMER_IRQ
**/
void __init time_init_hook(void)
{
setup_irq(0, &irq0);
}
#ifdef CONFIG_MCA
/**
* mca_nmi_hook - hook into MCA specific NMI chain
*
* Description:
* The MCA (Microchannel Arcitecture) has an NMI chain for NMI sources
* along the MCA bus. Use this to hook into that chain if you will need
* it.
**/
void __init mca_nmi_hook(void)
{
/* If I recall correctly, there's a whole bunch of other things that
* we can do to check for NMI problems, but that's all I know about
* at the moment.
*/
printk("NMI generated from unknown source!\n");
}
#endif
/*
* arch/i386/mach-generic/topology.c - Populate driverfs with topology information
*
* Written by: Matthew Dobson, IBM Corporation
* Original Code: Paul Dorwin, IBM Corporation, Patrick Mochel, OSDL
*
* 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 <colpatch@us.ibm.com>
*/
#include <linux/init.h>
#include <linux/smp.h>
#include <asm/cpu.h>
struct i386_cpu cpu_devices[NR_CPUS];
#ifdef CONFIG_NUMA
#include <linux/mmzone.h>
#include <asm/node.h>
struct i386_node node_devices[MAX_NUMNODES];
static int __init topology_init(void)
{
int i;
for (i = 0; i < num_online_nodes(); i++)
arch_register_node(i);
for (i = 0; i < NR_CPUS; i++)
if (cpu_possible(i)) arch_register_cpu(i);
return 0;
}
#else /* !CONFIG_NUMA */
static int __init topology_init(void)
{
int i;
for (i = 0; i < NR_CPUS; i++)
if (cpu_possible(i)) arch_register_cpu(i);
return 0;
}
#endif /* CONFIG_NUMA */
subsys_initcall(topology_init);
...@@ -4,15 +4,4 @@ ...@@ -4,15 +4,4 @@
EXTRA_CFLAGS += -I../kernel EXTRA_CFLAGS += -I../kernel
obj-y := probe.o summit.o bigsmp.o default.o obj-y := probe.o summit.o bigsmp.o es7000.o default.o ../mach-es7000/
#
# Makefile for the generic architecture
#
EXTRA_CFLAGS += -I../kernel
obj-y := probe.o summit.o bigsmp.o default.o
/*
* APIC driver for the Unisys ES7000 chipset.
*/
#define APIC_DEFINITION 1
#include <linux/config.h>
#include <linux/threads.h>
#include <linux/cpumask.h>
#include <asm/mpspec.h>
#include <asm/genapic.h>
#include <asm/fixmap.h>
#include <asm/apicdef.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/smp.h>
#include <linux/init.h>
#include <asm/mach-es7000/mach_apicdef.h>
#include <asm/mach-es7000/mach_apic.h>
#include <asm/mach-es7000/mach_ipi.h>
#include <asm/mach-es7000/mach_mpparse.h>
#include <asm/mach-es7000/mach_wakecpu.h>
static __init int probe_es7000(void)
{
/* probed later in mptable/ACPI hooks */
return 0;
}
struct genapic apic_es7000 = APIC_INIT("es7000", probe_es7000);
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
extern struct genapic apic_summit; extern struct genapic apic_summit;
extern struct genapic apic_bigsmp; extern struct genapic apic_bigsmp;
extern struct genapic apic_es7000;
extern struct genapic apic_default; extern struct genapic apic_default;
struct genapic *genapic = &apic_default; struct genapic *genapic = &apic_default;
...@@ -24,6 +25,7 @@ struct genapic *genapic = &apic_default; ...@@ -24,6 +25,7 @@ struct genapic *genapic = &apic_default;
struct genapic *apic_probe[] __initdata = { struct genapic *apic_probe[] __initdata = {
&apic_summit, &apic_summit,
&apic_bigsmp, &apic_bigsmp,
&apic_es7000,
&apic_default, /* must be last */ &apic_default, /* must be last */
NULL, NULL,
}; };
......
...@@ -26,7 +26,8 @@ struct genapic { ...@@ -26,7 +26,8 @@ struct genapic {
int int_delivery_mode; int int_delivery_mode;
int int_dest_mode; int int_dest_mode;
int apic_broadcast_id; int apic_broadcast_id;
int esr_disable; int ESR_DISABLE;
int apic_destination_logical;
unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid); unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid);
unsigned long (*check_apicid_present)(int apicid); unsigned long (*check_apicid_present)(int apicid);
int no_balance_irq; int no_balance_irq;
...@@ -80,6 +81,8 @@ struct genapic { ...@@ -80,6 +81,8 @@ struct genapic {
.apic_broadcast_id = APIC_BROADCAST_ID, \ .apic_broadcast_id = APIC_BROADCAST_ID, \
.no_balance_irq = NO_BALANCE_IRQ, \ .no_balance_irq = NO_BALANCE_IRQ, \
.no_ioapic_check = NO_IOAPIC_CHECK, \ .no_ioapic_check = NO_IOAPIC_CHECK, \
.ESR_DISABLE = esr_disable, \
.apic_destination_logical = APIC_DEST_LOGICAL, \
APICFUNC(apic_id_registered), \ APICFUNC(apic_id_registered), \
APICFUNC(target_cpus), \ APICFUNC(target_cpus), \
APICFUNC(check_apicid_used), \ APICFUNC(check_apicid_used), \
......
#ifndef __ASM_MACH_IPI_H #ifndef __ASM_MACH_IPI_H
#define __ASM_MACH_IPI_H #define __ASM_MACH_IPI_H
static inline void send_IPI_mask_sequence(cpumask_t mask, int vector); inline void send_IPI_mask_sequence(cpumask_t mask, int vector);
static inline void send_IPI_mask(cpumask_t mask, int vector) static inline void send_IPI_mask(cpumask_t mask, int vector)
{ {
......
...@@ -12,26 +12,28 @@ static inline void mpc_oem_pci_bus(struct mpc_config_bus *m, ...@@ -12,26 +12,28 @@ static inline void mpc_oem_pci_bus(struct mpc_config_bus *m,
{ {
} }
extern void parse_unisys_oem (char *oemptr, int oem_entries); extern int parse_unisys_oem (char *oemptr, int oem_entries);
extern int find_unisys_acpi_oem_table(unsigned long *oem_addr, int *length); extern int find_unisys_acpi_oem_table(unsigned long *oem_addr, int *length);
static inline void mps_oem_check(struct mp_config_table *mpc, char *oem, static inline int mps_oem_check(struct mp_config_table *mpc, char *oem,
char *productid) char *productid)
{ {
if (mpc->mpc_oemptr) { if (mpc->mpc_oemptr) {
struct mp_config_oemtable *oem_table = struct mp_config_oemtable *oem_table =
(struct mp_config_oemtable *)mpc->mpc_oemptr; (struct mp_config_oemtable *)mpc->mpc_oemptr;
parse_unisys_oem((char *)oem_table, oem_table->oem_length); return parse_unisys_oem((char *)oem_table, oem_table->oem_length);
} }
return 0;
} }
/* Hook from generic ACPI tables.c */ /* Hook from generic ACPI tables.c */
static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id) static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{ {
unsigned long oem_addr; unsigned long oem_addr;
int oem_entries; int oem_entries;
if (!find_unisys_acpi_oem_table(&oem_addr, &oem_entries)) if (!find_unisys_acpi_oem_table(&oem_addr, &oem_entries))
parse_unisys_oem((char *)oem_addr, oem_entries); return parse_unisys_oem((char *)oem_addr, oem_entries);
return 0;
} }
......
...@@ -3,15 +3,16 @@ ...@@ -3,15 +3,16 @@
#include <asm/genapic.h> #include <asm/genapic.h>
#define esr_disable (genapic->esr_disable) #define esr_disable (genapic->ESR_DISABLE)
#define NO_BALANCE_IRQ (genapic->no_balance_irq) #define NO_BALANCE_IRQ (genapic->no_balance_irq)
#define NO_IOAPIC_CHECK (genapic->no_ioapic_check) #define NO_IOAPIC_CHECK (genapic->no_ioapic_check)
#define APIC_BROADCAST_ID (genapic->apic_broadcast_id) #define APIC_BROADCAST_ID (genapic->apic_broadcast_id)
#define INT_DELIVERY_MODE (genapic->int_delivery_mode) #define INT_DELIVERY_MODE (genapic->int_delivery_mode)
#define INT_DEST_MODE (genapic->int_dest_mode) #define INT_DEST_MODE (genapic->int_dest_mode)
#undef APIC_DEST_LOGICAL
#define APIC_DEST_LOGICAL (genapic->apic_destination_logical)
#define TARGET_CPUS (genapic->target_cpus()) #define TARGET_CPUS (genapic->target_cpus())
#define apic_id_registered (genapic->apic_id_registered) #define apic_id_registered (genapic->apic_id_registered)
#define apic_id_registered (genapic->apic_id_registered)
#define init_apic_ldr (genapic->init_apic_ldr) #define init_apic_ldr (genapic->init_apic_ldr)
#define ioapic_phys_id_map (genapic->ioapic_phys_id_map) #define ioapic_phys_id_map (genapic->ioapic_phys_id_map)
#define clustered_apic_check (genapic->clustered_apic_check) #define clustered_apic_check (genapic->clustered_apic_check)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment