/*
 * arch/parisc/kernel/firmware.c  - safe PDC access routines
 *
 *	PDC == Processor Dependent Code
 *
 * See http://www.parisc-linux.org/documentation/index.html
 * for documentation describing the entry points and calling
 * conventions defined below.
 *
 * Copyright 1999 SuSE GmbH Nuernberg (Philipp Rumpf, prumpf@tux.org)
 * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
 * Copyright 2003 Grant Grundler <grundler parisc-linux org>
 * Copyright 2003,2004 Ryan Bradetich <rbrad@parisc-linux.org>
 * Copyright 2004 Thibaut VARENE <varenet@parisc-linux.org>
 *
 *    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.
 *
 */

/*	I think it would be in everyone's best interest to follow this
 *	guidelines when writing PDC wrappers:
 *
 *	 - the name of the pdc wrapper should match one of the macros
 *	   used for the first two arguments
 *	 - don't use caps for random parts of the name
 *	 - use the static PDC result buffers and "copyout" to structs
 *	   supplied by the caller to encapsulate alignment restrictions
 *	 - hold pdc_lock while in PDC or using static result buffers
 *	 - use __pa() to convert virtual (kernel) pointers to physical
 *	   ones.
 *	 - the name of the struct used for pdc return values should equal
 *	   one of the macros used for the first two arguments to the
 *	   corresponding PDC call
 *	 - keep the order of arguments
 *	 - don't be smart (setting trailing NUL bytes for strings, return
 *	   something useful even if the call failed) unless you are sure
 *	   it's not going to affect functionality or performance
 *
 *	Example:
 *	int pdc_cache_info(struct pdc_cache_info *cache_info )
 *	{
 *		int retval;
 *
 *		spin_lock_irq(&pdc_lock);
 *		retval = mem_pdc_call(PDC_CACHE,PDC_CACHE_INFO,__pa(cache_info),0);
 *		convert_to_wide(pdc_result);
 *		memcpy(cache_info, pdc_result, sizeof(*cache_info));
 *		spin_unlock_irq(&pdc_lock);
 *
 *		return retval;
 *	}
 *					prumpf	991016	
 */

#include <stdarg.h>

#include <linux/delay.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/spinlock.h>

#include <asm/page.h>
#include <asm/pdc.h>
#include <asm/pdcpat.h>
#include <asm/system.h>
#include <asm/processor.h>	/* for boot_cpu_data */

static DEFINE_SPINLOCK(pdc_lock);
static unsigned long pdc_result[32] __attribute__ ((aligned (8)));
static unsigned long pdc_result2[32] __attribute__ ((aligned (8)));

#ifdef __LP64__
#define WIDE_FIRMWARE 0x1
#define NARROW_FIRMWARE 0x2

/* Firmware needs to be initially set to narrow to determine the 
 * actual firmware width. */
int parisc_narrow_firmware = 1;
#endif

/* on all currently-supported platforms, IODC I/O calls are always
 * 32-bit calls, and MEM_PDC calls are always the same width as the OS.
 * This means Cxxx boxes can't run wide kernels right now. -PB
 *
 * CONFIG_PDC_NARROW has been added to allow 64-bit kernels to run on
 * systems with 32-bit MEM_PDC calls. This will allow wide kernels to
 * run on Cxxx boxes now. -RB
 *
 * Note that some PAT boxes may have 64-bit IODC I/O...
 */

#ifdef __LP64__
long real64_call(unsigned long function, ...);
#endif
long real32_call(unsigned long function, ...);

#ifdef __LP64__
#   define MEM_PDC (unsigned long)(PAGE0->mem_pdc_hi) << 32 | PAGE0->mem_pdc
#   define mem_pdc_call(args...) unlikely(parisc_narrow_firmware) ? real32_call(MEM_PDC, args) : real64_call(MEM_PDC, args)
#else
#   define MEM_PDC (unsigned long)PAGE0->mem_pdc
#   define mem_pdc_call(args...) real32_call(MEM_PDC, args)
#endif


/**
 * f_extend - Convert PDC addresses to kernel addresses.
 * @address: Address returned from PDC.
 *
 * This function is used to convert PDC addresses into kernel addresses
 * when the PDC address size and kernel address size are different.
 */
static unsigned long f_extend(unsigned long address)
{
#ifdef __LP64__
	if(unlikely(parisc_narrow_firmware)) {
		if((address & 0xff000000) == 0xf0000000)
			return 0xf0f0f0f000000000 | (u32)address;

		if((address & 0xf0000000) == 0xf0000000)
			return 0xffffffff00000000 | (u32)address;
	}
#endif
	return address;
}

/**
 * convert_to_wide - Convert the return buffer addresses into kernel addresses.
 * @address: The return buffer from PDC.
 *
 * This function is used to convert the return buffer addresses retrieved from PDC
 * into kernel addresses when the PDC address size and kernel address size are
 * different.
 */
static void convert_to_wide(unsigned long *addr)
{
#ifdef __LP64__
	int i;
	unsigned int *p = (unsigned int *)addr;

	if(unlikely(parisc_narrow_firmware)) {
		for(i = 31; i >= 0; --i)
			addr[i] = p[i];
	}
#endif
}

/**
 * set_firmware_width - Determine if the firmware is wide or narrow.
 * 
 * This function must be called before any pdc_* function that uses the convert_to_wide
 * function.
 */
void __init set_firmware_width(void)
{
#ifdef __LP64__
	int retval;

        spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
	convert_to_wide(pdc_result);
	if(pdc_result[0] != NARROW_FIRMWARE)
		parisc_narrow_firmware = 0;
        spin_unlock_irq(&pdc_lock);
#endif
}

/**
 * pdc_emergency_unlock - Unlock the linux pdc lock
 *
 * This call unlocks the linux pdc lock in case we need some PDC functions
 * (like pdc_add_valid) during kernel stack dump.
 */
void pdc_emergency_unlock(void)
{
 	/* Spinlock DEBUG code freaks out if we unconditionally unlock */
        if (spin_is_locked(&pdc_lock))
		spin_unlock(&pdc_lock);
}


/**
 * pdc_add_valid - Verify address can be accessed without causing a HPMC.
 * @address: Address to be verified.
 *
 * This PDC call attempts to read from the specified address and verifies
 * if the address is valid.
 * 
 * The return value is PDC_OK (0) in case accessing this address is valid.
 */
int pdc_add_valid(unsigned long address)
{
        int retval;

        spin_lock_irq(&pdc_lock);
        retval = mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, address);
        spin_unlock_irq(&pdc_lock);

        return retval;
}
EXPORT_SYMBOL(pdc_add_valid);

/**
 * pdc_chassis_info - Return chassis information.
 * @result: The return buffer.
 * @chassis_info: The memory buffer address.
 * @len: The size of the memory buffer address.
 *
 * An HVERSION dependent call for returning the chassis information.
 */
int __init pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len)
{
        int retval;

        spin_lock_irq(&pdc_lock);
        memcpy(&pdc_result, chassis_info, sizeof(*chassis_info));
        memcpy(&pdc_result2, led_info, len);
        retval = mem_pdc_call(PDC_CHASSIS, PDC_RETURN_CHASSIS_INFO,
                              __pa(pdc_result), __pa(pdc_result2), len);
        memcpy(chassis_info, pdc_result, sizeof(*chassis_info));
        memcpy(led_info, pdc_result2, len);
        spin_unlock_irq(&pdc_lock);

        return retval;
}

/**
 * pdc_pat_chassis_send_log - Sends a PDC PAT CHASSIS log message.
 * @retval: -1 on error, 0 on success. Other value are PDC errors
 * 
 * Must be correctly formatted or expect system crash
 */
#ifdef __LP64__
int pdc_pat_chassis_send_log(unsigned long state, unsigned long data)
{
	int retval = 0;
        
	if (!is_pdc_pat())
		return -1;

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_PAT_CHASSIS_LOG, PDC_PAT_CHASSIS_WRITE_LOG, __pa(&state), __pa(&data));
	spin_unlock_irq(&pdc_lock);

	return retval;
}
#endif

/**
 * pdc_chassis_disp - Updates display
 * @retval: -1 on error, 0 on success
 *
 * Works on old PDC only (E class, others?)
 */
int pdc_chassis_disp(unsigned long disp)
{
	int retval = 0;

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_DISP, disp);
	spin_unlock_irq(&pdc_lock);

	return retval;
}

/**
 * pdc_coproc_cfg - To identify coprocessors attached to the processor.
 * @pdc_coproc_info: Return buffer address.
 *
 * This PDC call returns the presence and status of all the coprocessors
 * attached to the processor.
 */
int __init pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info)
{
        int retval;

        spin_lock_irq(&pdc_lock);
        retval = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result));
        convert_to_wide(pdc_result);
        pdc_coproc_info->ccr_functional = pdc_result[0];
        pdc_coproc_info->ccr_present = pdc_result[1];
        pdc_coproc_info->revision = pdc_result[17];
        pdc_coproc_info->model = pdc_result[18];
        spin_unlock_irq(&pdc_lock);

        return retval;
}

/**
 * pdc_iodc_read - Read data from the modules IODC.
 * @actcnt: The actual number of bytes.
 * @hpa: The HPA of the module for the iodc read.
 * @index: The iodc entry point.
 * @iodc_data: A buffer memory for the iodc options.
 * @iodc_data_size: Size of the memory buffer.
 *
 * This PDC call reads from the IODC of the module specified by the hpa
 * argument.
 */
int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
		  void *iodc_data, unsigned int iodc_data_size)
{
	int retval;

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_IODC, PDC_IODC_READ, __pa(pdc_result), hpa, 
			      index, __pa(pdc_result2), iodc_data_size);
	convert_to_wide(pdc_result);
	*actcnt = pdc_result[0];
	memcpy(iodc_data, pdc_result2, iodc_data_size);
	spin_unlock_irq(&pdc_lock);

	return retval;
}
EXPORT_SYMBOL(pdc_iodc_read);

/**
 * pdc_system_map_find_mods - Locate unarchitected modules.
 * @pdc_mod_info: Return buffer address.
 * @mod_path: pointer to dev path structure.
 * @mod_index: fixed address module index.
 *
 * To locate and identify modules which reside at fixed I/O addresses, which
 * do not self-identify via architected bus walks.
 */
int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info,
			     struct pdc_module_path *mod_path, long mod_index)
{
	int retval;

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE, __pa(pdc_result), 
			      __pa(pdc_result2), mod_index);
	convert_to_wide(pdc_result);
	memcpy(pdc_mod_info, pdc_result, sizeof(*pdc_mod_info));
	memcpy(mod_path, pdc_result2, sizeof(*mod_path));
	spin_unlock_irq(&pdc_lock);

	pdc_mod_info->mod_addr = f_extend(pdc_mod_info->mod_addr);
	return retval;
}

/**
 * pdc_system_map_find_addrs - Retrieve additional address ranges.
 * @pdc_addr_info: Return buffer address.
 * @mod_index: Fixed address module index.
 * @addr_index: Address range index.
 * 
 * Retrieve additional information about subsequent address ranges for modules
 * with multiple address ranges.  
 */
int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info, 
			      long mod_index, long addr_index)
{
	int retval;

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_ADDRESS, __pa(pdc_result),
			      mod_index, addr_index);
	convert_to_wide(pdc_result);
	memcpy(pdc_addr_info, pdc_result, sizeof(*pdc_addr_info));
	spin_unlock_irq(&pdc_lock);

	pdc_addr_info->mod_addr = f_extend(pdc_addr_info->mod_addr);
	return retval;
}

/**
 * pdc_model_info - Return model information about the processor.
 * @model: The return buffer.
 *
 * Returns the version numbers, identifiers, and capabilities from the processor module.
 */
int pdc_model_info(struct pdc_model *model) 
{
	int retval;

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_INFO, __pa(pdc_result), 0);
	convert_to_wide(pdc_result);
	memcpy(model, pdc_result, sizeof(*model));
	spin_unlock_irq(&pdc_lock);

	return retval;
}

/**
 * pdc_model_sysmodel - Get the system model name.
 * @name: A char array of at least 81 characters.
 *
 * Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L)
 */
int pdc_model_sysmodel(char *name)
{
        int retval;

        spin_lock_irq(&pdc_lock);
        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_SYSMODEL, __pa(pdc_result),
                              OS_ID_HPUX, __pa(name));
        convert_to_wide(pdc_result);

        if (retval == PDC_OK) {
                name[pdc_result[0]] = '\0'; /* add trailing '\0' */
        } else {
                name[0] = 0;
        }
        spin_unlock_irq(&pdc_lock);

        return retval;
}

/**
 * pdc_model_versions - Identify the version number of each processor.
 * @cpu_id: The return buffer.
 * @id: The id of the processor to check.
 *
 * Returns the version number for each processor component.
 *
 * This comment was here before, but I do not know what it means :( -RB
 * id: 0 = cpu revision, 1 = boot-rom-version
 */
int pdc_model_versions(unsigned long *versions, int id)
{
        int retval;

        spin_lock_irq(&pdc_lock);
        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_VERSIONS, __pa(pdc_result), id);
        convert_to_wide(pdc_result);
        *versions = pdc_result[0];
        spin_unlock_irq(&pdc_lock);

        return retval;
}

/**
 * pdc_model_cpuid - Returns the CPU_ID.
 * @cpu_id: The return buffer.
 *
 * Returns the CPU_ID value which uniquely identifies the cpu portion of
 * the processor module.
 */
int pdc_model_cpuid(unsigned long *cpu_id)
{
        int retval;

        spin_lock_irq(&pdc_lock);
        pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CPU_ID, __pa(pdc_result), 0);
        convert_to_wide(pdc_result);
        *cpu_id = pdc_result[0];
        spin_unlock_irq(&pdc_lock);

        return retval;
}

/**
 * pdc_model_capabilities - Returns the platform capabilities.
 * @capabilities: The return buffer.
 *
 * Returns information about platform support for 32- and/or 64-bit
 * OSes, IO-PDIR coherency, and virtual aliasing.
 */
int pdc_model_capabilities(unsigned long *capabilities)
{
        int retval;

        spin_lock_irq(&pdc_lock);
        pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
        convert_to_wide(pdc_result);
        *capabilities = pdc_result[0];
        spin_unlock_irq(&pdc_lock);

        return retval;
}

/**
 * pdc_cache_info - Return cache and TLB information.
 * @cache_info: The return buffer.
 *
 * Returns information about the processor's cache and TLB.
 */
int pdc_cache_info(struct pdc_cache_info *cache_info)
{
        int retval;

        spin_lock_irq(&pdc_lock);
        retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_INFO, __pa(pdc_result), 0);
        convert_to_wide(pdc_result);
        memcpy(cache_info, pdc_result, sizeof(*cache_info));
        spin_unlock_irq(&pdc_lock);

        return retval;
}

#ifndef CONFIG_PA20
/**
 * pdc_btlb_info - Return block TLB information.
 * @btlb: The return buffer.
 *
 * Returns information about the hardware Block TLB.
 */
int pdc_btlb_info(struct pdc_btlb_info *btlb) 
{
        int retval;

        spin_lock_irq(&pdc_lock);
        retval = mem_pdc_call(PDC_BLOCK_TLB, PDC_BTLB_INFO, __pa(pdc_result), 0);
        memcpy(btlb, pdc_result, sizeof(*btlb));
        spin_unlock_irq(&pdc_lock);

        if(retval < 0) {
                btlb->max_size = 0;
        }
        return retval;
}

/**
 * pdc_mem_map_hpa - Find fixed module information.  
 * @address: The return buffer
 * @mod_path: pointer to dev path structure.
 *
 * This call was developed for S700 workstations to allow the kernel to find
 * the I/O devices (Core I/O). In the future (Kittyhawk and beyond) this
 * call will be replaced (on workstations) by the architected PDC_SYSTEM_MAP
 * call.
 *
 * This call is supported by all existing S700 workstations (up to  Gecko).
 */
int pdc_mem_map_hpa(struct pdc_memory_map *address,
		struct pdc_module_path *mod_path)
{
        int retval;

        spin_lock_irq(&pdc_lock);
        memcpy(pdc_result2, mod_path, sizeof(*mod_path));
        retval = mem_pdc_call(PDC_MEM_MAP, PDC_MEM_MAP_HPA, __pa(pdc_result),
				__pa(pdc_result2));
        memcpy(address, pdc_result, sizeof(*address));
        spin_unlock_irq(&pdc_lock);

        return retval;
}
#endif	/* !CONFIG_PA20 */

/**
 * pdc_lan_station_id - Get the LAN address.
 * @lan_addr: The return buffer.
 * @hpa: The network device HPA.
 *
 * Get the LAN station address when it is not directly available from the LAN hardware.
 */
int pdc_lan_station_id(char *lan_addr, unsigned long hpa)
{
	int retval;

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_LAN_STATION_ID, PDC_LAN_STATION_ID_READ,
			__pa(pdc_result), hpa);
	if (retval < 0) {
		/* FIXME: else read MAC from NVRAM */
		memset(lan_addr, 0, PDC_LAN_STATION_ID_SIZE);
	} else {
		memcpy(lan_addr, pdc_result, PDC_LAN_STATION_ID_SIZE);
	}
	spin_unlock_irq(&pdc_lock);

	return retval;
}
EXPORT_SYMBOL(pdc_lan_station_id);

/**
 * pdc_stable_read - Read data from Stable Storage.
 * @staddr: Stable Storage address to access.
 * @memaddr: The memory address where Stable Storage data shall be copied.
 * @count: number of bytes to transfert. count is multiple of 4.
 *
 * This PDC call reads from the Stable Storage address supplied in staddr
 * and copies count bytes to the memory address memaddr.
 * The call will fail if staddr+count > PDC_STABLE size.
 */
int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count)
{
       int retval;

       spin_lock_irq(&pdc_lock);
       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_READ, staddr,
               __pa(pdc_result), count);
       convert_to_wide(pdc_result);
       memcpy(memaddr, pdc_result, count);
       spin_unlock_irq(&pdc_lock);

       return retval;
}
EXPORT_SYMBOL(pdc_stable_read);

/**
 * pdc_stable_write - Write data to Stable Storage.
 * @staddr: Stable Storage address to access.
 * @memaddr: The memory address where Stable Storage data shall be read from.
 * @count: number of bytes to transfert. count is multiple of 4.
 *
 * This PDC call reads count bytes from the supplied memaddr address,
 * and copies count bytes to the Stable Storage address staddr.
 * The call will fail if staddr+count > PDC_STABLE size.
 */
int pdc_stable_write(unsigned long staddr, void *memaddr, unsigned long count)
{
       int retval;

       spin_lock_irq(&pdc_lock);
       memcpy(pdc_result, memaddr, count);
       convert_to_wide(pdc_result);
       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_WRITE, staddr,
               __pa(pdc_result), count);
       spin_unlock_irq(&pdc_lock);

       return retval;
}
EXPORT_SYMBOL(pdc_stable_write);

/**
 * pdc_stable_get_size - Get Stable Storage size in bytes.
 * @size: pointer where the size will be stored.
 *
 * This PDC call returns the number of bytes in the processor's Stable
 * Storage, which is the number of contiguous bytes implemented in Stable
 * Storage starting from staddr=0. size in an unsigned 64-bit integer
 * which is a multiple of four.
 */
int pdc_stable_get_size(unsigned long *size)
{
       int retval;

       spin_lock_irq(&pdc_lock);
       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_RETURN_SIZE, __pa(pdc_result));
       *size = pdc_result[0];
       spin_unlock_irq(&pdc_lock);

       return retval;
}
EXPORT_SYMBOL(pdc_stable_get_size);

/**
 * pdc_stable_verify_contents - Checks that Stable Storage contents are valid.
 *
 * This PDC call is meant to be used to check the integrity of the current
 * contents of Stable Storage.
 */
int pdc_stable_verify_contents(void)
{
       int retval;

       spin_lock_irq(&pdc_lock);
       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_VERIFY_CONTENTS);
       spin_unlock_irq(&pdc_lock);

       return retval;
}
EXPORT_SYMBOL(pdc_stable_verify_contents);

/**
 * pdc_stable_initialize - Sets Stable Storage contents to zero and initialize
 * the validity indicator.
 *
 * This PDC call will erase all contents of Stable Storage. Use with care!
 */
int pdc_stable_initialize(void)
{
       int retval;

       spin_lock_irq(&pdc_lock);
       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_INITIALIZE);
       spin_unlock_irq(&pdc_lock);

       return retval;
}
EXPORT_SYMBOL(pdc_stable_initialize);

/**
 * pdc_get_initiator - Get the SCSI Interface Card params (SCSI ID, SDTR, SE or LVD)
 * @hwpath: fully bc.mod style path to the device.
 * @initiator: the array to return the result into
 *
 * Get the SCSI operational parameters from PDC.
 * Needed since HPUX never used BIOS or symbios card NVRAM.
 * Most ncr/sym cards won't have an entry and just use whatever
 * capabilities of the card are (eg Ultra, LVD). But there are
 * several cases where it's useful:
 *    o set SCSI id for Multi-initiator clusters,
 *    o cable too long (ie SE scsi 10Mhz won't support 6m length),
 *    o bus width exported is less than what the interface chip supports.
 */
int pdc_get_initiator(struct hardware_path *hwpath, struct pdc_initiator *initiator)
{
	int retval;

	spin_lock_irq(&pdc_lock);

/* BCJ-XXXX series boxes. E.G. "9000/785/C3000" */
#define IS_SPROCKETS() (strlen(boot_cpu_data.pdc.sys_model_name) == 14 && \
	strncmp(boot_cpu_data.pdc.sys_model_name, "9000/785", 8) == 0)

	retval = mem_pdc_call(PDC_INITIATOR, PDC_GET_INITIATOR, 
			      __pa(pdc_result), __pa(hwpath));
	if (retval < PDC_OK)
		goto out;

	if (pdc_result[0] < 16) {
		initiator->host_id = pdc_result[0];
	} else {
		initiator->host_id = -1;
	}

	/*
	 * Sprockets and Piranha return 20 or 40 (MT/s).  Prelude returns
	 * 1, 2, 5 or 10 for 5, 10, 20 or 40 MT/s, respectively
	 */
	switch (pdc_result[1]) {
		case  1: initiator->factor = 50; break;
		case  2: initiator->factor = 25; break;
		case  5: initiator->factor = 12; break;
		case 25: initiator->factor = 10; break;
		case 20: initiator->factor = 12; break;
		case 40: initiator->factor = 10; break;
		default: initiator->factor = -1; break;
	}

	if (IS_SPROCKETS()) {
		initiator->width = pdc_result[4];
		initiator->mode = pdc_result[5];
	} else {
		initiator->width = -1;
		initiator->mode = -1;
	}

 out:
	spin_unlock_irq(&pdc_lock);
	return (retval >= PDC_OK);
}
EXPORT_SYMBOL(pdc_get_initiator);


/**
 * pdc_pci_irt_size - Get the number of entries in the interrupt routing table.
 * @num_entries: The return value.
 * @hpa: The HPA for the device.
 *
 * This PDC function returns the number of entries in the specified cell's
 * interrupt table.
 * Similar to PDC_PAT stuff - but added for Forte/Allegro boxes
 */ 
int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa)
{
	int retval;

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SIZE, 
			      __pa(pdc_result), hpa);
	convert_to_wide(pdc_result);
	*num_entries = pdc_result[0];
	spin_unlock_irq(&pdc_lock);

	return retval;
}

/** 
 * pdc_pci_irt - Get the PCI interrupt routing table.
 * @num_entries: The number of entries in the table.
 * @hpa: The Hard Physical Address of the device.
 * @tbl: 
 *
 * Get the PCI interrupt routing table for the device at the given HPA.
 * Similar to PDC_PAT stuff - but added for Forte/Allegro boxes
 */
int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl)
{
	int retval;

	spin_lock_irq(&pdc_lock);
	pdc_result[0] = num_entries;
	retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL, 
			      __pa(pdc_result), hpa, __pa(tbl));
	spin_unlock_irq(&pdc_lock);

	return retval;
}


#if 0	/* UNTEST CODE - left here in case someone needs it */

/** 
 * pdc_pci_config_read - read PCI config space.
 * @hpa		token from PDC to indicate which PCI device
 * @pci_addr	configuration space address to read from
 *
 * Read PCI Configuration space *before* linux PCI subsystem is running.
 */
unsigned int pdc_pci_config_read(void *hpa, unsigned long cfg_addr)
{
	int retval;
	spin_lock_irq(&pdc_lock);
	pdc_result[0] = 0;
	pdc_result[1] = 0;
	retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_READ_CONFIG, 
			      __pa(pdc_result), hpa, cfg_addr&~3UL, 4UL);
	spin_unlock_irq(&pdc_lock);
	return retval ? ~0 : (unsigned int) pdc_result[0];
}


/** 
 * pdc_pci_config_write - read PCI config space.
 * @hpa		token from PDC to indicate which PCI device
 * @pci_addr	configuration space address to write
 * @val		value we want in the 32-bit register
 *
 * Write PCI Configuration space *before* linux PCI subsystem is running.
 */
void pdc_pci_config_write(void *hpa, unsigned long cfg_addr, unsigned int val)
{
	int retval;
	spin_lock_irq(&pdc_lock);
	pdc_result[0] = 0;
	retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_WRITE_CONFIG, 
			      __pa(pdc_result), hpa,
			      cfg_addr&~3UL, 4UL, (unsigned long) val);
	spin_unlock_irq(&pdc_lock);
	return retval;
}
#endif /* UNTESTED CODE */

/**
 * pdc_tod_read - Read the Time-Of-Day clock.
 * @tod: The return buffer:
 *
 * Read the Time-Of-Day clock
 */
int pdc_tod_read(struct pdc_tod *tod)
{
        int retval;

        spin_lock_irq(&pdc_lock);
        retval = mem_pdc_call(PDC_TOD, PDC_TOD_READ, __pa(pdc_result), 0);
        convert_to_wide(pdc_result);
        memcpy(tod, pdc_result, sizeof(*tod));
        spin_unlock_irq(&pdc_lock);

        return retval;
}
EXPORT_SYMBOL(pdc_tod_read);

/**
 * pdc_tod_set - Set the Time-Of-Day clock.
 * @sec: The number of seconds since epoch.
 * @usec: The number of micro seconds.
 *
 * Set the Time-Of-Day clock.
 */ 
int pdc_tod_set(unsigned long sec, unsigned long usec)
{
        int retval;

        spin_lock_irq(&pdc_lock);
        retval = mem_pdc_call(PDC_TOD, PDC_TOD_WRITE, sec, usec);
        spin_unlock_irq(&pdc_lock);

        return retval;
}
EXPORT_SYMBOL(pdc_tod_set);

#ifdef __LP64__
int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
		struct pdc_memory_table *tbl, unsigned long entries)
{
	int retval;

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_MEM, PDC_MEM_TABLE, __pa(pdc_result), __pa(pdc_result2), entries);
	convert_to_wide(pdc_result);
	memcpy(r_addr, pdc_result, sizeof(*r_addr));
	memcpy(tbl, pdc_result2, entries * sizeof(*tbl));
	spin_unlock_irq(&pdc_lock);

	return retval;
}
#endif /* __LP64__ */

/* FIXME: Is this pdc used?  I could not find type reference to ftc_bitmap
 * so I guessed at unsigned long.  Someone who knows what this does, can fix
 * it later. :)
 */
int pdc_do_firm_test_reset(unsigned long ftc_bitmap)
{
        int retval;

        spin_lock_irq(&pdc_lock);
        retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_FIRM_TEST_RESET,
                              PDC_FIRM_TEST_MAGIC, ftc_bitmap);
        spin_unlock_irq(&pdc_lock);

        return retval;
}

/*
 * pdc_do_reset - Reset the system.
 *
 * Reset the system.
 */
int pdc_do_reset()
{
        int retval;

        spin_lock_irq(&pdc_lock);
        retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_RESET);
        spin_unlock_irq(&pdc_lock);

        return retval;
}

/*
 * pdc_soft_power_info - Enable soft power switch.
 * @power_reg: address of soft power register
 *
 * Return the absolute address of the soft power switch register
 */
int __init pdc_soft_power_info(unsigned long *power_reg)
{
	int retval;

	*power_reg = (unsigned long) (-1);
	
	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_INFO, __pa(pdc_result), 0);
	if (retval == PDC_OK) {
                convert_to_wide(pdc_result);
                *power_reg = f_extend(pdc_result[0]);
	}
	spin_unlock_irq(&pdc_lock);

	return retval;
}

/*
 * pdc_soft_power_button - Control the soft power button behaviour
 * @sw_control: 0 for hardware control, 1 for software control 
 *
 *
 * This PDC function places the soft power button under software or
 * hardware control.
 * Under software control the OS may control to when to allow to shut 
 * down the system. Under hardware control pressing the power button 
 * powers off the system immediately.
 */
int pdc_soft_power_button(int sw_control)
{
	int retval;
	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_ENABLE, __pa(pdc_result), sw_control);
	spin_unlock_irq(&pdc_lock);
	return retval;
}

/*
 * pdc_io_reset - Hack to avoid overlapping range registers of Bridges devices.
 * Primarily a problem on T600 (which parisc-linux doesn't support) but
 * who knows what other platform firmware might do with this OS "hook".
 */
void pdc_io_reset(void)
{
	spin_lock_irq(&pdc_lock);  
	mem_pdc_call(PDC_IO, PDC_IO_RESET, 0);
	spin_unlock_irq(&pdc_lock);
}

/*
 * pdc_io_reset_devices - Hack to Stop USB controller
 *
 * If PDC used the usb controller, the usb controller
 * is still running and will crash the machines during iommu 
 * setup, because of still running DMA. This PDC call
 * stops the USB controller.
 * Normally called after calling pdc_io_reset().
 */
void pdc_io_reset_devices(void)
{
	spin_lock_irq(&pdc_lock);  
	mem_pdc_call(PDC_IO, PDC_IO_RESET_DEVICES, 0);
	spin_unlock_irq(&pdc_lock);
}


/**
 * pdc_iodc_putc - Console character print using IODC.
 * @c: the character to output.
 *
 * Note that only these special chars are architected for console IODC io:
 * BEL, BS, CR, and LF. Others are passed through.
 * Since the HP console requires CR+LF to perform a 'newline', we translate
 * "\n" to "\r\n".
 */
void pdc_iodc_putc(unsigned char c)
{
        /* XXX Should we spinlock posx usage */
        static int posx;        /* for simple TAB-Simulation... */
        static int __attribute__((aligned(8)))   iodc_retbuf[32];
        static char __attribute__((aligned(64))) iodc_dbuf[4096];
        unsigned int n;
	unsigned int flags;

        switch (c) {
        case '\n':
                iodc_dbuf[0] = '\r';
                iodc_dbuf[1] = '\n';
                n = 2;
                posx = 0;
                break;
        case '\t':
                pdc_iodc_putc(' ');
                while (posx & 7)        /* expand TAB */
                        pdc_iodc_putc(' ');
                return;         /* return since IODC can't handle this */
        case '\b':
                posx-=2;                /* BS */
        default:
                iodc_dbuf[0] = c;
                n = 1;
                posx++;
                break;
        }

        spin_lock_irqsave(&pdc_lock, flags);
        real32_call(PAGE0->mem_cons.iodc_io,
                    (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
                    PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
                    __pa(iodc_retbuf), 0, __pa(iodc_dbuf), n, 0);
        spin_unlock_irqrestore(&pdc_lock, flags);
}

/**
 * pdc_iodc_outc - Console character print using IODC (without conversions).
 * @c: the character to output.
 *
 * Write the character directly to the IODC console.
 */
void pdc_iodc_outc(unsigned char c)
{
	unsigned int n, flags;

	/* fill buffer with one caracter and print it */
        static int __attribute__((aligned(8)))   iodc_retbuf[32];
        static char __attribute__((aligned(64))) iodc_dbuf[4096];

	n = 1;
	iodc_dbuf[0] = c;

	spin_lock_irqsave(&pdc_lock, flags);
	real32_call(PAGE0->mem_cons.iodc_io,
		    (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
		    PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
		    __pa(iodc_retbuf), 0, __pa(iodc_dbuf), n, 0);
	spin_unlock_irqrestore(&pdc_lock, flags);
}

/**
 * pdc_iodc_getc - Read a character (non-blocking) from the PDC console.
 *
 * Read a character (non-blocking) from the PDC console, returns -1 if
 * key is not present.
 */
int pdc_iodc_getc(void)
{
	unsigned int flags;
        static int __attribute__((aligned(8)))   iodc_retbuf[32];
        static char __attribute__((aligned(64))) iodc_dbuf[4096];
	int ch;
	int status;

	/* Bail if no console input device. */
	if (!PAGE0->mem_kbd.iodc_io)
		return 0;
	
	/* wait for a keyboard (rs232)-input */
	spin_lock_irqsave(&pdc_lock, flags);
	real32_call(PAGE0->mem_kbd.iodc_io,
		    (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
		    PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers), 
		    __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);

	ch = *iodc_dbuf;
	status = *iodc_retbuf;
	spin_unlock_irqrestore(&pdc_lock, flags);

	if (status == 0)
	    return -1;
	
	return ch;
}

int pdc_sti_call(unsigned long func, unsigned long flags,
                 unsigned long inptr, unsigned long outputr,
                 unsigned long glob_cfg)
{
        int retval;

        spin_lock_irq(&pdc_lock);  
        retval = real32_call(func, flags, inptr, outputr, glob_cfg);
        spin_unlock_irq(&pdc_lock);

        return retval;
}
EXPORT_SYMBOL(pdc_sti_call);

#ifdef __LP64__
/**
 * pdc_pat_cell_get_number - Returns the cell number.
 * @cell_info: The return buffer.
 *
 * This PDC call returns the cell number of the cell from which the call
 * is made.
 */
int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info)
{
	int retval;

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_GET_NUMBER, __pa(pdc_result));
	memcpy(cell_info, pdc_result, sizeof(*cell_info));
	spin_unlock_irq(&pdc_lock);

	return retval;
}

/**
 * pdc_pat_cell_module - Retrieve the cell's module information.
 * @actcnt: The number of bytes written to mem_addr.
 * @ploc: The physical location.
 * @mod: The module index.
 * @view_type: The view of the address type.
 * @mem_addr: The return buffer.
 *
 * This PDC call returns information about each module attached to the cell
 * at the specified location.
 */
int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long mod,
			unsigned long view_type, void *mem_addr)
{
	int retval;
	static struct pdc_pat_cell_mod_maddr_block result __attribute__ ((aligned (8)));

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_MODULE, __pa(pdc_result), 
			      ploc, mod, view_type, __pa(&result));
	if(!retval) {
		*actcnt = pdc_result[0];
		memcpy(mem_addr, &result, *actcnt);
	}
	spin_unlock_irq(&pdc_lock);

	return retval;
}

/**
 * pdc_pat_cpu_get_number - Retrieve the cpu number.
 * @cpu_info: The return buffer.
 * @hpa: The Hard Physical Address of the CPU.
 *
 * Retrieve the cpu number for the cpu at the specified HPA.
 */
int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, void *hpa)
{
	int retval;

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_PAT_CPU, PDC_PAT_CPU_GET_NUMBER,
			      __pa(&pdc_result), hpa);
	memcpy(cpu_info, pdc_result, sizeof(*cpu_info));
	spin_unlock_irq(&pdc_lock);

	return retval;
}

/**
 * pdc_pat_get_irt_size - Retrieve the number of entries in the cell's interrupt table.
 * @num_entries: The return value.
 * @cell_num: The target cell.
 *
 * This PDC function returns the number of entries in the specified cell's
 * interrupt table.
 */
int pdc_pat_get_irt_size(unsigned long *num_entries, unsigned long cell_num)
{
	int retval;

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE_SIZE,
			      __pa(pdc_result), cell_num);
	*num_entries = pdc_result[0];
	spin_unlock_irq(&pdc_lock);

	return retval;
}

/**
 * pdc_pat_get_irt - Retrieve the cell's interrupt table.
 * @r_addr: The return buffer.
 * @cell_num: The target cell.
 *
 * This PDC function returns the actual interrupt table for the specified cell.
 */
int pdc_pat_get_irt(void *r_addr, unsigned long cell_num)
{
	int retval;

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE,
			      __pa(r_addr), cell_num);
	spin_unlock_irq(&pdc_lock);

	return retval;
}

/**
 * pdc_pat_pd_get_addr_map - Retrieve information about memory address ranges.
 * @actlen: The return buffer.
 * @mem_addr: Pointer to the memory buffer.
 * @count: The number of bytes to read from the buffer.
 * @offset: The offset with respect to the beginning of the buffer.
 *
 */
int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, 
			    unsigned long count, unsigned long offset)
{
	int retval;

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_PAT_PD, PDC_PAT_PD_GET_ADDR_MAP, __pa(pdc_result), 
			      __pa(pdc_result2), count, offset);
	*actual_len = pdc_result[0];
	memcpy(mem_addr, pdc_result2, *actual_len);
	spin_unlock_irq(&pdc_lock);

	return retval;
}

/**
 * pdc_pat_io_pci_cfg_read - Read PCI configuration space.
 * @pci_addr: PCI configuration space address for which the read request is being made.
 * @pci_size: Size of read in bytes. Valid values are 1, 2, and 4. 
 * @mem_addr: Pointer to return memory buffer.
 *
 */
int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *mem_addr)
{
	int retval;
	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_READ,
					__pa(pdc_result), pci_addr, pci_size);
	switch(pci_size) {
		case 1: *(u8 *) mem_addr =  (u8)  pdc_result[0];
		case 2: *(u16 *)mem_addr =  (u16) pdc_result[0];
		case 4: *(u32 *)mem_addr =  (u32) pdc_result[0];
	}
	spin_unlock_irq(&pdc_lock);

	return retval;
}

/**
 * pdc_pat_io_pci_cfg_write - Retrieve information about memory address ranges.
 * @pci_addr: PCI configuration space address for which the write  request is being made.
 * @pci_size: Size of write in bytes. Valid values are 1, 2, and 4. 
 * @value: Pointer to 1, 2, or 4 byte value in low order end of argument to be 
 *         written to PCI Config space.
 *
 */
int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val)
{
	int retval;

	spin_lock_irq(&pdc_lock);
	retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_WRITE,
				pci_addr, pci_size, val);
	spin_unlock_irq(&pdc_lock);

	return retval;
}
#endif /* __LP64__ */


/***************** 32-bit real-mode calls ***********/
/* The struct below is used
 * to overlay real_stack (real2.S), preparing a 32-bit call frame.
 * real32_call_asm() then uses this stack in narrow real mode
 */

struct narrow_stack {
	/* use int, not long which is 64 bits */
	unsigned int arg13;
	unsigned int arg12;
	unsigned int arg11;
	unsigned int arg10;
	unsigned int arg9;
	unsigned int arg8;
	unsigned int arg7;
	unsigned int arg6;
	unsigned int arg5;
	unsigned int arg4;
	unsigned int arg3;
	unsigned int arg2;
	unsigned int arg1;
	unsigned int arg0;
	unsigned int frame_marker[8];
	unsigned int sp;
	/* in reality, there's nearly 8k of stack after this */
};

long real32_call(unsigned long fn, ...)
{
	va_list args;
	extern struct narrow_stack real_stack;
	extern unsigned long real32_call_asm(unsigned int *,
					     unsigned int *, 
					     unsigned int);
	
	va_start(args, fn);
	real_stack.arg0 = va_arg(args, unsigned int);
	real_stack.arg1 = va_arg(args, unsigned int);
	real_stack.arg2 = va_arg(args, unsigned int);
	real_stack.arg3 = va_arg(args, unsigned int);
	real_stack.arg4 = va_arg(args, unsigned int);
	real_stack.arg5 = va_arg(args, unsigned int);
	real_stack.arg6 = va_arg(args, unsigned int);
	real_stack.arg7 = va_arg(args, unsigned int);
	real_stack.arg8 = va_arg(args, unsigned int);
	real_stack.arg9 = va_arg(args, unsigned int);
	real_stack.arg10 = va_arg(args, unsigned int);
	real_stack.arg11 = va_arg(args, unsigned int);
	real_stack.arg12 = va_arg(args, unsigned int);
	real_stack.arg13 = va_arg(args, unsigned int);
	va_end(args);
	
	return real32_call_asm(&real_stack.sp, &real_stack.arg0, fn);
}

#ifdef __LP64__
/***************** 64-bit real-mode calls ***********/

struct wide_stack {
	unsigned long arg0;
	unsigned long arg1;
	unsigned long arg2;
	unsigned long arg3;
	unsigned long arg4;
	unsigned long arg5;
	unsigned long arg6;
	unsigned long arg7;
	unsigned long arg8;
	unsigned long arg9;
	unsigned long arg10;
	unsigned long arg11;
	unsigned long arg12;
	unsigned long arg13;
	unsigned long frame_marker[2];	/* rp, previous sp */
	unsigned long sp;
	/* in reality, there's nearly 8k of stack after this */
};

long real64_call(unsigned long fn, ...)
{
	va_list args;
	extern struct wide_stack real64_stack;
	extern unsigned long real64_call_asm(unsigned long *,
					     unsigned long *, 
					     unsigned long);
    
	va_start(args, fn);
	real64_stack.arg0 = va_arg(args, unsigned long);
	real64_stack.arg1 = va_arg(args, unsigned long);
	real64_stack.arg2 = va_arg(args, unsigned long);
	real64_stack.arg3 = va_arg(args, unsigned long);
	real64_stack.arg4 = va_arg(args, unsigned long);
	real64_stack.arg5 = va_arg(args, unsigned long);
	real64_stack.arg6 = va_arg(args, unsigned long);
	real64_stack.arg7 = va_arg(args, unsigned long);
	real64_stack.arg8 = va_arg(args, unsigned long);
	real64_stack.arg9 = va_arg(args, unsigned long);
	real64_stack.arg10 = va_arg(args, unsigned long);
	real64_stack.arg11 = va_arg(args, unsigned long);
	real64_stack.arg12 = va_arg(args, unsigned long);
	real64_stack.arg13 = va_arg(args, unsigned long);
	va_end(args);
	
	return real64_call_asm(&real64_stack.sp, &real64_stack.arg0, fn);
}

#endif /* __LP64__ */

