/* -*- mode: c; c-basic-offset: 8 -*- */

/* Copyright (C) 1999,2001
 *
 * Author: J.E.J.Bottomley@HansenPartnership.com
 *
 * linux/arch/i386/kernel/voyager_smp.c
 *
 * This file provides all the same external entries as smp.c but uses
 * the voyager hal to provide the functionality
 */
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
#include <linux/mc146818rtc.h>
#include <linux/cache.h>
#include <linux/interrupt.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/bootmem.h>
#include <linux/completion.h>
#include <asm/desc.h>
#include <asm/voyager.h>
#include <asm/vic.h>
#include <asm/mtrr.h>
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/arch_hooks.h>

/* TLB state -- visible externally, indexed physically */
DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0 };

/* CPU IRQ affinity -- set to all ones initially */
static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1]  = ~0UL };

/* per CPU data structure (for /proc/cpuinfo et al), visible externally
 * indexed physically */
struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
EXPORT_SYMBOL(cpu_data);

/* physical ID of the CPU used to boot the system */
unsigned char boot_cpu_id;

/* The memory line addresses for the Quad CPIs */
struct voyager_qic_cpi *voyager_quad_cpi_addr[NR_CPUS] __cacheline_aligned;

/* The masks for the Extended VIC processors, filled in by cat_init */
__u32 voyager_extended_vic_processors = 0;

/* Masks for the extended Quad processors which cannot be VIC booted */
__u32 voyager_allowed_boot_processors = 0;

/* The mask for the Quad Processors (both extended and non-extended) */
__u32 voyager_quad_processors = 0;

/* Total count of live CPUs, used in process.c to display
 * the CPU information and in irq.c for the per CPU irq
 * activity count.  Finally exported by i386_ksyms.c */
static int voyager_extended_cpus = 1;

/* Have we found an SMP box - used by time.c to do the profiling
   interrupt for timeslicing; do not set to 1 until the per CPU timer
   interrupt is active */
int smp_found_config = 0;

/* Used for the invalidate map that's also checked in the spinlock */
static volatile unsigned long smp_invalidate_needed;

/* Bitmask of currently online CPUs - used by setup.c for
   /proc/cpuinfo, visible externally but still physical */
cpumask_t cpu_online_map = CPU_MASK_NONE;
EXPORT_SYMBOL(cpu_online_map);

/* Bitmask of CPUs present in the system - exported by i386_syms.c, used
 * by scheduler but indexed physically */
cpumask_t phys_cpu_present_map = CPU_MASK_NONE;


/* The internal functions */
static void send_CPI(__u32 cpuset, __u8 cpi);
static void ack_CPI(__u8 cpi);
static int ack_QIC_CPI(__u8 cpi);
static void ack_special_QIC_CPI(__u8 cpi);
static void ack_VIC_CPI(__u8 cpi);
static void send_CPI_allbutself(__u8 cpi);
static void mask_vic_irq(unsigned int irq);
static void unmask_vic_irq(unsigned int irq);
static unsigned int startup_vic_irq(unsigned int irq);
static void enable_local_vic_irq(unsigned int irq);
static void disable_local_vic_irq(unsigned int irq);
static void before_handle_vic_irq(unsigned int irq);
static void after_handle_vic_irq(unsigned int irq);
static void set_vic_irq_affinity(unsigned int irq, cpumask_t mask);
static void ack_vic_irq(unsigned int irq);
static void vic_enable_cpi(void);
static void do_boot_cpu(__u8 cpuid);
static void do_quad_bootstrap(void);

int hard_smp_processor_id(void);
int safe_smp_processor_id(void);

/* Inline functions */
static inline void
send_one_QIC_CPI(__u8 cpu, __u8 cpi)
{
	voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi =
		(smp_processor_id() << 16) + cpi;
}

static inline void
send_QIC_CPI(__u32 cpuset, __u8 cpi)
{
	int cpu;

	for_each_online_cpu(cpu) {
		if(cpuset & (1<<cpu)) {
#ifdef VOYAGER_DEBUG
			if(!cpu_isset(cpu, cpu_online_map))
				VDEBUG(("CPU%d sending cpi %d to CPU%d not in cpu_online_map\n", hard_smp_processor_id(), cpi, cpu));
#endif
			send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET);
		}
	}
}

static inline void
wrapper_smp_local_timer_interrupt(void)
{
	irq_enter();
	smp_local_timer_interrupt();
	irq_exit();
}

static inline void
send_one_CPI(__u8 cpu, __u8 cpi)
{
	if(voyager_quad_processors & (1<<cpu))
		send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET);
	else
		send_CPI(1<<cpu, cpi);
}

static inline void
send_CPI_allbutself(__u8 cpi)
{
	__u8 cpu = smp_processor_id();
	__u32 mask = cpus_addr(cpu_online_map)[0] & ~(1 << cpu);
	send_CPI(mask, cpi);
}

static inline int
is_cpu_quad(void)
{
	__u8 cpumask = inb(VIC_PROC_WHO_AM_I);
	return ((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER);
}

static inline int
is_cpu_extended(void)
{
	__u8 cpu = hard_smp_processor_id();

	return(voyager_extended_vic_processors & (1<<cpu));
}

static inline int
is_cpu_vic_boot(void)
{
	__u8 cpu = hard_smp_processor_id();

	return(voyager_extended_vic_processors
	       & voyager_allowed_boot_processors & (1<<cpu));
}


static inline void
ack_CPI(__u8 cpi)
{
	switch(cpi) {
	case VIC_CPU_BOOT_CPI:
		if(is_cpu_quad() && !is_cpu_vic_boot())
			ack_QIC_CPI(cpi);
		else
			ack_VIC_CPI(cpi);
		break;
	case VIC_SYS_INT:
	case VIC_CMN_INT: 
		/* These are slightly strange.  Even on the Quad card,
		 * They are vectored as VIC CPIs */
		if(is_cpu_quad())
			ack_special_QIC_CPI(cpi);
		else
			ack_VIC_CPI(cpi);
		break;
	default:
		printk("VOYAGER ERROR: CPI%d is in common CPI code\n", cpi);
		break;
	}
}

/* local variables */

/* The VIC IRQ descriptors -- these look almost identical to the
 * 8259 IRQs except that masks and things must be kept per processor
 */
static struct irq_chip vic_chip = {
	.name		= "VIC",
	.startup	= startup_vic_irq,
	.mask		= mask_vic_irq,
	.unmask		= unmask_vic_irq,
	.set_affinity	= set_vic_irq_affinity,
};

/* used to count up as CPUs are brought on line (starts at 0) */
static int cpucount = 0;

/* steal a page from the bottom of memory for the trampoline and
 * squirrel its address away here.  This will be in kernel virtual
 * space */
static __u32 trampoline_base;

/* The per cpu profile stuff - used in smp_local_timer_interrupt */
static DEFINE_PER_CPU(int, prof_multiplier) = 1;
static DEFINE_PER_CPU(int, prof_old_multiplier) = 1;
static DEFINE_PER_CPU(int, prof_counter) =  1;

/* the map used to check if a CPU has booted */
static __u32 cpu_booted_map;

/* the synchronize flag used to hold all secondary CPUs spinning in
 * a tight loop until the boot sequence is ready for them */
static cpumask_t smp_commenced_mask = CPU_MASK_NONE;

/* This is for the new dynamic CPU boot code */
cpumask_t cpu_callin_map = CPU_MASK_NONE;
cpumask_t cpu_callout_map = CPU_MASK_NONE;
EXPORT_SYMBOL(cpu_callout_map);
cpumask_t cpu_possible_map = CPU_MASK_NONE;
EXPORT_SYMBOL(cpu_possible_map);

/* The per processor IRQ masks (these are usually kept in sync) */
static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned;

/* the list of IRQs to be enabled by the VIC_ENABLE_IRQ_CPI */
static __u16 vic_irq_enable_mask[NR_CPUS] __cacheline_aligned = { 0 };

/* Lock for enable/disable of VIC interrupts */
static  __cacheline_aligned DEFINE_SPINLOCK(vic_irq_lock);

/* The boot processor is correctly set up in PC mode when it 
 * comes up, but the secondaries need their master/slave 8259
 * pairs initializing correctly */

/* Interrupt counters (per cpu) and total - used to try to
 * even up the interrupt handling routines */
static long vic_intr_total = 0;
static long vic_intr_count[NR_CPUS] __cacheline_aligned = { 0 };
static unsigned long vic_tick[NR_CPUS] __cacheline_aligned = { 0 };

/* Since we can only use CPI0, we fake all the other CPIs */
static unsigned long vic_cpi_mailbox[NR_CPUS] __cacheline_aligned;

/* debugging routine to read the isr of the cpu's pic */
static inline __u16
vic_read_isr(void)
{
	__u16 isr;

	outb(0x0b, 0xa0);
	isr = inb(0xa0) << 8;
	outb(0x0b, 0x20);
	isr |= inb(0x20);

	return isr;
}

static __init void
qic_setup(void)
{
	if(!is_cpu_quad()) {
		/* not a quad, no setup */
		return;
	}
	outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0);
	outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1);
	
	if(is_cpu_extended()) {
		/* the QIC duplicate of the VIC base register */
		outb(VIC_DEFAULT_CPI_BASE, QIC_VIC_CPI_BASE_REGISTER);
		outb(QIC_DEFAULT_CPI_BASE, QIC_CPI_BASE_REGISTER);

		/* FIXME: should set up the QIC timer and memory parity
		 * error vectors here */
	}
}

static __init void
vic_setup_pic(void)
{
	outb(1, VIC_REDIRECT_REGISTER_1);
	/* clear the claim registers for dynamic routing */
	outb(0, VIC_CLAIM_REGISTER_0);
	outb(0, VIC_CLAIM_REGISTER_1);

	outb(0, VIC_PRIORITY_REGISTER);
	/* Set the Primary and Secondary Microchannel vector
	 * bases to be the same as the ordinary interrupts
	 *
	 * FIXME: This would be more efficient using separate
	 * vectors. */
	outb(FIRST_EXTERNAL_VECTOR, VIC_PRIMARY_MC_BASE);
	outb(FIRST_EXTERNAL_VECTOR, VIC_SECONDARY_MC_BASE);
	/* Now initiallise the master PIC belonging to this CPU by
	 * sending the four ICWs */

	/* ICW1: level triggered, ICW4 needed */
	outb(0x19, 0x20);

	/* ICW2: vector base */
	outb(FIRST_EXTERNAL_VECTOR, 0x21);

	/* ICW3: slave at line 2 */
	outb(0x04, 0x21);

	/* ICW4: 8086 mode */
	outb(0x01, 0x21);

	/* now the same for the slave PIC */

	/* ICW1: level trigger, ICW4 needed */
	outb(0x19, 0xA0);

	/* ICW2: slave vector base */
	outb(FIRST_EXTERNAL_VECTOR + 8, 0xA1);
	
	/* ICW3: slave ID */
	outb(0x02, 0xA1);

	/* ICW4: 8086 mode */
	outb(0x01, 0xA1);
}

static void
do_quad_bootstrap(void)
{
	if(is_cpu_quad() && is_cpu_vic_boot()) {
		int i;
		unsigned long flags;
		__u8 cpuid = hard_smp_processor_id();

		local_irq_save(flags);

		for(i = 0; i<4; i++) {
			/* FIXME: this would be >>3 &0x7 on the 32 way */
			if(((cpuid >> 2) & 0x03) == i)
				/* don't lower our own mask! */
				continue;

			/* masquerade as local Quad CPU */
			outb(QIC_CPUID_ENABLE | i, QIC_PROCESSOR_ID);
			/* enable the startup CPI */
			outb(QIC_BOOT_CPI_MASK, QIC_MASK_REGISTER1);
			/* restore cpu id */
			outb(0, QIC_PROCESSOR_ID);
		}
		local_irq_restore(flags);
	}
}


/* Set up all the basic stuff: read the SMP config and make all the
 * SMP information reflect only the boot cpu.  All others will be
 * brought on-line later. */
void __init 
find_smp_config(void)
{
	int i;

	boot_cpu_id = hard_smp_processor_id();

	printk("VOYAGER SMP: Boot cpu is %d\n", boot_cpu_id);

	/* initialize the CPU structures (moved from smp_boot_cpus) */
	for(i=0; i<NR_CPUS; i++) {
		cpu_irq_affinity[i] = ~0;
	}
	cpu_online_map = cpumask_of_cpu(boot_cpu_id);

	/* The boot CPU must be extended */
	voyager_extended_vic_processors = 1<<boot_cpu_id;
	/* initially, all of the first 8 cpu's can boot */
	voyager_allowed_boot_processors = 0xff;
	/* set up everything for just this CPU, we can alter
	 * this as we start the other CPUs later */
	/* now get the CPU disposition from the extended CMOS */
	cpus_addr(phys_cpu_present_map)[0] = voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK);
	cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8;
	cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16;
	cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24;
	cpu_possible_map = phys_cpu_present_map;
	printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", cpus_addr(phys_cpu_present_map)[0]);
	/* Here we set up the VIC to enable SMP */
	/* enable the CPIs by writing the base vector to their register */
	outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER);
	outb(1, VIC_REDIRECT_REGISTER_1);
	/* set the claim registers for static routing --- Boot CPU gets
	 * all interrupts untill all other CPUs started */
	outb(0xff, VIC_CLAIM_REGISTER_0);
	outb(0xff, VIC_CLAIM_REGISTER_1);
	/* Set the Primary and Secondary Microchannel vector
	 * bases to be the same as the ordinary interrupts
	 *
	 * FIXME: This would be more efficient using separate
	 * vectors. */
	outb(FIRST_EXTERNAL_VECTOR, VIC_PRIMARY_MC_BASE);
	outb(FIRST_EXTERNAL_VECTOR, VIC_SECONDARY_MC_BASE);

	/* Finally tell the firmware that we're driving */
	outb(inb(VOYAGER_SUS_IN_CONTROL_PORT) | VOYAGER_IN_CONTROL_FLAG,
	     VOYAGER_SUS_IN_CONTROL_PORT);

	current_thread_info()->cpu = boot_cpu_id;
}

/*
 *	The bootstrap kernel entry code has set these up. Save them
 *	for a given CPU, id is physical */
void __init
smp_store_cpu_info(int id)
{
	struct cpuinfo_x86 *c=&cpu_data[id];

	*c = boot_cpu_data;

	identify_cpu(c);
}

/* set up the trampoline and return the physical address of the code */
static __u32 __init
setup_trampoline(void)
{
	/* these two are global symbols in trampoline.S */
	extern __u8 trampoline_end[];
	extern __u8 trampoline_data[];

	memcpy((__u8 *)trampoline_base, trampoline_data,
	       trampoline_end - trampoline_data);
	return virt_to_phys((__u8 *)trampoline_base);
}

/* Routine initially called when a non-boot CPU is brought online */
static void __init
start_secondary(void *unused)
{
	__u8 cpuid = hard_smp_processor_id();
	/* external functions not defined in the headers */
	extern void calibrate_delay(void);

	cpu_init();

	/* OK, we're in the routine */
	ack_CPI(VIC_CPU_BOOT_CPI);

	/* setup the 8259 master slave pair belonging to this CPU ---
         * we won't actually receive any until the boot CPU
         * relinquishes it's static routing mask */
	vic_setup_pic();

	qic_setup();

	if(is_cpu_quad() && !is_cpu_vic_boot()) {
		/* clear the boot CPI */
		__u8 dummy;

		dummy = voyager_quad_cpi_addr[cpuid]->qic_cpi[VIC_CPU_BOOT_CPI].cpi;
		printk("read dummy %d\n", dummy);
	}

	/* lower the mask to receive CPIs */
	vic_enable_cpi();

	VDEBUG(("VOYAGER SMP: CPU%d, stack at about %p\n", cpuid, &cpuid));

	/* enable interrupts */
	local_irq_enable();

	/* get our bogomips */
	calibrate_delay();

	/* save our processor parameters */
	smp_store_cpu_info(cpuid);

	/* if we're a quad, we may need to bootstrap other CPUs */
	do_quad_bootstrap();

	/* FIXME: this is rather a poor hack to prevent the CPU
	 * activating softirqs while it's supposed to be waiting for
	 * permission to proceed.  Without this, the new per CPU stuff
	 * in the softirqs will fail */
	local_irq_disable();
	cpu_set(cpuid, cpu_callin_map);

	/* signal that we're done */
	cpu_booted_map = 1;

	while (!cpu_isset(cpuid, smp_commenced_mask))
		rep_nop();
	local_irq_enable();

	local_flush_tlb();

	cpu_set(cpuid, cpu_online_map);
	wmb();
	cpu_idle();
}


/* Routine to kick start the given CPU and wait for it to report ready
 * (or timeout in startup).  When this routine returns, the requested
 * CPU is either fully running and configured or known to be dead.
 *
 * We call this routine sequentially 1 CPU at a time, so no need for
 * locking */

static void __init
do_boot_cpu(__u8 cpu)
{
	struct task_struct *idle;
	int timeout;
	unsigned long flags;
	int quad_boot = (1<<cpu) & voyager_quad_processors 
		& ~( voyager_extended_vic_processors
		     & voyager_allowed_boot_processors);

	/* For the 486, we can't use the 4Mb page table trick, so
	 * must map a region of memory */
#ifdef CONFIG_M486
	int i;
	unsigned long *page_table_copies = (unsigned long *)
		__get_free_page(GFP_KERNEL);
#endif
	pgd_t orig_swapper_pg_dir0;

	/* This is an area in head.S which was used to set up the
	 * initial kernel stack.  We need to alter this to give the
	 * booting CPU a new stack (taken from its idle process) */
	extern struct {
		__u8 *esp;
		unsigned short ss;
	} stack_start;
	/* This is the format of the CPI IDT gate (in real mode) which
	 * we're hijacking to boot the CPU */
	union 	IDTFormat {
		struct seg {
			__u16	Offset;
			__u16	Segment;
		} idt;
		__u32 val;
	} hijack_source;

	__u32 *hijack_vector;
	__u32 start_phys_address = setup_trampoline();

	/* There's a clever trick to this: The linux trampoline is
	 * compiled to begin at absolute location zero, so make the
	 * address zero but have the data segment selector compensate
	 * for the actual address */
	hijack_source.idt.Offset = start_phys_address & 0x000F;
	hijack_source.idt.Segment = (start_phys_address >> 4) & 0xFFFF;

	cpucount++;
	idle = fork_idle(cpu);
	if(IS_ERR(idle))
		panic("failed fork for CPU%d", cpu);
	idle->thread.eip = (unsigned long) start_secondary;
	/* init_tasks (in sched.c) is indexed logically */
	stack_start.esp = (void *) idle->thread.esp;

	irq_ctx_init(cpu);

	/* Note: Don't modify initial ss override */
	VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu, 
		(unsigned long)hijack_source.val, hijack_source.idt.Segment,
		hijack_source.idt.Offset, stack_start.esp));
	/* set the original swapper_pg_dir[0] to map 0 to 4Mb transparently
	 * (so that the booting CPU can find start_32 */
	orig_swapper_pg_dir0 = swapper_pg_dir[0];
#ifdef CONFIG_M486
	if(page_table_copies == NULL)
		panic("No free memory for 486 page tables\n");
	for(i = 0; i < PAGE_SIZE/sizeof(unsigned long); i++)
		page_table_copies[i] = (i * PAGE_SIZE) 
			| _PAGE_RW | _PAGE_USER | _PAGE_PRESENT;

	((unsigned long *)swapper_pg_dir)[0] = 
		((virt_to_phys(page_table_copies)) & PAGE_MASK)
		| _PAGE_RW | _PAGE_USER | _PAGE_PRESENT;
#else
	((unsigned long *)swapper_pg_dir)[0] = 
		(virt_to_phys(pg0) & PAGE_MASK)
		| _PAGE_RW | _PAGE_USER | _PAGE_PRESENT;
#endif

	if(quad_boot) {
		printk("CPU %d: non extended Quad boot\n", cpu);
		hijack_vector = (__u32 *)phys_to_virt((VIC_CPU_BOOT_CPI + QIC_DEFAULT_CPI_BASE)*4);
		*hijack_vector = hijack_source.val;
	} else {
		printk("CPU%d: extended VIC boot\n", cpu);
		hijack_vector = (__u32 *)phys_to_virt((VIC_CPU_BOOT_CPI + VIC_DEFAULT_CPI_BASE)*4);
		*hijack_vector = hijack_source.val;
		/* VIC errata, may also receive interrupt at this address */
		hijack_vector = (__u32 *)phys_to_virt((VIC_CPU_BOOT_ERRATA_CPI + VIC_DEFAULT_CPI_BASE)*4);
		*hijack_vector = hijack_source.val;
	}
	/* All non-boot CPUs start with interrupts fully masked.  Need
	 * to lower the mask of the CPI we're about to send.  We do
	 * this in the VIC by masquerading as the processor we're
	 * about to boot and lowering its interrupt mask */
	local_irq_save(flags);
	if(quad_boot) {
		send_one_QIC_CPI(cpu, VIC_CPU_BOOT_CPI);
	} else {
		outb(VIC_CPU_MASQUERADE_ENABLE | cpu, VIC_PROCESSOR_ID);
		/* here we're altering registers belonging to `cpu' */
		
		outb(VIC_BOOT_INTERRUPT_MASK, 0x21);
		/* now go back to our original identity */
		outb(boot_cpu_id, VIC_PROCESSOR_ID);

		/* and boot the CPU */

		send_CPI((1<<cpu), VIC_CPU_BOOT_CPI);
	}
	cpu_booted_map = 0;
	local_irq_restore(flags);

	/* now wait for it to become ready (or timeout) */
	for(timeout = 0; timeout < 50000; timeout++) {
		if(cpu_booted_map)
			break;
		udelay(100);
	}
	/* reset the page table */
	swapper_pg_dir[0] = orig_swapper_pg_dir0;
	local_flush_tlb();
#ifdef CONFIG_M486
	free_page((unsigned long)page_table_copies);
#endif
	  
	if (cpu_booted_map) {
		VDEBUG(("CPU%d: Booted successfully, back in CPU %d\n",
			cpu, smp_processor_id()));
	
		printk("CPU%d: ", cpu);
		print_cpu_info(&cpu_data[cpu]);
		wmb();
		cpu_set(cpu, cpu_callout_map);
		cpu_set(cpu, cpu_present_map);
	}
	else {
		printk("CPU%d FAILED TO BOOT: ", cpu);
		if (*((volatile unsigned char *)phys_to_virt(start_phys_address))==0xA5)
			printk("Stuck.\n");
		else
			printk("Not responding.\n");
		
		cpucount--;
	}
}

void __init
smp_boot_cpus(void)
{
	int i;

	/* CAT BUS initialisation must be done after the memory */
	/* FIXME: The L4 has a catbus too, it just needs to be
	 * accessed in a totally different way */
	if(voyager_level == 5) {
		voyager_cat_init();

		/* now that the cat has probed the Voyager System Bus, sanity
		 * check the cpu map */
		if( ((voyager_quad_processors | voyager_extended_vic_processors)
		     & cpus_addr(phys_cpu_present_map)[0]) != cpus_addr(phys_cpu_present_map)[0]) {
			/* should panic */
			printk("\n\n***WARNING*** Sanity check of CPU present map FAILED\n");
		}
	} else if(voyager_level == 4)
		voyager_extended_vic_processors = cpus_addr(phys_cpu_present_map)[0];

	/* this sets up the idle task to run on the current cpu */
	voyager_extended_cpus = 1;
	/* Remove the global_irq_holder setting, it triggers a BUG() on
	 * schedule at the moment */
	//global_irq_holder = boot_cpu_id;

	/* FIXME: Need to do something about this but currently only works
	 * on CPUs with a tsc which none of mine have. 
	smp_tune_scheduling();
	 */
	smp_store_cpu_info(boot_cpu_id);
	printk("CPU%d: ", boot_cpu_id);
	print_cpu_info(&cpu_data[boot_cpu_id]);

	if(is_cpu_quad()) {
		/* booting on a Quad CPU */
		printk("VOYAGER SMP: Boot CPU is Quad\n");
		qic_setup();
		do_quad_bootstrap();
	}

	/* enable our own CPIs */
	vic_enable_cpi();

	cpu_set(boot_cpu_id, cpu_online_map);
	cpu_set(boot_cpu_id, cpu_callout_map);
	
	/* loop over all the extended VIC CPUs and boot them.  The 
	 * Quad CPUs must be bootstrapped by their extended VIC cpu */
	for(i = 0; i < NR_CPUS; i++) {
		if(i == boot_cpu_id || !cpu_isset(i, phys_cpu_present_map))
			continue;
		do_boot_cpu(i);
		/* This udelay seems to be needed for the Quad boots
		 * don't remove unless you know what you're doing */
		udelay(1000);
	}
	/* we could compute the total bogomips here, but why bother?,
	 * Code added from smpboot.c */
	{
		unsigned long bogosum = 0;
		for (i = 0; i < NR_CPUS; i++)
			if (cpu_isset(i, cpu_online_map))
				bogosum += cpu_data[i].loops_per_jiffy;
		printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
			cpucount+1,
			bogosum/(500000/HZ),
			(bogosum/(5000/HZ))%100);
	}
	voyager_extended_cpus = hweight32(voyager_extended_vic_processors);
	printk("VOYAGER: Extended (interrupt handling CPUs): %d, non-extended: %d\n", voyager_extended_cpus, num_booting_cpus() - voyager_extended_cpus);
	/* that's it, switch to symmetric mode */
	outb(0, VIC_PRIORITY_REGISTER);
	outb(0, VIC_CLAIM_REGISTER_0);
	outb(0, VIC_CLAIM_REGISTER_1);
	
	VDEBUG(("VOYAGER SMP: Booted with %d CPUs\n", num_booting_cpus()));
}

/* Reload the secondary CPUs task structure (this function does not
 * return ) */
void __init 
initialize_secondary(void)
{
#if 0
	// AC kernels only
	set_current(hard_get_current());
#endif

	/*
	 * We don't actually need to load the full TSS,
	 * basically just the stack pointer and the eip.
	 */

	asm volatile(
		"movl %0,%%esp\n\t"
		"jmp *%1"
		:
		:"r" (current->thread.esp),"r" (current->thread.eip));
}

/* handle a Voyager SYS_INT -- If we don't, the base board will
 * panic the system.
 *
 * System interrupts occur because some problem was detected on the
 * various busses.  To find out what you have to probe all the
 * hardware via the CAT bus.  FIXME: At the moment we do nothing. */
fastcall void
smp_vic_sys_interrupt(struct pt_regs *regs)
{
	ack_CPI(VIC_SYS_INT);
	printk("Voyager SYSTEM INTERRUPT\n");	
}

/* Handle a voyager CMN_INT; These interrupts occur either because of
 * a system status change or because a single bit memory error
 * occurred.  FIXME: At the moment, ignore all this. */
fastcall void
smp_vic_cmn_interrupt(struct pt_regs *regs)
{
	static __u8 in_cmn_int = 0;
	static DEFINE_SPINLOCK(cmn_int_lock);

	/* common ints are broadcast, so make sure we only do this once */
	_raw_spin_lock(&cmn_int_lock);
	if(in_cmn_int)
		goto unlock_end;

	in_cmn_int++;
	_raw_spin_unlock(&cmn_int_lock);

	VDEBUG(("Voyager COMMON INTERRUPT\n"));

	if(voyager_level == 5)
		voyager_cat_do_common_interrupt();

	_raw_spin_lock(&cmn_int_lock);
	in_cmn_int = 0;
 unlock_end:
	_raw_spin_unlock(&cmn_int_lock);
	ack_CPI(VIC_CMN_INT);
}

/*
 * Reschedule call back. Nothing to do, all the work is done
 * automatically when we return from the interrupt.  */
static void
smp_reschedule_interrupt(void)
{
	/* do nothing */
}

static struct mm_struct * flush_mm;
static unsigned long flush_va;
static DEFINE_SPINLOCK(tlbstate_lock);
#define FLUSH_ALL	0xffffffff

/*
 * We cannot call mmdrop() because we are in interrupt context, 
 * instead update mm->cpu_vm_mask.
 *
 * We need to reload %cr3 since the page tables may be going
 * away from under us..
 */
static inline void
leave_mm (unsigned long cpu)
{
	if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK)
		BUG();
	cpu_clear(cpu, per_cpu(cpu_tlbstate, cpu).active_mm->cpu_vm_mask);
	load_cr3(swapper_pg_dir);
}


/*
 * Invalidate call-back
 */
static void 
smp_invalidate_interrupt(void)
{
	__u8 cpu = smp_processor_id();

	if (!test_bit(cpu, &smp_invalidate_needed))
		return;
	/* This will flood messages.  Don't uncomment unless you see
	 * Problems with cross cpu invalidation
	VDEBUG(("VOYAGER SMP: CPU%d received INVALIDATE_CPI\n",
		smp_processor_id()));
	*/

	if (flush_mm == per_cpu(cpu_tlbstate, cpu).active_mm) {
		if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) {
			if (flush_va == FLUSH_ALL)
				local_flush_tlb();
			else
				__flush_tlb_one(flush_va);
		} else
			leave_mm(cpu);
	}
	smp_mb__before_clear_bit();
	clear_bit(cpu, &smp_invalidate_needed);
	smp_mb__after_clear_bit();
}

/* All the new flush operations for 2.4 */


/* This routine is called with a physical cpu mask */
static void
flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
						unsigned long va)
{
	int stuck = 50000;

	if (!cpumask)
		BUG();
	if ((cpumask & cpus_addr(cpu_online_map)[0]) != cpumask)
		BUG();
	if (cpumask & (1 << smp_processor_id()))
		BUG();
	if (!mm)
		BUG();

	spin_lock(&tlbstate_lock);
	
	flush_mm = mm;
	flush_va = va;
	atomic_set_mask(cpumask, &smp_invalidate_needed);
	/*
	 * We have to send the CPI only to
	 * CPUs affected.
	 */
	send_CPI(cpumask, VIC_INVALIDATE_CPI);

	while (smp_invalidate_needed) {
		mb();
		if(--stuck == 0) {
			printk("***WARNING*** Stuck doing invalidate CPI (CPU%d)\n", smp_processor_id());
			break;
		}
	}

	/* Uncomment only to debug invalidation problems
	VDEBUG(("VOYAGER SMP: Completed invalidate CPI (CPU%d)\n", cpu));
	*/

	flush_mm = NULL;
	flush_va = 0;
	spin_unlock(&tlbstate_lock);
}

void
flush_tlb_current_task(void)
{
	struct mm_struct *mm = current->mm;
	unsigned long cpu_mask;

	preempt_disable();

	cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id());
	local_flush_tlb();
	if (cpu_mask)
		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);

	preempt_enable();
}


void
flush_tlb_mm (struct mm_struct * mm)
{
	unsigned long cpu_mask;

	preempt_disable();

	cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id());

	if (current->active_mm == mm) {
		if (current->mm)
			local_flush_tlb();
		else
			leave_mm(smp_processor_id());
	}
	if (cpu_mask)
		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);

	preempt_enable();
}

void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
{
	struct mm_struct *mm = vma->vm_mm;
	unsigned long cpu_mask;

	preempt_disable();

	cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id());
	if (current->active_mm == mm) {
		if(current->mm)
			__flush_tlb_one(va);
		 else
		 	leave_mm(smp_processor_id());
	}

	if (cpu_mask)
		flush_tlb_others(cpu_mask, mm, va);

	preempt_enable();
}
EXPORT_SYMBOL(flush_tlb_page);

/* enable the requested IRQs */
static void
smp_enable_irq_interrupt(void)
{
	__u8 irq;
	__u8 cpu = get_cpu();

	VDEBUG(("VOYAGER SMP: CPU%d enabling irq mask 0x%x\n", cpu,
	       vic_irq_enable_mask[cpu]));

	spin_lock(&vic_irq_lock);
	for(irq = 0; irq < 16; irq++) {
		if(vic_irq_enable_mask[cpu] & (1<<irq))
			enable_local_vic_irq(irq);
	}
	vic_irq_enable_mask[cpu] = 0;
	spin_unlock(&vic_irq_lock);

	put_cpu_no_resched();
}
	
/*
 *	CPU halt call-back
 */
static void
smp_stop_cpu_function(void *dummy)
{
	VDEBUG(("VOYAGER SMP: CPU%d is STOPPING\n", smp_processor_id()));
	cpu_clear(smp_processor_id(), cpu_online_map);
	local_irq_disable();
	for(;;)
		halt();
}

static DEFINE_SPINLOCK(call_lock);

struct call_data_struct {
	void (*func) (void *info);
	void *info;
	volatile unsigned long started;
	volatile unsigned long finished;
	int wait;
};

static struct call_data_struct * call_data;

/* execute a thread on a new CPU.  The function to be called must be
 * previously set up.  This is used to schedule a function for
 * execution on all CPU's - set up the function then broadcast a
 * function_interrupt CPI to come here on each CPU */
static void
smp_call_function_interrupt(void)
{
	void (*func) (void *info) = call_data->func;
	void *info = call_data->info;
	/* must take copy of wait because call_data may be replaced
	 * unless the function is waiting for us to finish */
	int wait = call_data->wait;
	__u8 cpu = smp_processor_id();

	/*
	 * Notify initiating CPU that I've grabbed the data and am
	 * about to execute the function
	 */
	mb();
	if(!test_and_clear_bit(cpu, &call_data->started)) {
		/* If the bit wasn't set, this could be a replay */
		printk(KERN_WARNING "VOYAGER SMP: CPU %d received call funtion with no call pending\n", cpu);
		return;
	}
	/*
	 * At this point the info structure may be out of scope unless wait==1
	 */
	irq_enter();
	(*func)(info);
	irq_exit();
	if (wait) {
		mb();
		clear_bit(cpu, &call_data->finished);
	}
}

/* Call this function on all CPUs using the function_interrupt above 
    <func> The function to run. This must be fast and non-blocking.
    <info> An arbitrary pointer to pass to the function.
    <retry> If true, keep retrying until ready.
    <wait> If true, wait until function has completed on other CPUs.
    [RETURNS] 0 on success, else a negative status code. Does not return until
    remote CPUs are nearly ready to execute <<func>> or are or have executed.
*/
int
smp_call_function (void (*func) (void *info), void *info, int retry,
		   int wait)
{
	struct call_data_struct data;
	__u32 mask = cpus_addr(cpu_online_map)[0];

	mask &= ~(1<<smp_processor_id());

	if (!mask)
		return 0;

	/* Can deadlock when called with interrupts disabled */
	WARN_ON(irqs_disabled());

	data.func = func;
	data.info = info;
	data.started = mask;
	data.wait = wait;
	if (wait)
		data.finished = mask;

	spin_lock(&call_lock);
	call_data = &data;
	wmb();
	/* Send a message to all other CPUs and wait for them to respond */
	send_CPI_allbutself(VIC_CALL_FUNCTION_CPI);

	/* Wait for response */
	while (data.started)
		barrier();

	if (wait)
		while (data.finished)
			barrier();

	spin_unlock(&call_lock);

	return 0;
}
EXPORT_SYMBOL(smp_call_function);

/* Sorry about the name.  In an APIC based system, the APICs
 * themselves are programmed to send a timer interrupt.  This is used
 * by linux to reschedule the processor.  Voyager doesn't have this,
 * so we use the system clock to interrupt one processor, which in
 * turn, broadcasts a timer CPI to all the others --- we receive that
 * CPI here.  We don't use this actually for counting so losing
 * ticks doesn't matter 
 *
 * FIXME: For those CPU's which actually have a local APIC, we could
 * try to use it to trigger this interrupt instead of having to
 * broadcast the timer tick.  Unfortunately, all my pentium DYADs have
 * no local APIC, so I can't do this
 *
 * This function is currently a placeholder and is unused in the code */
fastcall void 
smp_apic_timer_interrupt(struct pt_regs *regs)
{
	struct pt_regs *old_regs = set_irq_regs(regs);
	wrapper_smp_local_timer_interrupt();
	set_irq_regs(old_regs);
}

/* All of the QUAD interrupt GATES */
fastcall void
smp_qic_timer_interrupt(struct pt_regs *regs)
{
	struct pt_regs *old_regs = set_irq_regs(regs);
	ack_QIC_CPI(QIC_TIMER_CPI);
	wrapper_smp_local_timer_interrupt();
	set_irq_regs(old_regs);
}

fastcall void
smp_qic_invalidate_interrupt(struct pt_regs *regs)
{
	ack_QIC_CPI(QIC_INVALIDATE_CPI);
	smp_invalidate_interrupt();
}

fastcall void
smp_qic_reschedule_interrupt(struct pt_regs *regs)
{
	ack_QIC_CPI(QIC_RESCHEDULE_CPI);
	smp_reschedule_interrupt();
}

fastcall void
smp_qic_enable_irq_interrupt(struct pt_regs *regs)
{
	ack_QIC_CPI(QIC_ENABLE_IRQ_CPI);
	smp_enable_irq_interrupt();
}

fastcall void
smp_qic_call_function_interrupt(struct pt_regs *regs)
{
	ack_QIC_CPI(QIC_CALL_FUNCTION_CPI);
	smp_call_function_interrupt();
}

fastcall void
smp_vic_cpi_interrupt(struct pt_regs *regs)
{
	struct pt_regs *old_regs = set_irq_regs(regs);
	__u8 cpu = smp_processor_id();

	if(is_cpu_quad())
		ack_QIC_CPI(VIC_CPI_LEVEL0);
	else
		ack_VIC_CPI(VIC_CPI_LEVEL0);

	if(test_and_clear_bit(VIC_TIMER_CPI, &vic_cpi_mailbox[cpu]))
		wrapper_smp_local_timer_interrupt();
	if(test_and_clear_bit(VIC_INVALIDATE_CPI, &vic_cpi_mailbox[cpu]))
		smp_invalidate_interrupt();
	if(test_and_clear_bit(VIC_RESCHEDULE_CPI, &vic_cpi_mailbox[cpu]))
		smp_reschedule_interrupt();
	if(test_and_clear_bit(VIC_ENABLE_IRQ_CPI, &vic_cpi_mailbox[cpu]))
		smp_enable_irq_interrupt();
	if(test_and_clear_bit(VIC_CALL_FUNCTION_CPI, &vic_cpi_mailbox[cpu]))
		smp_call_function_interrupt();
	set_irq_regs(old_regs);
}

static void
do_flush_tlb_all(void* info)
{
	unsigned long cpu = smp_processor_id();

	__flush_tlb_all();
	if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_LAZY)
		leave_mm(cpu);
}


/* flush the TLB of every active CPU in the system */
void
flush_tlb_all(void)
{
	on_each_cpu(do_flush_tlb_all, 0, 1, 1);
}

/* used to set up the trampoline for other CPUs when the memory manager
 * is sorted out */
void __init
smp_alloc_memory(void)
{
	trampoline_base = (__u32)alloc_bootmem_low_pages(PAGE_SIZE);
	if(__pa(trampoline_base) >= 0x93000)
		BUG();
}

/* send a reschedule CPI to one CPU by physical CPU number*/
void
smp_send_reschedule(int cpu)
{
	send_one_CPI(cpu, VIC_RESCHEDULE_CPI);
}


int
hard_smp_processor_id(void)
{
	__u8 i;
	__u8 cpumask = inb(VIC_PROC_WHO_AM_I);
	if((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER)
		return cpumask & 0x1F;

	for(i = 0; i < 8; i++) {
		if(cpumask & (1<<i))
			return i;
	}
	printk("** WARNING ** Illegal cpuid returned by VIC: %d", cpumask);
	return 0;
}

int
safe_smp_processor_id(void)
{
	return hard_smp_processor_id();
}

/* broadcast a halt to all other CPUs */
void
smp_send_stop(void)
{
	smp_call_function(smp_stop_cpu_function, NULL, 1, 1);
}

/* this function is triggered in time.c when a clock tick fires
 * we need to re-broadcast the tick to all CPUs */
void
smp_vic_timer_interrupt(void)
{
	send_CPI_allbutself(VIC_TIMER_CPI);
	smp_local_timer_interrupt();
}

/* local (per CPU) timer interrupt.  It does both profiling and
 * process statistics/rescheduling.
 *
 * We do profiling in every local tick, statistics/rescheduling
 * happen only every 'profiling multiplier' ticks. The default
 * multiplier is 1 and it can be changed by writing the new multiplier
 * value into /proc/profile.
 */
void
smp_local_timer_interrupt(void)
{
	int cpu = smp_processor_id();
	long weight;

	profile_tick(CPU_PROFILING);
	if (--per_cpu(prof_counter, cpu) <= 0) {
		/*
		 * The multiplier may have changed since the last time we got
		 * to this point as a result of the user writing to
		 * /proc/profile. In this case we need to adjust the APIC
		 * timer accordingly.
		 *
		 * Interrupts are already masked off at this point.
		 */
		per_cpu(prof_counter,cpu) = per_cpu(prof_multiplier, cpu);
		if (per_cpu(prof_counter, cpu) !=
					per_cpu(prof_old_multiplier, cpu)) {
			/* FIXME: need to update the vic timer tick here */
			per_cpu(prof_old_multiplier, cpu) =
						per_cpu(prof_counter, cpu);
		}

		update_process_times(user_mode_vm(get_irq_regs()));
	}

	if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
		/* only extended VIC processors participate in
		 * interrupt distribution */
		return;

	/*
	 * We take the 'long' return path, and there every subsystem
	 * grabs the apropriate locks (kernel lock/ irq lock).
	 *
	 * we might want to decouple profiling from the 'long path',
	 * and do the profiling totally in assembly.
	 *
	 * Currently this isn't too much of an issue (performance wise),
	 * we can take more than 100K local irqs per second on a 100 MHz P5.
	 */

	if((++vic_tick[cpu] & 0x7) != 0)
		return;
	/* get here every 16 ticks (about every 1/6 of a second) */

	/* Change our priority to give someone else a chance at getting
         * the IRQ. The algorithm goes like this:
	 *
	 * In the VIC, the dynamically routed interrupt is always
	 * handled by the lowest priority eligible (i.e. receiving
	 * interrupts) CPU.  If >1 eligible CPUs are equal lowest, the
	 * lowest processor number gets it.
	 *
	 * The priority of a CPU is controlled by a special per-CPU
	 * VIC priority register which is 3 bits wide 0 being lowest
	 * and 7 highest priority..
	 *
	 * Therefore we subtract the average number of interrupts from
	 * the number we've fielded.  If this number is negative, we
	 * lower the activity count and if it is positive, we raise
	 * it.
	 *
	 * I'm afraid this still leads to odd looking interrupt counts:
	 * the totals are all roughly equal, but the individual ones
	 * look rather skewed.
	 *
	 * FIXME: This algorithm is total crap when mixed with SMP
	 * affinity code since we now try to even up the interrupt
	 * counts when an affinity binding is keeping them on a
	 * particular CPU*/
	weight = (vic_intr_count[cpu]*voyager_extended_cpus
		  - vic_intr_total) >> 4;
	weight += 4;
	if(weight > 7)
		weight = 7;
	if(weight < 0)
		weight = 0;
	
	outb((__u8)weight, VIC_PRIORITY_REGISTER);

#ifdef VOYAGER_DEBUG
	if((vic_tick[cpu] & 0xFFF) == 0) {
		/* print this message roughly every 25 secs */
		printk("VOYAGER SMP: vic_tick[%d] = %lu, weight = %ld\n",
		       cpu, vic_tick[cpu], weight);
	}
#endif
}

/* setup the profiling timer */
int 
setup_profiling_timer(unsigned int multiplier)
{
	int i;

	if ( (!multiplier))
		return -EINVAL;

	/* 
	 * Set the new multiplier for each CPU. CPUs don't start using the
	 * new values until the next timer interrupt in which they do process
	 * accounting.
	 */
	for (i = 0; i < NR_CPUS; ++i)
		per_cpu(prof_multiplier, i) = multiplier;

	return 0;
}

/* This is a bit of a mess, but forced on us by the genirq changes
 * there's no genirq handler that really does what voyager wants
 * so hack it up with the simple IRQ handler */
static void fastcall
handle_vic_irq(unsigned int irq, struct irq_desc *desc)
{
	before_handle_vic_irq(irq);
	handle_simple_irq(irq, desc);
	after_handle_vic_irq(irq);
}


/*  The CPIs are handled in the per cpu 8259s, so they must be
 *  enabled to be received: FIX: enabling the CPIs in the early
 *  boot sequence interferes with bug checking; enable them later
 *  on in smp_init */
#define VIC_SET_GATE(cpi, vector) \
	set_intr_gate((cpi) + VIC_DEFAULT_CPI_BASE, (vector))
#define QIC_SET_GATE(cpi, vector) \
	set_intr_gate((cpi) + QIC_DEFAULT_CPI_BASE, (vector))

void __init
smp_intr_init(void)
{
	int i;

	/* initialize the per cpu irq mask to all disabled */
	for(i = 0; i < NR_CPUS; i++)
		vic_irq_mask[i] = 0xFFFF;

	VIC_SET_GATE(VIC_CPI_LEVEL0, vic_cpi_interrupt);

	VIC_SET_GATE(VIC_SYS_INT, vic_sys_interrupt);
	VIC_SET_GATE(VIC_CMN_INT, vic_cmn_interrupt);

	QIC_SET_GATE(QIC_TIMER_CPI, qic_timer_interrupt);
	QIC_SET_GATE(QIC_INVALIDATE_CPI, qic_invalidate_interrupt);
	QIC_SET_GATE(QIC_RESCHEDULE_CPI, qic_reschedule_interrupt);
	QIC_SET_GATE(QIC_ENABLE_IRQ_CPI, qic_enable_irq_interrupt);
	QIC_SET_GATE(QIC_CALL_FUNCTION_CPI, qic_call_function_interrupt);
	

	/* now put the VIC descriptor into the first 48 IRQs 
	 *
	 * This is for later: first 16 correspond to PC IRQs; next 16
	 * are Primary MC IRQs and final 16 are Secondary MC IRQs */
	for(i = 0; i < 48; i++)
		set_irq_chip_and_handler(i, &vic_chip, handle_vic_irq);
}

/* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per
 * processor to receive CPI */
static void
send_CPI(__u32 cpuset, __u8 cpi)
{
	int cpu;
	__u32 quad_cpuset = (cpuset & voyager_quad_processors);

	if(cpi < VIC_START_FAKE_CPI) {
		/* fake CPI are only used for booting, so send to the 
		 * extended quads as well---Quads must be VIC booted */
		outb((__u8)(cpuset), VIC_CPI_Registers[cpi]);
		return;
	}
	if(quad_cpuset)
		send_QIC_CPI(quad_cpuset, cpi);
	cpuset &= ~quad_cpuset;
	cpuset &= 0xff;		/* only first 8 CPUs vaild for VIC CPI */
	if(cpuset == 0)
		return;
	for_each_online_cpu(cpu) {
		if(cpuset & (1<<cpu))
			set_bit(cpi, &vic_cpi_mailbox[cpu]);
	}
	if(cpuset)
		outb((__u8)cpuset, VIC_CPI_Registers[VIC_CPI_LEVEL0]);
}

/* Acknowledge receipt of CPI in the QIC, clear in QIC hardware and
 * set the cache line to shared by reading it.
 *
 * DON'T make this inline otherwise the cache line read will be
 * optimised away
 * */
static int
ack_QIC_CPI(__u8 cpi) {
	__u8 cpu = hard_smp_processor_id();

	cpi &= 7;

	outb(1<<cpi, QIC_INTERRUPT_CLEAR1);
	return voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi;
}

static void
ack_special_QIC_CPI(__u8 cpi)
{
	switch(cpi) {
	case VIC_CMN_INT:
		outb(QIC_CMN_INT, QIC_INTERRUPT_CLEAR0);
		break;
	case VIC_SYS_INT:
		outb(QIC_SYS_INT, QIC_INTERRUPT_CLEAR0);
		break;
	}
	/* also clear at the VIC, just in case (nop for non-extended proc) */
	ack_VIC_CPI(cpi);
}

/* Acknowledge receipt of CPI in the VIC (essentially an EOI) */
static void
ack_VIC_CPI(__u8 cpi)
{
#ifdef VOYAGER_DEBUG
	unsigned long flags;
	__u16 isr;
	__u8 cpu = smp_processor_id();

	local_irq_save(flags);
	isr = vic_read_isr();
	if((isr & (1<<(cpi &7))) == 0) {
		printk("VOYAGER SMP: CPU%d lost CPI%d\n", cpu, cpi);
	}
#endif
	/* send specific EOI; the two system interrupts have
	 * bit 4 set for a separate vector but behave as the
	 * corresponding 3 bit intr */
	outb_p(0x60|(cpi & 7),0x20);

#ifdef VOYAGER_DEBUG
	if((vic_read_isr() & (1<<(cpi &7))) != 0) {
		printk("VOYAGER SMP: CPU%d still asserting CPI%d\n", cpu, cpi);
	}
	local_irq_restore(flags);
#endif
}

/* cribbed with thanks from irq.c */
#define __byte(x,y) 	(((unsigned char *)&(y))[x])
#define cached_21(cpu)	(__byte(0,vic_irq_mask[cpu]))
#define cached_A1(cpu)	(__byte(1,vic_irq_mask[cpu]))

static unsigned int
startup_vic_irq(unsigned int irq)
{
	unmask_vic_irq(irq);

	return 0;
}

/* The enable and disable routines.  This is where we run into
 * conflicting architectural philosophy.  Fundamentally, the voyager
 * architecture does not expect to have to disable interrupts globally
 * (the IRQ controllers belong to each CPU).  The processor masquerade
 * which is used to start the system shouldn't be used in a running OS
 * since it will cause great confusion if two separate CPUs drive to
 * the same IRQ controller (I know, I've tried it).
 *
 * The solution is a variant on the NCR lazy SPL design:
 *
 * 1) To disable an interrupt, do nothing (other than set the
 *    IRQ_DISABLED flag).  This dares the interrupt actually to arrive.
 *
 * 2) If the interrupt dares to come in, raise the local mask against
 *    it (this will result in all the CPU masks being raised
 *    eventually).
 *
 * 3) To enable the interrupt, lower the mask on the local CPU and
 *    broadcast an Interrupt enable CPI which causes all other CPUs to
 *    adjust their masks accordingly.  */

static void
unmask_vic_irq(unsigned int irq)
{
	/* linux doesn't to processor-irq affinity, so enable on
	 * all CPUs we know about */
	int cpu = smp_processor_id(), real_cpu;
	__u16 mask = (1<<irq);
	__u32 processorList = 0;
	unsigned long flags;

	VDEBUG(("VOYAGER: unmask_vic_irq(%d) CPU%d affinity 0x%lx\n",
		irq, cpu, cpu_irq_affinity[cpu]));
	spin_lock_irqsave(&vic_irq_lock, flags);
	for_each_online_cpu(real_cpu) {
		if(!(voyager_extended_vic_processors & (1<<real_cpu)))
			continue;
		if(!(cpu_irq_affinity[real_cpu] & mask)) {
			/* irq has no affinity for this CPU, ignore */
			continue;
		}
		if(real_cpu == cpu) {
			enable_local_vic_irq(irq);
		}
		else if(vic_irq_mask[real_cpu] & mask) {
			vic_irq_enable_mask[real_cpu] |= mask;
			processorList |= (1<<real_cpu);
		}
	}
	spin_unlock_irqrestore(&vic_irq_lock, flags);
	if(processorList)
		send_CPI(processorList, VIC_ENABLE_IRQ_CPI);
}

static void
mask_vic_irq(unsigned int irq)
{
	/* lazy disable, do nothing */
}

static void
enable_local_vic_irq(unsigned int irq)
{
	__u8 cpu = smp_processor_id();
	__u16 mask = ~(1 << irq);
	__u16 old_mask = vic_irq_mask[cpu];

	vic_irq_mask[cpu] &= mask;
	if(vic_irq_mask[cpu] == old_mask)
		return;

	VDEBUG(("VOYAGER DEBUG: Enabling irq %d in hardware on CPU %d\n",
		irq, cpu));

	if (irq & 8) {
		outb_p(cached_A1(cpu),0xA1);
		(void)inb_p(0xA1);
	}
	else {
		outb_p(cached_21(cpu),0x21);
		(void)inb_p(0x21);
	}
}

static void
disable_local_vic_irq(unsigned int irq)
{
	__u8 cpu = smp_processor_id();
	__u16 mask = (1 << irq);
	__u16 old_mask = vic_irq_mask[cpu];

	if(irq == 7)
		return;

	vic_irq_mask[cpu] |= mask;
	if(old_mask == vic_irq_mask[cpu])
		return;

	VDEBUG(("VOYAGER DEBUG: Disabling irq %d in hardware on CPU %d\n",
		irq, cpu));

	if (irq & 8) {
		outb_p(cached_A1(cpu),0xA1);
		(void)inb_p(0xA1);
	}
	else {
		outb_p(cached_21(cpu),0x21);
		(void)inb_p(0x21);
	}
}

/* The VIC is level triggered, so the ack can only be issued after the
 * interrupt completes.  However, we do Voyager lazy interrupt
 * handling here: It is an extremely expensive operation to mask an
 * interrupt in the vic, so we merely set a flag (IRQ_DISABLED).  If
 * this interrupt actually comes in, then we mask and ack here to push
 * the interrupt off to another CPU */
static void
before_handle_vic_irq(unsigned int irq)
{
	irq_desc_t *desc = irq_desc + irq;
	__u8 cpu = smp_processor_id();

	_raw_spin_lock(&vic_irq_lock);
	vic_intr_total++;
	vic_intr_count[cpu]++;

	if(!(cpu_irq_affinity[cpu] & (1<<irq))) {
		/* The irq is not in our affinity mask, push it off
		 * onto another CPU */
		VDEBUG(("VOYAGER DEBUG: affinity triggered disable of irq %d on cpu %d\n",
			irq, cpu));
		disable_local_vic_irq(irq);
		/* set IRQ_INPROGRESS to prevent the handler in irq.c from
		 * actually calling the interrupt routine */
		desc->status |= IRQ_REPLAY | IRQ_INPROGRESS;
	} else if(desc->status & IRQ_DISABLED) {
		/* Damn, the interrupt actually arrived, do the lazy
		 * disable thing. The interrupt routine in irq.c will
		 * not handle a IRQ_DISABLED interrupt, so nothing more
		 * need be done here */
		VDEBUG(("VOYAGER DEBUG: lazy disable of irq %d on CPU %d\n",
			irq, cpu));
		disable_local_vic_irq(irq);
		desc->status |= IRQ_REPLAY;
	} else {
		desc->status &= ~IRQ_REPLAY;
	}

	_raw_spin_unlock(&vic_irq_lock);
}

/* Finish the VIC interrupt: basically mask */
static void
after_handle_vic_irq(unsigned int irq)
{
	irq_desc_t *desc = irq_desc + irq;

	_raw_spin_lock(&vic_irq_lock);
	{
		unsigned int status = desc->status & ~IRQ_INPROGRESS;
#ifdef VOYAGER_DEBUG
		__u16 isr;
#endif

		desc->status = status;
		if ((status & IRQ_DISABLED))
			disable_local_vic_irq(irq);
#ifdef VOYAGER_DEBUG
		/* DEBUG: before we ack, check what's in progress */
		isr = vic_read_isr();
		if((isr & (1<<irq) && !(status & IRQ_REPLAY)) == 0) {
			int i;
			__u8 cpu = smp_processor_id();
			__u8 real_cpu;
			int mask; /* Um... initialize me??? --RR */

			printk("VOYAGER SMP: CPU%d lost interrupt %d\n",
			       cpu, irq);
			for_each_possible_cpu(real_cpu, mask) {

				outb(VIC_CPU_MASQUERADE_ENABLE | real_cpu,
				     VIC_PROCESSOR_ID);
				isr = vic_read_isr();
				if(isr & (1<<irq)) {
					printk("VOYAGER SMP: CPU%d ack irq %d\n",
					       real_cpu, irq);
					ack_vic_irq(irq);
				}
				outb(cpu, VIC_PROCESSOR_ID);
			}
		}
#endif /* VOYAGER_DEBUG */
		/* as soon as we ack, the interrupt is eligible for
		 * receipt by another CPU so everything must be in
		 * order here  */
		ack_vic_irq(irq);
		if(status & IRQ_REPLAY) {
			/* replay is set if we disable the interrupt
			 * in the before_handle_vic_irq() routine, so
			 * clear the in progress bit here to allow the
			 * next CPU to handle this correctly */
			desc->status &= ~(IRQ_REPLAY | IRQ_INPROGRESS);
		}
#ifdef VOYAGER_DEBUG
		isr = vic_read_isr();
		if((isr & (1<<irq)) != 0)
			printk("VOYAGER SMP: after_handle_vic_irq() after ack irq=%d, isr=0x%x\n",
			       irq, isr);
#endif /* VOYAGER_DEBUG */
	}
	_raw_spin_unlock(&vic_irq_lock);

	/* All code after this point is out of the main path - the IRQ
	 * may be intercepted by another CPU if reasserted */
}


/* Linux processor - interrupt affinity manipulations.
 *
 * For each processor, we maintain a 32 bit irq affinity mask.
 * Initially it is set to all 1's so every processor accepts every
 * interrupt.  In this call, we change the processor's affinity mask:
 *
 * Change from enable to disable:
 *
 * If the interrupt ever comes in to the processor, we will disable it
 * and ack it to push it off to another CPU, so just accept the mask here.
 *
 * Change from disable to enable:
 *
 * change the mask and then do an interrupt enable CPI to re-enable on
 * the selected processors */

void
set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
{
	/* Only extended processors handle interrupts */
	unsigned long real_mask;
	unsigned long irq_mask = 1 << irq;
	int cpu;

	real_mask = cpus_addr(mask)[0] & voyager_extended_vic_processors;
	
	if(cpus_addr(mask)[0] == 0)
		/* can't have no cpu's to accept the interrupt -- extremely
		 * bad things will happen */
		return;

	if(irq == 0)
		/* can't change the affinity of the timer IRQ.  This
		 * is due to the constraint in the voyager
		 * architecture that the CPI also comes in on and IRQ
		 * line and we have chosen IRQ0 for this.  If you
		 * raise the mask on this interrupt, the processor
		 * will no-longer be able to accept VIC CPIs */
		return;

	if(irq >= 32) 
		/* You can only have 32 interrupts in a voyager system
		 * (and 32 only if you have a secondary microchannel
		 * bus) */
		return;

	for_each_online_cpu(cpu) {
		unsigned long cpu_mask = 1 << cpu;
		
		if(cpu_mask & real_mask) {
			/* enable the interrupt for this cpu */
			cpu_irq_affinity[cpu] |= irq_mask;
		} else {
			/* disable the interrupt for this cpu */
			cpu_irq_affinity[cpu] &= ~irq_mask;
		}
	}
	/* this is magic, we now have the correct affinity maps, so
	 * enable the interrupt.  This will send an enable CPI to
	 * those cpu's who need to enable it in their local masks,
	 * causing them to correct for the new affinity . If the
	 * interrupt is currently globally disabled, it will simply be
	 * disabled again as it comes in (voyager lazy disable).  If
	 * the affinity map is tightened to disable the interrupt on a
	 * cpu, it will be pushed off when it comes in */
	unmask_vic_irq(irq);
}

static void
ack_vic_irq(unsigned int irq)
{
	if (irq & 8) {
		outb(0x62,0x20);	/* Specific EOI to cascade */
		outb(0x60|(irq & 7),0xA0);
	} else {
		outb(0x60 | (irq & 7),0x20);
	}
}

/* enable the CPIs.  In the VIC, the CPIs are delivered by the 8259
 * but are not vectored by it.  This means that the 8259 mask must be
 * lowered to receive them */
static __init void
vic_enable_cpi(void)
{
	__u8 cpu = smp_processor_id();
	
	/* just take a copy of the current mask (nop for boot cpu) */
	vic_irq_mask[cpu] = vic_irq_mask[boot_cpu_id];

	enable_local_vic_irq(VIC_CPI_LEVEL0);
	enable_local_vic_irq(VIC_CPI_LEVEL1);
	/* for sys int and cmn int */
	enable_local_vic_irq(7);

	if(is_cpu_quad()) {
		outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0);
		outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1);
		VDEBUG(("VOYAGER SMP: QIC ENABLE CPI: CPU%d: MASK 0x%x\n",
			cpu, QIC_CPI_ENABLE));
	}

	VDEBUG(("VOYAGER SMP: ENABLE CPI: CPU%d: MASK 0x%x\n",
		cpu, vic_irq_mask[cpu]));
}

void
voyager_smp_dump()
{
	int old_cpu = smp_processor_id(), cpu;

	/* dump the interrupt masks of each processor */
	for_each_online_cpu(cpu) {
		__u16 imr, isr, irr;
		unsigned long flags;

		local_irq_save(flags);
		outb(VIC_CPU_MASQUERADE_ENABLE | cpu, VIC_PROCESSOR_ID);
		imr = (inb(0xa1) << 8) | inb(0x21);
		outb(0x0a, 0xa0);
		irr = inb(0xa0) << 8;
		outb(0x0a, 0x20);
		irr |= inb(0x20);
		outb(0x0b, 0xa0);
		isr = inb(0xa0) << 8;
		outb(0x0b, 0x20);
		isr |= inb(0x20);
		outb(old_cpu, VIC_PROCESSOR_ID);
		local_irq_restore(flags);
		printk("\tCPU%d: mask=0x%x, IMR=0x%x, IRR=0x%x, ISR=0x%x\n",
		       cpu, vic_irq_mask[cpu], imr, irr, isr);
#if 0
		/* These lines are put in to try to unstick an un ack'd irq */
		if(isr != 0) {
			int irq;
			for(irq=0; irq<16; irq++) {
				if(isr & (1<<irq)) {
					printk("\tCPU%d: ack irq %d\n",
					       cpu, irq);
					local_irq_save(flags);
					outb(VIC_CPU_MASQUERADE_ENABLE | cpu,
					     VIC_PROCESSOR_ID);
					ack_vic_irq(irq);
					outb(old_cpu, VIC_PROCESSOR_ID);
					local_irq_restore(flags);
				}
			}
		}
#endif
	}
}

void
smp_voyager_power_off(void *dummy)
{
	if(smp_processor_id() == boot_cpu_id) 
		voyager_power_off();
	else
		smp_stop_cpu_function(NULL);
}

void __init
smp_prepare_cpus(unsigned int max_cpus)
{
	/* FIXME: ignore max_cpus for now */
	smp_boot_cpus();
}

void __devinit smp_prepare_boot_cpu(void)
{
	cpu_set(smp_processor_id(), cpu_online_map);
	cpu_set(smp_processor_id(), cpu_callout_map);
	cpu_set(smp_processor_id(), cpu_possible_map);
	cpu_set(smp_processor_id(), cpu_present_map);
}

int __devinit
__cpu_up(unsigned int cpu)
{
	/* This only works at boot for x86.  See "rewrite" above. */
	if (cpu_isset(cpu, smp_commenced_mask))
		return -ENOSYS;

	/* In case one didn't come up */
	if (!cpu_isset(cpu, cpu_callin_map))
		return -EIO;
	/* Unleash the CPU! */
	cpu_set(cpu, smp_commenced_mask);
	while (!cpu_isset(cpu, cpu_online_map))
		mb();
	return 0;
}

void __init 
smp_cpus_done(unsigned int max_cpus)
{
	zap_low_mappings();
}

void __init
smp_setup_processor_id(void)
{
	current_thread_info()->cpu = hard_smp_processor_id();
}
