/*
        Added support for the AMD Geode LX RNG
	(c) Copyright 2004-2005 Advanced Micro Devices, Inc.

	derived from

 	Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
	(c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
 
 	derived from
 
        Hardware driver for the AMD 768 Random Number Generator (RNG)
        (c) Copyright 2001 Red Hat Inc <alan@redhat.com>

 	derived from
 
	Hardware driver for Intel i810 Random Number Generator (RNG)
	Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
	Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>

	Please read Documentation/hw_random.txt for details on use.

	----------------------------------------------------------
	This software may be used and distributed according to the terms
        of the GNU General Public License, incorporated herein by reference.

 */


#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/random.h>
#include <linux/miscdevice.h>
#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/delay.h>

#ifdef __i386__
#include <asm/msr.h>
#include <asm/cpufeature.h>
#endif

#include <asm/io.h>
#include <asm/uaccess.h>


/*
 * core module and version information
 */
#define RNG_VERSION "1.0.0"
#define RNG_MODULE_NAME "hw_random"
#define RNG_DRIVER_NAME   RNG_MODULE_NAME " hardware driver " RNG_VERSION
#define PFX RNG_MODULE_NAME ": "


/*
 * debugging macros
 */

/* pr_debug() collapses to a no-op if DEBUG is not defined */
#define DPRINTK(fmt, args...) pr_debug(PFX "%s: " fmt, __FUNCTION__ , ## args)


#undef RNG_NDEBUG        /* define to enable lightweight runtime checks */
#ifdef RNG_NDEBUG
#define assert(expr)							\
		if(!(expr)) {						\
		printk(KERN_DEBUG PFX "Assertion failed! %s,%s,%s,"	\
		"line=%d\n", #expr, __FILE__, __FUNCTION__, __LINE__);	\
		}
#else
#define assert(expr)
#endif

#define RNG_MISCDEV_MINOR		183 /* official */

static int rng_dev_open (struct inode *inode, struct file *filp);
static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
				loff_t * offp);

static int __init intel_init (struct pci_dev *dev);
static void intel_cleanup(void);
static unsigned int intel_data_present (void);
static u32 intel_data_read (void);

static int __init amd_init (struct pci_dev *dev);
static void amd_cleanup(void);
static unsigned int amd_data_present (void);
static u32 amd_data_read (void);

#ifdef __i386__
static int __init via_init(struct pci_dev *dev);
static void via_cleanup(void);
static unsigned int via_data_present (void);
static u32 via_data_read (void);
#endif

static int __init geode_init(struct pci_dev *dev);
static void geode_cleanup(void);
static unsigned int geode_data_present (void);
static u32 geode_data_read (void);

struct rng_operations {
	int (*init) (struct pci_dev *dev);
	void (*cleanup) (void);
	unsigned int (*data_present) (void);
	u32 (*data_read) (void);
	unsigned int n_bytes; /* number of bytes per ->data_read */
};
static struct rng_operations *rng_ops;

static struct file_operations rng_chrdev_ops = {
	.owner		= THIS_MODULE,
	.open		= rng_dev_open,
	.read		= rng_dev_read,
};


static struct miscdevice rng_miscdev = {
	RNG_MISCDEV_MINOR,
	RNG_MODULE_NAME,
	&rng_chrdev_ops,
};

enum {
	rng_hw_none,
	rng_hw_intel,
	rng_hw_amd,
	rng_hw_via,
	rng_hw_geode,
};

static struct rng_operations rng_vendor_ops[] = {
	/* rng_hw_none */
	{ },

	/* rng_hw_intel */
	{ intel_init, intel_cleanup, intel_data_present,
	  intel_data_read, 1 },

	/* rng_hw_amd */
	{ amd_init, amd_cleanup, amd_data_present, amd_data_read, 4 },

#ifdef __i386__
	/* rng_hw_via */
	{ via_init, via_cleanup, via_data_present, via_data_read, 1 },
#endif

	/* rng_hw_geode */
	{ geode_init, geode_cleanup, geode_data_present, geode_data_read, 4 }
};

/*
 * Data for PCI driver interface
 *
 * This data only exists for exporting the supported
 * PCI ids via MODULE_DEVICE_TABLE.  We do not actually
 * register a pci_driver, because someone else might one day
 * want to register another driver on the same PCI id.
 */
static struct pci_device_id rng_pci_tbl[] = {
	{ 0x1022, 0x7443, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_amd },
	{ 0x1022, 0x746b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_amd },

	{ 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
	{ 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
	{ 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
	{ 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
	{ 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },

	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LX_AES,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_geode },

	{ 0, },	/* terminate list */
};
MODULE_DEVICE_TABLE (pci, rng_pci_tbl);


/***********************************************************************
 *
 * Intel RNG operations
 *
 */

/*
 * RNG registers (offsets from rng_mem)
 */
#define INTEL_RNG_HW_STATUS			0
#define         INTEL_RNG_PRESENT		0x40
#define         INTEL_RNG_ENABLED		0x01
#define INTEL_RNG_STATUS			1
#define         INTEL_RNG_DATA_PRESENT		0x01
#define INTEL_RNG_DATA				2

/*
 * Magic address at which Intel PCI bridges locate the RNG
 */
#define INTEL_RNG_ADDR				0xFFBC015F
#define INTEL_RNG_ADDR_LEN			3

/* token to our ioremap'd RNG register area */
static void __iomem *rng_mem;

static inline u8 intel_hwstatus (void)
{
	assert (rng_mem != NULL);
	return readb (rng_mem + INTEL_RNG_HW_STATUS);
}

static inline u8 intel_hwstatus_set (u8 hw_status)
{
	assert (rng_mem != NULL);
	writeb (hw_status, rng_mem + INTEL_RNG_HW_STATUS);
	return intel_hwstatus ();
}

static unsigned int intel_data_present(void)
{
	assert (rng_mem != NULL);

	return (readb (rng_mem + INTEL_RNG_STATUS) & INTEL_RNG_DATA_PRESENT) ?
		1 : 0;
}

static u32 intel_data_read(void)
{
	assert (rng_mem != NULL);

	return readb (rng_mem + INTEL_RNG_DATA);
}

static int __init intel_init (struct pci_dev *dev)
{
	int rc;
	u8 hw_status;

	DPRINTK ("ENTER\n");

	rng_mem = ioremap (INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN);
	if (rng_mem == NULL) {
		printk (KERN_ERR PFX "cannot ioremap RNG Memory\n");
		rc = -EBUSY;
		goto err_out;
	}

	/* Check for Intel 82802 */
	hw_status = intel_hwstatus ();
	if ((hw_status & INTEL_RNG_PRESENT) == 0) {
		printk (KERN_ERR PFX "RNG not detected\n");
		rc = -ENODEV;
		goto err_out_free_map;
	}

	/* turn RNG h/w on, if it's off */
	if ((hw_status & INTEL_RNG_ENABLED) == 0)
		hw_status = intel_hwstatus_set (hw_status | INTEL_RNG_ENABLED);
	if ((hw_status & INTEL_RNG_ENABLED) == 0) {
		printk (KERN_ERR PFX "cannot enable RNG, aborting\n");
		rc = -EIO;
		goto err_out_free_map;
	}

	DPRINTK ("EXIT, returning 0\n");
	return 0;

err_out_free_map:
	iounmap (rng_mem);
	rng_mem = NULL;
err_out:
	DPRINTK ("EXIT, returning %d\n", rc);
	return rc;
}

static void intel_cleanup(void)
{
	u8 hw_status;

	hw_status = intel_hwstatus ();
	if (hw_status & INTEL_RNG_ENABLED)
		intel_hwstatus_set (hw_status & ~INTEL_RNG_ENABLED);
	else
		printk(KERN_WARNING PFX "unusual: RNG already disabled\n");
	iounmap(rng_mem);
	rng_mem = NULL;
}

/***********************************************************************
 *
 * AMD RNG operations
 *
 */

static u32 pmbase;			/* PMxx I/O base */
static struct pci_dev *amd_dev;

static unsigned int amd_data_present (void)
{
      	return inl(pmbase + 0xF4) & 1;
}


static u32 amd_data_read (void)
{
	return inl(pmbase + 0xF0);
}

static int __init amd_init (struct pci_dev *dev)
{
	int rc;
	u8 rnen;

	DPRINTK ("ENTER\n");

	pci_read_config_dword(dev, 0x58, &pmbase);

	pmbase &= 0x0000FF00;

	if (pmbase == 0)
	{
		printk (KERN_ERR PFX "power management base not set\n");
		rc = -EIO;
		goto err_out;
	}

	pci_read_config_byte(dev, 0x40, &rnen);
	rnen |= (1 << 7);	/* RNG on */
	pci_write_config_byte(dev, 0x40, rnen);

	pci_read_config_byte(dev, 0x41, &rnen);
	rnen |= (1 << 7);	/* PMIO enable */
	pci_write_config_byte(dev, 0x41, rnen);

	pr_info( PFX "AMD768 system management I/O registers at 0x%X.\n",
			pmbase);

	amd_dev = dev;

	DPRINTK ("EXIT, returning 0\n");
	return 0;

err_out:
	DPRINTK ("EXIT, returning %d\n", rc);
	return rc;
}

static void amd_cleanup(void)
{
	u8 rnen;

	pci_read_config_byte(amd_dev, 0x40, &rnen);
	rnen &= ~(1 << 7);	/* RNG off */
	pci_write_config_byte(amd_dev, 0x40, rnen);

	/* FIXME: twiddle pmio, also? */
}

#ifdef __i386__
/***********************************************************************
 *
 * VIA RNG operations
 *
 */

enum {
	VIA_STRFILT_CNT_SHIFT	= 16,
	VIA_STRFILT_FAIL	= (1 << 15),
	VIA_STRFILT_ENABLE	= (1 << 14),
	VIA_RAWBITS_ENABLE	= (1 << 13),
	VIA_RNG_ENABLE		= (1 << 6),
	VIA_XSTORE_CNT_MASK	= 0x0F,

	VIA_RNG_CHUNK_8		= 0x00,	/* 64 rand bits, 64 stored bits */
	VIA_RNG_CHUNK_4		= 0x01,	/* 32 rand bits, 32 stored bits */
	VIA_RNG_CHUNK_4_MASK	= 0xFFFFFFFF,
	VIA_RNG_CHUNK_2		= 0x02,	/* 16 rand bits, 32 stored bits */
	VIA_RNG_CHUNK_2_MASK	= 0xFFFF,
	VIA_RNG_CHUNK_1		= 0x03,	/* 8 rand bits, 32 stored bits */
	VIA_RNG_CHUNK_1_MASK	= 0xFF,
};

static u32 via_rng_datum;

/*
 * Investigate using the 'rep' prefix to obtain 32 bits of random data
 * in one insn.  The upside is potentially better performance.  The
 * downside is that the instruction becomes no longer atomic.  Due to
 * this, just like familiar issues with /dev/random itself, the worst
 * case of a 'rep xstore' could potentially pause a cpu for an
 * unreasonably long time.  In practice, this condition would likely
 * only occur when the hardware is failing.  (or so we hope :))
 *
 * Another possible performance boost may come from simply buffering
 * until we have 4 bytes, thus returning a u32 at a time,
 * instead of the current u8-at-a-time.
 */

static inline u32 xstore(u32 *addr, u32 edx_in)
{
	u32 eax_out;

	asm(".byte 0x0F,0xA7,0xC0 /* xstore %%edi (addr=%0) */"
		:"=m"(*addr), "=a"(eax_out)
		:"D"(addr), "d"(edx_in));

	return eax_out;
}

static unsigned int via_data_present(void)
{
	u32 bytes_out;

	/* We choose the recommended 1-byte-per-instruction RNG rate,
	 * for greater randomness at the expense of speed.  Larger
	 * values 2, 4, or 8 bytes-per-instruction yield greater
	 * speed at lesser randomness.
	 *
	 * If you change this to another VIA_CHUNK_n, you must also
	 * change the ->n_bytes values in rng_vendor_ops[] tables.
	 * VIA_CHUNK_8 requires further code changes.
	 *
	 * A copy of MSR_VIA_RNG is placed in eax_out when xstore
	 * completes.
	 */
	via_rng_datum = 0; /* paranoia, not really necessary */
	bytes_out = xstore(&via_rng_datum, VIA_RNG_CHUNK_1) & VIA_XSTORE_CNT_MASK;
	if (bytes_out == 0)
		return 0;

	return 1;
}

static u32 via_data_read(void)
{
	return via_rng_datum;
}

static int __init via_init(struct pci_dev *dev)
{
	u32 lo, hi, old_lo;

	/* Control the RNG via MSR.  Tread lightly and pay very close
	 * close attention to values written, as the reserved fields
	 * are documented to be "undefined and unpredictable"; but it
	 * does not say to write them as zero, so I make a guess that
	 * we restore the values we find in the register.
	 */
	rdmsr(MSR_VIA_RNG, lo, hi);

	old_lo = lo;
	lo &= ~(0x7f << VIA_STRFILT_CNT_SHIFT);
	lo &= ~VIA_XSTORE_CNT_MASK;
	lo &= ~(VIA_STRFILT_ENABLE | VIA_STRFILT_FAIL | VIA_RAWBITS_ENABLE);
	lo |= VIA_RNG_ENABLE;

	if (lo != old_lo)
		wrmsr(MSR_VIA_RNG, lo, hi);

	/* perhaps-unnecessary sanity check; remove after testing if
	   unneeded */
	rdmsr(MSR_VIA_RNG, lo, hi);
	if ((lo & VIA_RNG_ENABLE) == 0) {
		printk(KERN_ERR PFX "cannot enable VIA C3 RNG, aborting\n");
		return -ENODEV;
	}

	return 0;
}

static void via_cleanup(void)
{
	/* do nothing */
}
#endif

/***********************************************************************
 *
 * AMD Geode RNG operations
 *
 */

static void __iomem *geode_rng_base = NULL;

#define GEODE_RNG_DATA_REG   0x50
#define GEODE_RNG_STATUS_REG 0x54

static u32 geode_data_read(void)
{
	u32 val;

	assert(geode_rng_base != NULL);
	val = readl(geode_rng_base + GEODE_RNG_DATA_REG);
	return val;
}

static unsigned int geode_data_present(void)
{
	u32 val;

	assert(geode_rng_base != NULL);
	val = readl(geode_rng_base + GEODE_RNG_STATUS_REG);
	return val;
}

static void geode_cleanup(void)
{
	iounmap(geode_rng_base);
  	geode_rng_base = NULL;
}

static int geode_init(struct pci_dev *dev)
{
	unsigned long rng_base = pci_resource_start(dev, 0);

	if (rng_base == 0)
		return 1;

	geode_rng_base = ioremap(rng_base, 0x58);

	if (geode_rng_base == NULL) {
		printk(KERN_ERR PFX "Cannot ioremap RNG memory\n");
		return -EBUSY;
	}

	return 0;
}

/***********************************************************************
 *
 * /dev/hwrandom character device handling (major 10, minor 183)
 *
 */

static int rng_dev_open (struct inode *inode, struct file *filp)
{
	/* enforce read-only access to this chrdev */
	if ((filp->f_mode & FMODE_READ) == 0)
		return -EINVAL;
	if (filp->f_mode & FMODE_WRITE)
		return -EINVAL;

	return 0;
}


static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
				loff_t * offp)
{
	static DEFINE_SPINLOCK(rng_lock);
	unsigned int have_data;
	u32 data = 0;
	ssize_t ret = 0;

	while (size) {
		spin_lock(&rng_lock);

		have_data = 0;
		if (rng_ops->data_present()) {
			data = rng_ops->data_read();
			have_data = rng_ops->n_bytes;
		}

		spin_unlock (&rng_lock);

		while (have_data && size) {
			if (put_user((u8)data, buf++)) {
				ret = ret ? : -EFAULT;
				break;
			}
			size--;
			ret++;
			have_data--;
			data>>=8;
		}

		if (filp->f_flags & O_NONBLOCK)
			return ret ? : -EAGAIN;

		if(need_resched())
			schedule_timeout_interruptible(1);
		else
			udelay(200);	/* FIXME: We could poll for 250uS ?? */

		if (signal_pending (current))
			return ret ? : -ERESTARTSYS;
	}
	return ret;
}



/*
 * rng_init_one - look for and attempt to init a single RNG
 */
static int __init rng_init_one (struct pci_dev *dev)
{
	int rc;

	DPRINTK ("ENTER\n");

	assert(rng_ops != NULL);

	rc = rng_ops->init(dev);
	if (rc)
		goto err_out;

	rc = misc_register (&rng_miscdev);
	if (rc) {
		printk (KERN_ERR PFX "misc device register failed\n");
		goto err_out_cleanup_hw;
	}

	DPRINTK ("EXIT, returning 0\n");
	return 0;

err_out_cleanup_hw:
	rng_ops->cleanup();
err_out:
	DPRINTK ("EXIT, returning %d\n", rc);
	return rc;
}



MODULE_AUTHOR("The Linux Kernel team");
MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver");
MODULE_LICENSE("GPL");


/*
 * rng_init - initialize RNG module
 */
static int __init rng_init (void)
{
	int rc;
	struct pci_dev *pdev = NULL;
	const struct pci_device_id *ent;

	DPRINTK ("ENTER\n");

	/* Probe for Intel, AMD, Geode RNGs */
	for_each_pci_dev(pdev) {
		ent = pci_match_id(rng_pci_tbl, pdev);
		if (ent) {
			rng_ops = &rng_vendor_ops[ent->driver_data];
			goto match;
		}
	}

#ifdef __i386__
	/* Probe for VIA RNG */
	if (cpu_has_xstore) {
		rng_ops = &rng_vendor_ops[rng_hw_via];
		pdev = NULL;
		goto match;
	}
#endif

	DPRINTK ("EXIT, returning -ENODEV\n");
	return -ENODEV;

match:
	rc = rng_init_one (pdev);
	if (rc)
		return rc;

	pr_info( RNG_DRIVER_NAME " loaded\n");

	DPRINTK ("EXIT, returning 0\n");
	return 0;
}


/*
 * rng_init - shutdown RNG module
 */
static void __exit rng_cleanup (void)
{
	DPRINTK ("ENTER\n");

	misc_deregister (&rng_miscdev);

	if (rng_ops->cleanup)
		rng_ops->cleanup();

	DPRINTK ("EXIT\n");
}


module_init (rng_init);
module_exit (rng_cleanup);
