/*
 * bioscalls.c - the lowlevel layer of the PnPBIOS driver
 *
 */

#include <linux/types.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/linkage.h>
#include <linux/kernel.h>
#include <linux/pnpbios.h>
#include <linux/device.h>
#include <linux/pnp.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/slab.h>
#include <linux/kmod.h>
#include <linux/completion.h>
#include <linux/spinlock.h>

#include <asm/page.h>
#include <asm/desc.h>
#include <asm/system.h>
#include <asm/byteorder.h>

#include "pnpbios.h"

static struct {
	u16	offset;
	u16	segment;
} pnp_bios_callpoint;


/* The PnP BIOS entries in the GDT */
#define PNP_GDT    (GDT_ENTRY_PNPBIOS_BASE * 8)

#define PNP_CS32   (PNP_GDT+0x00)	/* segment for calling fn */
#define PNP_CS16   (PNP_GDT+0x08)	/* code segment for BIOS */
#define PNP_DS     (PNP_GDT+0x10)	/* data segment for BIOS */
#define PNP_TS1    (PNP_GDT+0x18)	/* transfer data segment */
#define PNP_TS2    (PNP_GDT+0x20)	/* another data segment */

/*
 * These are some opcodes for a "static asmlinkage"
 * As this code is *not* executed inside the linux kernel segment, but in a
 * alias at offset 0, we need a far return that can not be compiled by
 * default (please, prove me wrong! this is *really* ugly!)
 * This is the only way to get the bios to return into the kernel code,
 * because the bios code runs in 16 bit protected mode and therefore can only
 * return to the caller if the call is within the first 64kB, and the linux
 * kernel begins at offset 3GB...
 */

asmlinkage void pnp_bios_callfunc(void);

__asm__(
	".text			\n"
	__ALIGN_STR "\n"
	"pnp_bios_callfunc:\n"
	"	pushl %edx	\n"
	"	pushl %ecx	\n"
	"	pushl %ebx	\n"
	"	pushl %eax	\n"
	"	lcallw *pnp_bios_callpoint\n"
	"	addl $16, %esp	\n"
	"	lret		\n"
	".previous		\n"
);

#define Q_SET_SEL(cpu, selname, address, size) \
do { \
set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], __va((u32)(address))); \
set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \
} while(0)

#define Q2_SET_SEL(cpu, selname, address, size) \
do { \
set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], (u32)(address)); \
set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \
} while(0)

static struct desc_struct bad_bios_desc = { 0, 0x00409200 };

/*
 * At some point we want to use this stack frame pointer to unwind
 * after PnP BIOS oopses.
 */

u32 pnp_bios_fault_esp;
u32 pnp_bios_fault_eip;
u32 pnp_bios_is_utter_crap = 0;

static spinlock_t pnp_bios_lock;


/*
 * Support Functions
 */

static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
				u16 arg4, u16 arg5, u16 arg6, u16 arg7,
				void *ts1_base, u32 ts1_size,
				void *ts2_base, u32 ts2_size)
{
	unsigned long flags;
	u16 status;
	struct desc_struct save_desc_40;
	int cpu;

	/*
	 * PnP BIOSes are generally not terribly re-entrant.
	 * Also, don't rely on them to save everything correctly.
	 */
	if(pnp_bios_is_utter_crap)
		return PNP_FUNCTION_NOT_SUPPORTED;

	cpu = get_cpu();
	save_desc_40 = per_cpu(cpu_gdt_table,cpu)[0x40 / 8];
	per_cpu(cpu_gdt_table,cpu)[0x40 / 8] = bad_bios_desc;

	/* On some boxes IRQ's during PnP BIOS calls are deadly.  */
	spin_lock_irqsave(&pnp_bios_lock, flags);

	/* The lock prevents us bouncing CPU here */
	if (ts1_size)
		Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size);
	if (ts2_size)
		Q2_SET_SEL(smp_processor_id(), PNP_TS2, ts2_base, ts2_size);

	__asm__ __volatile__(
	        "pushl %%ebp\n\t"
		"pushl %%edi\n\t"
		"pushl %%esi\n\t"
		"pushl %%ds\n\t"
		"pushl %%es\n\t"
		"pushl %%fs\n\t"
		"pushl %%gs\n\t"
		"pushfl\n\t"
		"movl %%esp, pnp_bios_fault_esp\n\t"
		"movl $1f, pnp_bios_fault_eip\n\t"
		"lcall %5,%6\n\t"
		"1:popfl\n\t"
		"popl %%gs\n\t"
		"popl %%fs\n\t"
		"popl %%es\n\t"
		"popl %%ds\n\t"
	        "popl %%esi\n\t"
		"popl %%edi\n\t"
		"popl %%ebp\n\t"
		: "=a" (status)
		: "0" ((func) | (((u32)arg1) << 16)),
		  "b" ((arg2) | (((u32)arg3) << 16)),
		  "c" ((arg4) | (((u32)arg5) << 16)),
		  "d" ((arg6) | (((u32)arg7) << 16)),
		  "i" (PNP_CS32),
		  "i" (0)
		: "memory"
	);
	spin_unlock_irqrestore(&pnp_bios_lock, flags);

	per_cpu(cpu_gdt_table,cpu)[0x40 / 8] = save_desc_40;
	put_cpu();

	/* If we get here and this is set then the PnP BIOS faulted on us. */
	if(pnp_bios_is_utter_crap)
	{
		printk(KERN_ERR "PnPBIOS: Warning! Your PnP BIOS caused a fatal error. Attempting to continue\n");
		printk(KERN_ERR "PnPBIOS: You may need to reboot with the \"pnpbios=off\" option to operate stably\n");
		printk(KERN_ERR "PnPBIOS: Check with your vendor for an updated BIOS\n");
	}

	return status;
}

void pnpbios_print_status(const char * module, u16 status)
{
	switch(status) {
	case PNP_SUCCESS:
		printk(KERN_ERR "PnPBIOS: %s: function successful\n", module);
		break;
	case PNP_NOT_SET_STATICALLY:
		printk(KERN_ERR "PnPBIOS: %s: unable to set static resources\n", module);
		break;
	case PNP_UNKNOWN_FUNCTION:
		printk(KERN_ERR "PnPBIOS: %s: invalid function number passed\n", module);
		break;
	case PNP_FUNCTION_NOT_SUPPORTED:
		printk(KERN_ERR "PnPBIOS: %s: function not supported on this system\n", module);
		break;
	case PNP_INVALID_HANDLE:
		printk(KERN_ERR "PnPBIOS: %s: invalid handle\n", module);
		break;
	case PNP_BAD_PARAMETER:
		printk(KERN_ERR "PnPBIOS: %s: invalid parameters were passed\n", module);
		break;
	case PNP_SET_FAILED:
		printk(KERN_ERR "PnPBIOS: %s: unable to set resources\n", module);
		break;
	case PNP_EVENTS_NOT_PENDING:
		printk(KERN_ERR "PnPBIOS: %s: no events are pending\n", module);
		break;
	case PNP_SYSTEM_NOT_DOCKED:
		printk(KERN_ERR "PnPBIOS: %s: the system is not docked\n", module);
		break;
	case PNP_NO_ISA_PNP_CARDS:
		printk(KERN_ERR "PnPBIOS: %s: no isapnp cards are installed on this system\n", module);
		break;
	case PNP_UNABLE_TO_DETERMINE_DOCK_CAPABILITIES:
		printk(KERN_ERR "PnPBIOS: %s: cannot determine the capabilities of the docking station\n", module);
		break;
	case PNP_CONFIG_CHANGE_FAILED_NO_BATTERY:
		printk(KERN_ERR "PnPBIOS: %s: unable to undock, the system does not have a battery\n", module);
		break;
	case PNP_CONFIG_CHANGE_FAILED_RESOURCE_CONFLICT:
		printk(KERN_ERR "PnPBIOS: %s: could not dock due to resource conflicts\n", module);
		break;
	case PNP_BUFFER_TOO_SMALL:
		printk(KERN_ERR "PnPBIOS: %s: the buffer passed is too small\n", module);
		break;
	case PNP_USE_ESCD_SUPPORT:
		printk(KERN_ERR "PnPBIOS: %s: use ESCD instead\n", module);
		break;
	case PNP_MESSAGE_NOT_SUPPORTED:
		printk(KERN_ERR "PnPBIOS: %s: the message is unsupported\n", module);
		break;
	case PNP_HARDWARE_ERROR:
		printk(KERN_ERR "PnPBIOS: %s: a hardware failure has occured\n", module);
		break;
	default:
		printk(KERN_ERR "PnPBIOS: %s: unexpected status 0x%x\n", module, status);
		break;
	}
}


/*
 * PnP BIOS Low Level Calls
 */

#define PNP_GET_NUM_SYS_DEV_NODES		0x00
#define PNP_GET_SYS_DEV_NODE			0x01
#define PNP_SET_SYS_DEV_NODE			0x02
#define PNP_GET_EVENT				0x03
#define PNP_SEND_MESSAGE			0x04
#define PNP_GET_DOCKING_STATION_INFORMATION	0x05
#define PNP_SET_STATIC_ALLOCED_RES_INFO		0x09
#define PNP_GET_STATIC_ALLOCED_RES_INFO		0x0a
#define PNP_GET_APM_ID_TABLE			0x0b
#define PNP_GET_PNP_ISA_CONFIG_STRUC		0x40
#define PNP_GET_ESCD_INFO			0x41
#define PNP_READ_ESCD				0x42
#define PNP_WRITE_ESCD				0x43

/*
 * Call PnP BIOS with function 0x00, "get number of system device nodes"
 */
static int __pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
{
	u16 status;
	if (!pnp_bios_present())
		return PNP_FUNCTION_NOT_SUPPORTED;
	status = call_pnp_bios(PNP_GET_NUM_SYS_DEV_NODES, 0, PNP_TS1, 2, PNP_TS1, PNP_DS, 0, 0,
			       data, sizeof(struct pnp_dev_node_info), NULL, 0);
	data->no_nodes &= 0xff;
	return status;
}

int pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
{
	int status = __pnp_bios_dev_node_info( data );
	if ( status )
		pnpbios_print_status( "dev_node_info", status );
	return status;
}

/*
 * Note that some PnP BIOSes (e.g., on Sony Vaio laptops) die a horrible
 * death if they are asked to access the "current" configuration.
 * Therefore, if it's a matter of indifference, it's better to call
 * get_dev_node() and set_dev_node() with boot=1 rather than with boot=0.
 */

/* 
 * Call PnP BIOS with function 0x01, "get system device node"
 * Input: *nodenum = desired node,
 *        boot = whether to get nonvolatile boot (!=0)
 *               or volatile current (0) config
 * Output: *nodenum=next node or 0xff if no more nodes
 */
static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
{
	u16 status;
	if (!pnp_bios_present())
		return PNP_FUNCTION_NOT_SUPPORTED;
	if ( !boot && pnpbios_dont_use_current_config )
		return PNP_FUNCTION_NOT_SUPPORTED;
	status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0,
			       nodenum, sizeof(char), data, 65536);
	return status;
}

int pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
{
	int status;
	status =  __pnp_bios_get_dev_node( nodenum, boot, data );
	if ( status )
		pnpbios_print_status( "get_dev_node", status );
	return status;
}


/*
 * Call PnP BIOS with function 0x02, "set system device node"
 * Input: *nodenum = desired node, 
 *        boot = whether to set nonvolatile boot (!=0)
 *               or volatile current (0) config
 */
static int __pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data)
{
	u16 status;
	if (!pnp_bios_present())
		return PNP_FUNCTION_NOT_SUPPORTED;
	if ( !boot && pnpbios_dont_use_current_config )
		return PNP_FUNCTION_NOT_SUPPORTED;
	status = call_pnp_bios(PNP_SET_SYS_DEV_NODE, nodenum, 0, PNP_TS1, boot ? 2 : 1, PNP_DS, 0, 0,
			       data, 65536, NULL, 0);
	return status;
}

int pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data)
{
	int status;
	status =  __pnp_bios_set_dev_node( nodenum, boot, data );
	if ( status ) {
		pnpbios_print_status( "set_dev_node", status );
		return status;
	}
	if ( !boot ) { /* Update devlist */
		status =  pnp_bios_get_dev_node( &nodenum, boot, data );
		if ( status )
			return status;
	}
	return status;
}

#if needed
/*
 * Call PnP BIOS with function 0x03, "get event"
 */
static int pnp_bios_get_event(u16 *event)
{
	u16 status;
	if (!pnp_bios_present())
		return PNP_FUNCTION_NOT_SUPPORTED;
	status = call_pnp_bios(PNP_GET_EVENT, 0, PNP_TS1, PNP_DS, 0, 0 ,0 ,0,
			       event, sizeof(u16), NULL, 0);
	return status;
}
#endif

#if needed
/*
 * Call PnP BIOS with function 0x04, "send message"
 */
static int pnp_bios_send_message(u16 message)
{
	u16 status;
	if (!pnp_bios_present())
		return PNP_FUNCTION_NOT_SUPPORTED;
	status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, 0, 0, 0, 0, 0, 0);
	return status;
}
#endif

/*
 * Call PnP BIOS with function 0x05, "get docking station information"
 */
int pnp_bios_dock_station_info(struct pnp_docking_station_info *data)
{
	u16 status;
	if (!pnp_bios_present())
		return PNP_FUNCTION_NOT_SUPPORTED;
	status = call_pnp_bios(PNP_GET_DOCKING_STATION_INFORMATION, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
			       data, sizeof(struct pnp_docking_station_info), NULL, 0);
	return status;
}

#if needed
/*
 * Call PnP BIOS with function 0x09, "set statically allocated resource
 * information"
 */
static int pnp_bios_set_stat_res(char *info)
{
	u16 status;
	if (!pnp_bios_present())
		return PNP_FUNCTION_NOT_SUPPORTED;
	status = call_pnp_bios(PNP_SET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
			       info, *((u16 *) info), 0, 0);
	return status;
}
#endif

/*
 * Call PnP BIOS with function 0x0a, "get statically allocated resource
 * information"
 */
static int __pnp_bios_get_stat_res(char *info)
{
	u16 status;
	if (!pnp_bios_present())
		return PNP_FUNCTION_NOT_SUPPORTED;
	status = call_pnp_bios(PNP_GET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
			       info, 65536, NULL, 0);
	return status;
}

int pnp_bios_get_stat_res(char *info)
{
	int status;
	status = __pnp_bios_get_stat_res( info );
	if ( status )
		pnpbios_print_status( "get_stat_res", status );
	return status;
}

#if needed
/*
 * Call PnP BIOS with function 0x0b, "get APM id table"
 */
static int pnp_bios_apm_id_table(char *table, u16 *size)
{
	u16 status;
	if (!pnp_bios_present())
		return PNP_FUNCTION_NOT_SUPPORTED;
	status = call_pnp_bios(PNP_GET_APM_ID_TABLE, 0, PNP_TS2, 0, PNP_TS1, PNP_DS, 0, 0,
			       table, *size, size, sizeof(u16));
	return status;
}
#endif

/*
 * Call PnP BIOS with function 0x40, "get isa pnp configuration structure"
 */
static int __pnp_bios_isapnp_config(struct pnp_isa_config_struc *data)
{
	u16 status;
	if (!pnp_bios_present())
		return PNP_FUNCTION_NOT_SUPPORTED;
	status = call_pnp_bios(PNP_GET_PNP_ISA_CONFIG_STRUC, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
			       data, sizeof(struct pnp_isa_config_struc), NULL, 0);
	return status;
}

int pnp_bios_isapnp_config(struct pnp_isa_config_struc *data)
{
	int status;
	status = __pnp_bios_isapnp_config( data );
	if ( status )
		pnpbios_print_status( "isapnp_config", status );
	return status;
}

/*
 * Call PnP BIOS with function 0x41, "get ESCD info"
 */
static int __pnp_bios_escd_info(struct escd_info_struc *data)
{
	u16 status;
	if (!pnp_bios_present())
		return ESCD_FUNCTION_NOT_SUPPORTED;
	status = call_pnp_bios(PNP_GET_ESCD_INFO, 0, PNP_TS1, 2, PNP_TS1, 4, PNP_TS1, PNP_DS,
			       data, sizeof(struct escd_info_struc), NULL, 0);
	return status;
}

int pnp_bios_escd_info(struct escd_info_struc *data)
{
	int status;
	status = __pnp_bios_escd_info( data );
	if ( status )
		pnpbios_print_status( "escd_info", status );
	return status;
}

/*
 * Call PnP BIOS function 0x42, "read ESCD"
 * nvram_base is determined by calling escd_info
 */
static int __pnp_bios_read_escd(char *data, u32 nvram_base)
{
	u16 status;
	if (!pnp_bios_present())
		return ESCD_FUNCTION_NOT_SUPPORTED;
	status = call_pnp_bios(PNP_READ_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0,
			       data, 65536, __va(nvram_base), 65536);
	return status;
}

int pnp_bios_read_escd(char *data, u32 nvram_base)
{
	int status;
	status = __pnp_bios_read_escd( data, nvram_base );
	if ( status )
		pnpbios_print_status( "read_escd", status );
	return status;
}

#if needed
/*
 * Call PnP BIOS function 0x43, "write ESCD"
 */
static int pnp_bios_write_escd(char *data, u32 nvram_base)
{
	u16 status;
	if (!pnp_bios_present())
		return ESCD_FUNCTION_NOT_SUPPORTED;
	status = call_pnp_bios(PNP_WRITE_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0,
			       data, 65536, __va(nvram_base), 65536);
	return status;
}
#endif


/*
 * Initialization
 */

void pnpbios_calls_init(union pnp_bios_install_struct *header)
{
	int i;
	spin_lock_init(&pnp_bios_lock);
	pnp_bios_callpoint.offset = header->fields.pm16offset;
	pnp_bios_callpoint.segment = PNP_CS16;

	set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
	_set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
	for(i=0; i < NR_CPUS; i++)
	{
		Q2_SET_SEL(i, PNP_CS32, &pnp_bios_callfunc, 64 * 1024);
		Q_SET_SEL(i, PNP_CS16, header->fields.pm16cseg, 64 * 1024);
		Q_SET_SEL(i, PNP_DS, header->fields.pm16dseg, 64 * 1024);
	}
}
