From: "Protasevich, Natalie" Include ES7000 specific code for es7000 subarch. 25-akpm/arch/i386/Kconfig | 14 25-akpm/arch/i386/Makefile | 4 25-akpm/arch/i386/kernel/apic.c | 1 25-akpm/arch/i386/mach-es7000/Makefile | 7 25-akpm/arch/i386/mach-es7000/es7000.c | 281 ++++++++++++++++++++ 25-akpm/arch/i386/mach-es7000/es7000.h | 109 +++++++ 25-akpm/arch/i386/mach-es7000/setup.c | 105 +++++++ 25-akpm/arch/i386/mach-es7000/topology.c | 68 ++++ 25-akpm/include/asm-i386/mach-bigsmp/mach_apic.h | 4 25-akpm/include/asm-i386/mach-default/mach_apic.h | 4 25-akpm/include/asm-i386/mach-es7000/mach_apic.h | 189 +++++++++++++ 25-akpm/include/asm-i386/mach-es7000/mach_apicdef.h | 13 25-akpm/include/asm-i386/mach-es7000/mach_ipi.h | 24 + 25-akpm/include/asm-i386/mach-es7000/mach_mpparse.h | 38 ++ 25-akpm/include/asm-i386/mach-es7000/mach_mpspec.h | 13 25-akpm/include/asm-i386/mach-es7000/mach_wakecpu.h | 58 ++++ 25-akpm/include/asm-i386/mach-numaq/mach_apic.h | 6 25-akpm/include/asm-i386/mach-summit/mach_apic.h | 4 25-akpm/include/asm-i386/mach-visws/mach_apic.h | 4 19 files changed, 945 insertions(+), 1 deletion(-) diff -puN arch/i386/Kconfig~es7000-02-subarch arch/i386/Kconfig --- 25/arch/i386/Kconfig~es7000-02-subarch Wed Jun 11 13:55:27 2003 +++ 25-akpm/arch/i386/Kconfig Wed Jun 11 13:55:27 2003 @@ -99,6 +99,15 @@ config X86_GENERICARCH This option compiles in the Summit, bigsmp, default subarchitectures. It is intended for a generic binary kernel. +config X86_ES7000 + bool "Support for Unisys ES7000 IA32 series" + depends on SMP + help + Support for Unisys ES7000 systems. Say 'Y' here if this kernel is + supposed to run on an IA32-based Unisys ES7000 system. + Only choose this option if you have such a system, otherwise you + should say N here. + endchoice config ACPI_SRAT @@ -111,6 +120,11 @@ config X86_CYCLONE_TIMER default y depends on X86_SUMMIT || X86_GENERICARCH +config ES7000_CLUSTERED_APIC + bool + default y + depends on SMP && X86_ES7000 && MPENTIUMIII + choice prompt "Processor family" default M686 diff -puN arch/i386/kernel/apic.c~es7000-02-subarch arch/i386/kernel/apic.c --- 25/arch/i386/kernel/apic.c~es7000-02-subarch Wed Jun 11 13:55:27 2003 +++ 25-akpm/arch/i386/kernel/apic.c Wed Jun 11 13:55:27 2003 @@ -161,6 +161,7 @@ void __init connect_bsp_APIC(void) outb(0x70, 0x22); outb(0x01, 0x23); } + enable_apic_mode(); } void disconnect_bsp_APIC(void) diff -puN /dev/null arch/i386/mach-es7000/es7000.c --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/arch/i386/mach-es7000/es7000.c Wed Jun 11 13:55:27 2003 @@ -0,0 +1,281 @@ +/* + * Written by: Garry Forsgren, Unisys Corporation + * Natalie Protasevich, Unisys Corporation + * This file contains the code to configure and interface + * with Unisys ES7000 series hardware system manager. + * + * Copyright (c) 2003 Unisys Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Unisys Corporation, Township Line & Union Meeting + * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or: + * + * http://www.unisys.com + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "es7000.h" + +/* + * ES7000 Globals + */ + +volatile unsigned long *psai = NULL; +struct mip_reg *mip_reg; +struct mip_reg *host_reg; +int mip_port; +unsigned long mip_addr, host_addr; + +static int es7000_plat; + +/* + * Parse the OEM Table + */ + +void __init +parse_unisys_oem (char *oemptr, int oem_entries) +{ + int i; + int success = 0; + unsigned char type, size; + unsigned long val; + char *tp = NULL; + struct psai *psaip = NULL; + struct mip_reg_info *mi; + struct mip_reg *host, *mip; + + tp = oemptr; + + tp += 8; + + for (i=0; i <= oem_entries; i++) { + type = *tp++; + size = *tp++; + tp -= 2; + switch (type) { + case MIP_REG: + mi = (struct mip_reg_info *)tp; + val = MIP_RD_LO(mi->host_reg); + host_addr = val; + host = (struct mip_reg *)val; + host_reg = __va(host); + val = MIP_RD_LO(mi->mip_reg); + mip_addr = val; + mip = (struct mip_reg *)val; + mip_reg = __va(mip); + Dprintk("es7000_mipcfg: host_reg = 0x%lx \n", + (unsigned long)host_reg); + Dprintk("es7000_mipcfg: mip_reg = 0x%lx \n", + (unsigned long)mip_reg); + success++; + break; + case MIP_PSAI_REG: + psaip = (struct psai *)tp; + if (tp != NULL) { + if (psaip->addr) + psai = __va(psaip->addr); + else + psai = NULL; + success++; + } + break; + default: + break; + } + if (i == 6) break; + tp += size; + } + + if (success < 2) { + printk("\nNo ES7000 found.\n"); + es7000_plat = 0; + } else { + printk("\nEnabling ES7000 specific features...\n"); + es7000_plat = 1; + } + return; +} + +int __init +find_unisys_acpi_oem_table(unsigned long *oem_addr, int *length) +{ + struct acpi_table_rsdp *rsdp = NULL; + unsigned long rsdp_phys = 0; + struct acpi_table_header *header = NULL; + int i; + struct acpi_table_sdt sdt; + + rsdp_phys = acpi_find_rsdp(); + rsdp = __va(rsdp_phys); + if (rsdp->rsdt_address) { + struct acpi_table_rsdt *mapped_rsdt = NULL; + sdt.pa = rsdp->rsdt_address; + + header = (struct acpi_table_header *) + __acpi_map_table(sdt.pa, sizeof(struct acpi_table_header)); + if (!header) + return -ENODEV; + + sdt.count = (header->length - sizeof(struct acpi_table_header)) >> 3; + mapped_rsdt = (struct acpi_table_rsdt *) + __acpi_map_table(sdt.pa, header->length); + if (!mapped_rsdt) + return -ENODEV; + + header = &mapped_rsdt->header; + + for (i = 0; i < sdt.count; i++) + sdt.entry[i].pa = (unsigned long) mapped_rsdt->entry[i]; + }; + for (i = 0; i < sdt.count; i++) { + + header = (struct acpi_table_header *) + __acpi_map_table(sdt.entry[i].pa, + sizeof(struct acpi_table_header)); + if (!header) + continue; + if (!strncmp((char *) &header->signature, "OEM1", 4)) { + if (!strncmp((char *) &header->oem_id, "UNISYS", 6)) { + void *addr; + struct oem_table *t; + acpi_table_print(header, sdt.entry[i].pa); + t = (struct oem_table *) __acpi_map_table(sdt.entry[i].pa, header->length); + addr = (void *) __acpi_map_table(t->OEMTableAddr, t->OEMTableSize); + *length = header->length; + *oem_addr = (unsigned long) addr; + return 0; + } + } + } + printk("ES7000: did not find Unisys ACPI OEM table!\n"); + return -1; +} + +static void +es7000_spin(int n) +{ + int i = 0; + + while (i++ < n) + rep_nop(); +} + +static int __init +es7000_mip_write(struct mip_reg *mip_reg) +{ + int status = 0; + int spin; + + spin = MIP_SPIN; + while (((unsigned long long)host_reg->off_38 & + (unsigned long long)MIP_VALID) != 0) { + if (--spin <= 0) { + printk("es7000_mip_write: Timeout waiting for Host Valid Flag"); + return -1; + } + es7000_spin(MIP_SPIN); + } + + memcpy(host_reg, mip_reg, sizeof(struct mip_reg)); + outb(1, mip_port); + + spin = MIP_SPIN; + + while (((unsigned long long)mip_reg->off_38 & + (unsigned long long)MIP_VALID) == 0) { + if (--spin <= 0) { + printk("es7000_mip_write: Timeout waiting for MIP Valid Flag"); + return -1; + } + es7000_spin(MIP_SPIN); + } + + status = ((unsigned long long)mip_reg->off_0 & + (unsigned long long)0xffff0000000000) >> 48; + mip_reg->off_38 = ((unsigned long long)mip_reg->off_38 & + (unsigned long long)~MIP_VALID); + return status; +} + +int +es7000_start_cpu(int cpu, unsigned long eip) +{ + unsigned long vect = 0, psaival = 0; + + if (psai == NULL) + return -1; + + vect = ((unsigned long)__pa(eip)/0x1000) << 16; + psaival = (0x1000000 | vect | cpu); + + while (*psai & 0x1000000) + ; + + *psai = psaival; + + return 0; + +} + +int +es7000_stop_cpu(int cpu) +{ + int startup; + + if (psai == NULL) + return -1; + + startup= (0x1000000 | cpu); + + while ((*psai & 0xff00ffff) != startup) + ; + + startup = (*psai & 0xff0000) >> 16; + *psai &= 0xffffff; + + return 0; + +} + +void __init +es7000_sw_apic() +{ + if (es7000_plat) { + int mip_status; + struct mip_reg es7000_mip_reg; + + printk("ES7000: Enabling APIC mode.\n"); + memset(&es7000_mip_reg, 0, sizeof(struct mip_reg)); + es7000_mip_reg.off_0 = MIP_SW_APIC; + es7000_mip_reg.off_38 = (MIP_VALID); + while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0) + printk("es7000_sw_apic: command failed, status = %x\n", + mip_status); + return; + } +} diff -puN /dev/null arch/i386/mach-es7000/es7000.h --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/arch/i386/mach-es7000/es7000.h Wed Jun 11 13:55:27 2003 @@ -0,0 +1,109 @@ +/* + * Written by: Garry Forsgren, Unisys Corporation + * Natalie Protasevich, Unisys Corporation + * This file contains the code to configure and interface + * with Unisys ES7000 series hardware system manager. + * + * Copyright (c) 2003 Unisys Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Unisys Corporation, Township Line & Union Meeting + * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or: + * + * http://www.unisys.com + */ + +#define MIP_REG 1 +#define MIP_PSAI_REG 4 + +#define MIP_BUSY 1 +#define MIP_SPIN 0xf0000 +#define MIP_VALID 0x0100000000000000 + +#define MIP_RD_LO(VALUE) (VALUE & 0xffffffff) + +struct mip_reg_info { + unsigned long long mip_info; + unsigned long long delivery_info; + unsigned long long host_reg; + unsigned long long mip_reg; +}; + +struct part_info { + unsigned char type; + unsigned char length; + unsigned char part_id; + unsigned char apic_mode; + unsigned long snum; + char ptype[16]; + char sname[64]; + char pname[64]; +}; + +struct psai { + unsigned long long entry_type; + unsigned long long addr; + unsigned long long bep_addr; +}; + +struct es7000_mem_info { + unsigned char type; + unsigned char length; + unsigned char resv[6]; + unsigned long long start; + unsigned long long size; +}; + +struct es7000_oem_table { + unsigned long long hdr; + struct mip_reg_info mip; + struct part_info pif; + struct es7000_mem_info shm; + struct psai psai; +}; + +struct acpi_table_sdt { + unsigned long pa; + unsigned long count; + struct { + unsigned long pa; + enum acpi_table_id id; + unsigned long size; + } entry[50]; +}; + +struct oem_table { + struct acpi_table_header Header; + u32 OEMTableAddr; + u32 OEMTableSize; +}; + +struct mip_reg { + unsigned long long off_0; + unsigned long long off_8; + unsigned long long off_10; + unsigned long long off_18; + unsigned long long off_20; + unsigned long long off_28; + unsigned long long off_30; + unsigned long long off_38; +}; + +#define MIP_SW_APIC 0x1020b +#define MIP_FUNC(VALUE) (VALUE & 0xff) + +extern void parse_unisys_oem (char *oemptr, int oem_entries); +extern int find_unisys_acpi_oem_table(unsigned long *oem_addr, int *length); +extern int es7000_start_cpu(int cpu, unsigned long eip); +extern void es7000_sw_apic(void); diff -puN /dev/null arch/i386/mach-es7000/Makefile --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/arch/i386/mach-es7000/Makefile Wed Jun 11 13:55:27 2003 @@ -0,0 +1,7 @@ +# +# Makefile for the linux kernel. +# + +EXTRA_CFLAGS += -I../kernel + +obj-y := setup.o topology.o es7000.o diff -puN /dev/null arch/i386/mach-es7000/setup.c --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/arch/i386/mach-es7000/setup.c Wed Jun 11 13:55:27 2003 @@ -0,0 +1,105 @@ +/* + * Machine specific setup for es7000 + */ + +#include +#include +#include +#include +#include +#include + +/** + * 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 + + 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 diff -puN /dev/null arch/i386/mach-es7000/topology.c --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/arch/i386/mach-es7000/topology.c Wed Jun 11 13:55:27 2003 @@ -0,0 +1,68 @@ +/* + * 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 + */ +#include +#include +#include + +struct i386_cpu cpu_devices[NR_CPUS]; + +#ifdef CONFIG_NUMA +#include +#include +#include + +struct i386_node node_devices[MAX_NUMNODES]; +struct i386_memblk memblk_devices[MAX_NR_MEMBLKS]; + +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); + for (i = 0; i < num_online_memblks(); i++) + arch_register_memblk(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); diff -puN arch/i386/Makefile~es7000-02-subarch arch/i386/Makefile --- 25/arch/i386/Makefile~es7000-02-subarch Wed Jun 11 13:55:27 2003 +++ 25-akpm/arch/i386/Makefile Wed Jun 11 13:55:27 2003 @@ -78,6 +78,10 @@ mflags-$(CONFIG_X86_GENERICARCH) := -Iin mcore-$(CONFIG_X86_GENERICARCH) := mach-default core-$(CONFIG_X86_GENERICARCH) += arch/i386/mach-generic/ +# ES7000 subarch support +mflags-$(CONFIG_X86_ES7000) := -Iinclude/asm-i386/mach-es7000 +mcore-$(CONFIG_X86_ES7000) := mach-es7000 + # default subarch .h files mflags-y += -Iinclude/asm-i386/mach-default diff -puN include/asm-i386/mach-bigsmp/mach_apic.h~es7000-02-subarch include/asm-i386/mach-bigsmp/mach_apic.h --- 25/include/asm-i386/mach-bigsmp/mach_apic.h~es7000-02-subarch Wed Jun 11 13:55:27 2003 +++ 25-akpm/include/asm-i386/mach-bigsmp/mach_apic.h Wed Jun 11 13:55:27 2003 @@ -123,6 +123,10 @@ static inline void setup_portio_remap(vo { } +static inline void enable_apic_mode(void) +{ +} + static inline int check_phys_apicid_present(int boot_cpu_physical_apicid) { return (1); diff -puN include/asm-i386/mach-default/mach_apic.h~es7000-02-subarch include/asm-i386/mach-default/mach_apic.h --- 25/include/asm-i386/mach-default/mach_apic.h~es7000-02-subarch Wed Jun 11 13:55:27 2003 +++ 25-akpm/include/asm-i386/mach-default/mach_apic.h Wed Jun 11 13:55:27 2003 @@ -118,4 +118,8 @@ static inline unsigned int cpu_mask_to_a return cpumask; } +static inline void enable_apic_mode(void) +{ +} + #endif /* __ASM_MACH_APIC_H */ diff -puN /dev/null include/asm-i386/mach-es7000/mach_apicdef.h --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/include/asm-i386/mach-es7000/mach_apicdef.h Wed Jun 11 13:55:27 2003 @@ -0,0 +1,13 @@ +#ifndef __ASM_MACH_APICDEF_H +#define __ASM_MACH_APICDEF_H + +#define APIC_ID_MASK (0xFF<<24) + +static inline unsigned get_apic_id(unsigned long x) +{ + return (((x)>>24)&0xFF); +} + +#define GET_APIC_ID(x) get_apic_id(x) + +#endif diff -puN /dev/null include/asm-i386/mach-es7000/mach_apic.h --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/include/asm-i386/mach-es7000/mach_apic.h Wed Jun 11 13:55:27 2003 @@ -0,0 +1,189 @@ +#ifndef __ASM_MACH_APIC_H +#define __ASM_MACH_APIC_H + +extern u8 bios_cpu_apicid[]; + +#define xapic_phys_to_log_apicid(cpu) (bios_cpu_apicid[cpu]) +#define esr_disable (1) + +static inline int apic_id_registered(void) +{ + return (1); +} + +static inline unsigned long target_cpus(void) +{ +#if defined CONFIG_ES7000_CLUSTERED_APIC + return (0xff); +#else + return (bios_cpu_apicid[smp_processor_id()]); +#endif +} +#define TARGET_CPUS (target_cpus()) + +#if defined CONFIG_ES7000_CLUSTERED_APIC +#define APIC_DFR_VALUE (APIC_DFR_CLUSTER) +#define INT_DELIVERY_MODE (dest_LowestPrio) +#define INT_DEST_MODE (1) /* logical delivery broadcast to all procs */ +#define NO_BALANCE_IRQ (1) +#undef WAKE_SECONDARY_VIA_INIT +#define WAKE_SECONDARY_VIA_MIP +#else +#define APIC_DFR_VALUE (APIC_DFR_FLAT) +#define INT_DELIVERY_MODE (dest_Fixed) +#define INT_DEST_MODE (0) /* phys delivery to target procs */ +#define NO_BALANCE_IRQ (0) +#undef APIC_DEST_LOGICAL +#define APIC_DEST_LOGICAL 0x0 +#define WAKE_SECONDARY_VIA_INIT +#endif + +#define APIC_BROADCAST_ID (0xff) + +static inline unsigned long check_apicid_used(unsigned long bitmap, int apicid) +{ + return 0; +} +static inline unsigned long check_apicid_present(int bit) +{ + return (phys_cpu_present_map & (1 << bit)); +} + +#define apicid_cluster(apicid) (apicid & 0xF0) + +static inline unsigned long calculate_ldr(int cpu) +{ + unsigned long id; + id = xapic_phys_to_log_apicid(cpu); + return (SET_APIC_LOGICAL_ID(id)); +} + +/* + * Set up the logical destination ID. + * + * Intel recommends to set DFR, LdR and TPR before enabling + * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel + * document number 292116). So here it goes... + */ +static inline void init_apic_ldr(void) +{ + unsigned long val; + int cpu = smp_processor_id(); + + apic_write_around(APIC_DFR, APIC_DFR_VALUE); + val = calculate_ldr(cpu); + apic_write_around(APIC_LDR, val); +} + +extern void es7000_sw_apic(void); +static inline void enable_apic_mode(void) +{ + es7000_sw_apic(); + return; +} + +extern int apic_version [MAX_APICS]; +static inline void clustered_apic_check(void) +{ + int apic = bios_cpu_apicid[smp_processor_id()]; + printk("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", + (apic_version[apic] == 0x14) ? + "Physical Cluster" : "Logical Cluster", nr_ioapics, TARGET_CPUS); +} + +static inline int multi_timer_check(int apic, int irq) +{ + return 0; +} + +static inline int apicid_to_node(int logical_apicid) +{ + return 0; +} + + +static inline int cpu_present_to_apicid(int mps_cpu) +{ + if (!mps_cpu) + return boot_cpu_physical_apicid; + else + return (int) bios_cpu_apicid[mps_cpu]; +} + +static inline unsigned long apicid_to_cpu_present(int phys_apicid) +{ + static int cpu = 0; + return (1ul << cpu++); +} + +extern volatile u8 cpu_2_logical_apicid[]; +/* Mapping from cpu number to logical apicid */ +static inline int cpu_to_logical_apicid(int cpu) +{ + return (int)cpu_2_logical_apicid[cpu]; +} + +static inline int mpc_apic_id(struct mpc_config_processor *m, int quad) +{ + printk("Processor #%d %ld:%ld APIC version %d\n", + m->mpc_apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, + (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, + m->mpc_apicver); + return (m->mpc_apicid); +} + +static inline ulong ioapic_phys_id_map(ulong phys_map) +{ + /* For clustered we don't have a good way to do this yet - hack */ + return (0xff); +} + + +static inline void setup_portio_remap(void) +{ +} + +extern unsigned int boot_cpu_physical_apicid; +static inline int check_phys_apicid_present(int cpu_physical_apicid) +{ + boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); + return (1); +} + +static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) +{ + int num_bits_set; + int cpus_found = 0; + int cpu; + int apicid; + + if (cpumask == TARGET_CPUS) + return cpumask; + num_bits_set = hweight32(cpumask); + /* Return id to all */ + if (num_bits_set == 32) + return TARGET_CPUS; + /* + * The cpus in the mask must all be on the apic cluster. If are not + * on the same apicid cluster return default value of TARGET_CPUS. + */ + cpu = ffs(cpumask)-1; + apicid = cpu_to_logical_apicid(cpu); + while (cpus_found < num_bits_set) { + if (cpumask & (1 << cpu)) { + int new_apicid = cpu_to_logical_apicid(cpu); + if (apicid_cluster(apicid) != + apicid_cluster(new_apicid)){ + printk ("%s: Not a valid mask!\n",__FUNCTION__); + return TARGET_CPUS; + } + apicid = new_apicid; + cpus_found++; + } + cpu++; + } + return apicid; +} + +#endif /* __ASM_MACH_APIC_H */ diff -puN /dev/null include/asm-i386/mach-es7000/mach_ipi.h --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/include/asm-i386/mach-es7000/mach_ipi.h Wed Jun 11 13:55:27 2003 @@ -0,0 +1,24 @@ +#ifndef __ASM_MACH_IPI_H +#define __ASM_MACH_IPI_H + +static inline void send_IPI_mask_sequence(int mask, int vector); + +static inline void send_IPI_mask(int mask, int vector) +{ + send_IPI_mask_sequence(mask, vector); +} + +static inline void send_IPI_allbutself(int vector) +{ + unsigned long mask = cpu_online_map & ~(1 << smp_processor_id()); + + if (mask) + send_IPI_mask(mask, vector); +} + +static inline void send_IPI_all(int vector) +{ + send_IPI_mask(cpu_online_map, vector); +} + +#endif /* __ASM_MACH_IPI_H */ diff -puN /dev/null include/asm-i386/mach-es7000/mach_mpparse.h --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/include/asm-i386/mach-es7000/mach_mpparse.h Wed Jun 11 13:55:27 2003 @@ -0,0 +1,38 @@ +#ifndef __ASM_MACH_MPPARSE_H +#define __ASM_MACH_MPPARSE_H + +static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, + struct mpc_config_translation *translation) +{ + Dprintk("Bus #%d is %s\n", m->mpc_busid, name); +} + +static inline void mpc_oem_pci_bus(struct mpc_config_bus *m, + struct mpc_config_translation *translation) +{ +} + +extern void parse_unisys_oem (char *oemptr, int oem_entries); +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, + char *productid) +{ + if (mpc->mpc_oemptr) { + struct mp_config_oemtable *oem_table = + (struct mp_config_oemtable *)mpc->mpc_oemptr; + parse_unisys_oem((char *)oem_table, oem_table->oem_length); + } +} + +/* Hook from generic ACPI tables.c */ +static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + unsigned long oem_addr; + int oem_entries; + if (!find_unisys_acpi_oem_table(&oem_addr, &oem_entries)) + parse_unisys_oem((char *)oem_addr, oem_entries); +} + + +#endif /* __ASM_MACH_MPPARSE_H */ diff -puN /dev/null include/asm-i386/mach-es7000/mach_mpspec.h --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/include/asm-i386/mach-es7000/mach_mpspec.h Wed Jun 11 13:55:27 2003 @@ -0,0 +1,13 @@ +#ifndef __ASM_MACH_MPSPEC_H +#define __ASM_MACH_MPSPEC_H + +/* + * a maximum of 256 APICs with the current APIC ID architecture. + */ +#define MAX_APICS 256 + +#define MAX_IRQ_SOURCES 256 + +#define MAX_MP_BUSSES 32 + +#endif /* __ASM_MACH_MPSPEC_H */ diff -puN /dev/null include/asm-i386/mach-es7000/mach_wakecpu.h --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/include/asm-i386/mach-es7000/mach_wakecpu.h Wed Jun 11 13:55:27 2003 @@ -0,0 +1,58 @@ +#ifndef __ASM_MACH_WAKECPU_H +#define __ASM_MACH_WAKECPU_H + +/* + * This file copes with machines that wakeup secondary CPUs by the + * INIT, INIT, STARTUP sequence. + */ + +#ifdef CONFIG_ES7000_CLUSTERED_APIC +#define WAKE_SECONDARY_VIA_MIP +#else +#define WAKE_SECONDARY_VIA_INIT +#endif + +#ifdef WAKE_SECONDARY_VIA_MIP +extern int es7000_start_cpu(int cpu, unsigned long eip); +static inline int +wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) +{ + int boot_error = 0; + boot_error = es7000_start_cpu(phys_apicid, start_eip); + return boot_error; +} +#endif + +#define TRAMPOLINE_LOW phys_to_virt(0x467) +#define TRAMPOLINE_HIGH phys_to_virt(0x469) + +#define boot_cpu_apicid boot_cpu_physical_apicid + +static inline void wait_for_init_deassert(atomic_t *deassert) +{ +#ifdef WAKE_SECONDARY_VIA_INIT + while (!atomic_read(deassert)); +#endif + return; +} + +/* Nothing to do for most platforms, since cleared by the INIT cycle */ +static inline void smp_callin_clear_local_apic(void) +{ +} + +static inline void store_NMI_vector(unsigned short *high, unsigned short *low) +{ +} + +static inline void restore_NMI_vector(unsigned short *high, unsigned short *low) +{ +} + +#if APIC_DEBUG + #define inquire_remote_apic(apicid) __inquire_remote_apic(apicid) +#else + #define inquire_remote_apic(apicid) {} +#endif + +#endif /* __ASM_MACH_WAKECPU_H */ diff -puN include/asm-i386/mach-numaq/mach_apic.h~es7000-02-subarch include/asm-i386/mach-numaq/mach_apic.h --- 25/include/asm-i386/mach-numaq/mach_apic.h~es7000-02-subarch Wed Jun 11 13:55:27 2003 +++ 25-akpm/include/asm-i386/mach-numaq/mach_apic.h Wed Jun 11 13:56:00 2003 @@ -107,7 +107,11 @@ static inline int check_phys_apicid_pres return (1); } -/* +static inline void enable_apic_mode(void) +{ +} + +/* * We use physical apicids here, not logical, so just return the default * physical broadcast to stop people from breaking us */ diff -puN include/asm-i386/mach-summit/mach_apic.h~es7000-02-subarch include/asm-i386/mach-summit/mach_apic.h --- 25/include/asm-i386/mach-summit/mach_apic.h~es7000-02-subarch Wed Jun 11 13:55:27 2003 +++ 25-akpm/include/asm-i386/mach-summit/mach_apic.h Wed Jun 11 13:55:27 2003 @@ -118,6 +118,10 @@ static inline int check_phys_apicid_pres return 1; } +static inline void enable_apic_mode(void) +{ +} + static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask) { int num_bits_set; diff -puN include/asm-i386/mach-visws/mach_apic.h~es7000-02-subarch include/asm-i386/mach-visws/mach_apic.h --- 25/include/asm-i386/mach-visws/mach_apic.h~es7000-02-subarch Wed Jun 11 13:55:27 2003 +++ 25-akpm/include/asm-i386/mach-visws/mach_apic.h Wed Jun 11 13:55:27 2003 @@ -72,6 +72,10 @@ static inline void setup_portio_remap(vo { } +static inline void enable_apic_mode(void) +{ +} + static inline int check_phys_apicid_present(int boot_cpu_physical_apicid) { return test_bit(boot_cpu_physical_apicid, &phys_cpu_present_map); _