/* Copyright (C) 1999,2001 
 *
 * Author: J.E.J.Bottomley@HansenPartnership.com
 *
 * linux/arch/i386/kernel/voyager.c
 *
 * This file contains all the voyager specific routines for getting
 * initialisation of the architecture to function.  For additional
 * features see:
 *
 *	voyager_cat.c - Voyager CAT bus interface
 *	voyager_smp.c - Voyager SMP hal (emulates linux smp.c)
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/sysrq.h>
#include <asm/io.h>
#include <asm/voyager.h>
#include <asm/vic.h>
#include <linux/pm.h>
#include <linux/irq.h>
#include <asm/tlbflush.h>
#include <asm/arch_hooks.h>

/*
 * Power off function, if any
 */
void (*pm_power_off)(void);

int voyager_level = 0;

struct voyager_SUS *voyager_SUS = NULL;

#ifdef CONFIG_SMP
static void
voyager_dump(int dummy1, struct pt_regs *dummy2, struct tty_struct *dummy3)
{
	/* get here via a sysrq */
	voyager_smp_dump();
}

static struct sysrq_key_op sysrq_voyager_dump_op = {
	.handler	= voyager_dump,
	.help_msg	= "Voyager",
	.action_msg	= "Dump Voyager Status",
};
#endif

void
voyager_detect(struct voyager_bios_info *bios)
{
	if(bios->len != 0xff) {
		int class = (bios->class_1 << 8) 
			| (bios->class_2 & 0xff);

		printk("Voyager System detected.\n"
		       "        Class %x, Revision %d.%d\n",
		       class, bios->major, bios->minor);
		if(class == VOYAGER_LEVEL4) 
			voyager_level = 4;
		else if(class < VOYAGER_LEVEL5_AND_ABOVE)
			voyager_level = 3;
		else
			voyager_level = 5;
		printk("        Architecture Level %d\n", voyager_level);
		if(voyager_level < 4)
			printk("\n**WARNING**: Voyager HAL only supports Levels 4 and 5 Architectures at the moment\n\n");
		/* install the power off handler */
		pm_power_off = voyager_power_off;
#ifdef CONFIG_SMP
		register_sysrq_key('v', &sysrq_voyager_dump_op);
#endif
	} else {
		printk("\n\n**WARNING**: No Voyager Subsystem Found\n");
	}
}

void
voyager_system_interrupt(int cpl, void *dev_id, struct pt_regs *regs)
{
	printk("Voyager: detected system interrupt\n");
}

/* Routine to read information from the extended CMOS area */
__u8
voyager_extended_cmos_read(__u16 addr)
{
	outb(addr & 0xff, 0x74);
	outb((addr >> 8) & 0xff, 0x75);
	return inb(0x76);
}

/* internal definitions for the SUS Click Map of memory */

#define CLICK_ENTRIES	16
#define CLICK_SIZE	4096	/* click to byte conversion for Length */

typedef struct ClickMap {
	struct Entry {
		__u32	Address;
		__u32	Length;
	} Entry[CLICK_ENTRIES];
} ClickMap_t;


/* This routine is pretty much an awful hack to read the bios clickmap by
 * mapping it into page 0.  There are usually three regions in the map:
 * 	Base Memory
 * 	Extended Memory
 *	zero length marker for end of map
 *
 * Returns are 0 for failure and 1 for success on extracting region.
 */
int __init
voyager_memory_detect(int region, __u32 *start, __u32 *length)
{
	int i;
	int retval = 0;
	__u8 cmos[4];
	ClickMap_t *map;
	unsigned long map_addr;
	unsigned long old;

	if(region >= CLICK_ENTRIES) {
		printk("Voyager: Illegal ClickMap region %d\n", region);
		return 0;
	}

	for(i = 0; i < sizeof(cmos); i++)
		cmos[i] = voyager_extended_cmos_read(VOYAGER_MEMORY_CLICKMAP + i);

	map_addr = *(unsigned long *)cmos;

	/* steal page 0 for this */
	old = pg0[0];
	pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
	local_flush_tlb();
	/* now clear everything out but page 0 */
	map = (ClickMap_t *)(map_addr & (~PAGE_MASK));

	/* zero length is the end of the clickmap */
	if(map->Entry[region].Length != 0) {
		*length = map->Entry[region].Length * CLICK_SIZE;
		*start = map->Entry[region].Address;
		retval = 1;
	}

	/* replace the mapping */
	pg0[0] = old;
	local_flush_tlb();
	return retval;
}

/* voyager specific handling code for timer interrupts.  Used to hand
 * off the timer tick to the SMP code, since the VIC doesn't have an
 * internal timer (The QIC does, but that's another story). */
void
voyager_timer_interrupt(struct pt_regs *regs)
{
	if((jiffies & 0x3ff) == 0) {

		/* There seems to be something flaky in either
		 * hardware or software that is resetting the timer 0
		 * count to something much higher than it should be
		 * This seems to occur in the boot sequence, just
		 * before root is mounted.  Therefore, every 10
		 * seconds or so, we sanity check the timer zero count
		 * and kick it back to where it should be.
		 *
		 * FIXME: This is the most awful hack yet seen.  I
		 * should work out exactly what is interfering with
		 * the timer count settings early in the boot sequence
		 * and swiftly introduce it to something sharp and
		 * pointy.  */
		__u16 val;
		extern spinlock_t i8253_lock;

		spin_lock(&i8253_lock);
		
		outb_p(0x00, 0x43);
		val = inb_p(0x40);
		val |= inb(0x40) << 8;
		spin_unlock(&i8253_lock);

		if(val > LATCH) {
			printk("\nVOYAGER: countdown timer value too high (%d), resetting\n\n", val);
			spin_lock(&i8253_lock);
			outb(0x34,0x43);
			outb_p(LATCH & 0xff , 0x40);	/* LSB */
			outb(LATCH >> 8 , 0x40);	/* MSB */
			spin_unlock(&i8253_lock);
		}
	}
#ifdef CONFIG_SMP
	smp_vic_timer_interrupt(regs);
#endif
}

void
voyager_power_off(void)
{
	printk("VOYAGER Power Off\n");

	if(voyager_level == 5) {
		voyager_cat_power_off();
	} else if(voyager_level == 4) {
		/* This doesn't apparently work on most L4 machines,
		 * but the specs say to do this to get automatic power
		 * off.  Unfortunately, if it doesn't power off the
		 * machine, it ends up doing a cold restart, which
		 * isn't really intended, so comment out the code */
#if 0
		int port;

	  
		/* enable the voyager Configuration Space */
		outb((inb(VOYAGER_MC_SETUP) & 0xf0) | 0x8, 
		     VOYAGER_MC_SETUP);
		/* the port for the power off flag is an offset from the
		   floating base */
		port = (inb(VOYAGER_SSPB_RELOCATION_PORT) << 8) + 0x21;
		/* set the power off flag */
		outb(inb(port) | 0x1, port);
#endif
	}
	/* and wait for it to happen */
	for(;;) {
		__asm("cli");
		__asm("hlt");
	}
}

/* copied from process.c */
static inline void
kb_wait(void)
{
	int i;

	for (i=0; i<0x10000; i++)
		if ((inb_p(0x64) & 0x02) == 0)
			break;
}

void
machine_restart(char *cmd)
{
	printk("Voyager Warm Restart\n");
	kb_wait();

	if(voyager_level == 5) {
		/* write magic values to the RTC to inform system that
		 * shutdown is beginning */
		outb(0x8f, 0x70);
		outb(0x5 , 0x71);
		
		udelay(50);
		outb(0xfe,0x64);         /* pull reset low */
	} else if(voyager_level == 4) {
		__u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT)<<8;
		__u8 basebd = inb(VOYAGER_MC_SETUP);
		
		outb(basebd | 0x08, VOYAGER_MC_SETUP);
		outb(0x02, catbase + 0x21);
	}
	for(;;) {
		asm("cli");
		asm("hlt");
	}
}

EXPORT_SYMBOL(machine_restart);

void
mca_nmi_hook(void)
{
	__u8 dumpval __attribute__((unused)) = inb(0xf823);
	__u8 swnmi __attribute__((unused)) = inb(0xf813);

	/* FIXME: assume dump switch pressed */
	/* check to see if the dump switch was pressed */
	VDEBUG(("VOYAGER: dumpval = 0x%x, swnmi = 0x%x\n", dumpval, swnmi));
	/* clear swnmi */
	outb(0xff, 0xf813);
	/* tell SUS to ignore dump */
	if(voyager_level == 5 && voyager_SUS != NULL) {
		if(voyager_SUS->SUS_mbox == VOYAGER_DUMP_BUTTON_NMI) {
			voyager_SUS->kernel_mbox = VOYAGER_NO_COMMAND;
			voyager_SUS->kernel_flags |= VOYAGER_OS_IN_PROGRESS;
			udelay(1000);
			voyager_SUS->kernel_mbox = VOYAGER_IGNORE_DUMP;
			voyager_SUS->kernel_flags &= ~VOYAGER_OS_IN_PROGRESS;
		}
	}
	printk(KERN_ERR "VOYAGER: Dump switch pressed, printing CPU%d tracebacks\n", smp_processor_id());
	show_stack(NULL, NULL);
	show_state();
}



void
machine_halt(void)
{
	/* treat a halt like a power off */
	machine_power_off();
}

EXPORT_SYMBOL(machine_halt);

void machine_power_off(void)
{
	if (pm_power_off)
		pm_power_off();
}

EXPORT_SYMBOL(machine_power_off);
