[PATCH] skge: support yukon lite rev 4
[linux-2.6] / drivers / char / hw_random.c
1 /*
2         Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
3         (c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
4  
5         derived from
6  
7         Hardware driver for the AMD 768 Random Number Generator (RNG)
8         (c) Copyright 2001 Red Hat Inc <alan@redhat.com>
9
10         derived from
11  
12         Hardware driver for Intel i810 Random Number Generator (RNG)
13         Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
14         Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
15
16         Please read Documentation/hw_random.txt for details on use.
17
18         ----------------------------------------------------------
19         This software may be used and distributed according to the terms
20         of the GNU General Public License, incorporated herein by reference.
21
22  */
23
24
25 #include <linux/module.h>
26 #include <linux/kernel.h>
27 #include <linux/fs.h>
28 #include <linux/init.h>
29 #include <linux/pci.h>
30 #include <linux/interrupt.h>
31 #include <linux/spinlock.h>
32 #include <linux/random.h>
33 #include <linux/miscdevice.h>
34 #include <linux/smp_lock.h>
35 #include <linux/mm.h>
36 #include <linux/delay.h>
37
38 #ifdef __i386__
39 #include <asm/msr.h>
40 #include <asm/cpufeature.h>
41 #endif
42
43 #include <asm/io.h>
44 #include <asm/uaccess.h>
45
46
47 /*
48  * core module and version information
49  */
50 #define RNG_VERSION "1.0.0"
51 #define RNG_MODULE_NAME "hw_random"
52 #define RNG_DRIVER_NAME   RNG_MODULE_NAME " hardware driver " RNG_VERSION
53 #define PFX RNG_MODULE_NAME ": "
54
55
56 /*
57  * debugging macros
58  */
59
60 /* pr_debug() collapses to a no-op if DEBUG is not defined */
61 #define DPRINTK(fmt, args...) pr_debug(PFX "%s: " fmt, __FUNCTION__ , ## args)
62
63
64 #undef RNG_NDEBUG        /* define to enable lightweight runtime checks */
65 #ifdef RNG_NDEBUG
66 #define assert(expr)                                                    \
67                 if(!(expr)) {                                           \
68                 printk(KERN_DEBUG PFX "Assertion failed! %s,%s,%s,"     \
69                 "line=%d\n", #expr, __FILE__, __FUNCTION__, __LINE__);  \
70                 }
71 #else
72 #define assert(expr)
73 #endif
74
75 #define RNG_MISCDEV_MINOR               183 /* official */
76
77 static int rng_dev_open (struct inode *inode, struct file *filp);
78 static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
79                                 loff_t * offp);
80
81 static int __init intel_init (struct pci_dev *dev);
82 static void intel_cleanup(void);
83 static unsigned int intel_data_present (void);
84 static u32 intel_data_read (void);
85
86 static int __init amd_init (struct pci_dev *dev);
87 static void amd_cleanup(void);
88 static unsigned int amd_data_present (void);
89 static u32 amd_data_read (void);
90
91 #ifdef __i386__
92 static int __init via_init(struct pci_dev *dev);
93 static void via_cleanup(void);
94 static unsigned int via_data_present (void);
95 static u32 via_data_read (void);
96 #endif
97
98 struct rng_operations {
99         int (*init) (struct pci_dev *dev);
100         void (*cleanup) (void);
101         unsigned int (*data_present) (void);
102         u32 (*data_read) (void);
103         unsigned int n_bytes; /* number of bytes per ->data_read */
104 };
105 static struct rng_operations *rng_ops;
106
107 static struct file_operations rng_chrdev_ops = {
108         .owner          = THIS_MODULE,
109         .open           = rng_dev_open,
110         .read           = rng_dev_read,
111 };
112
113
114 static struct miscdevice rng_miscdev = {
115         RNG_MISCDEV_MINOR,
116         RNG_MODULE_NAME,
117         &rng_chrdev_ops,
118 };
119
120 enum {
121         rng_hw_none,
122         rng_hw_intel,
123         rng_hw_amd,
124         rng_hw_via,
125 };
126
127 static struct rng_operations rng_vendor_ops[] = {
128         /* rng_hw_none */
129         { },
130
131         /* rng_hw_intel */
132         { intel_init, intel_cleanup, intel_data_present,
133           intel_data_read, 1 },
134
135         /* rng_hw_amd */
136         { amd_init, amd_cleanup, amd_data_present, amd_data_read, 4 },
137
138 #ifdef __i386__
139         /* rng_hw_via */
140         { via_init, via_cleanup, via_data_present, via_data_read, 1 },
141 #endif
142 };
143
144 /*
145  * Data for PCI driver interface
146  *
147  * This data only exists for exporting the supported
148  * PCI ids via MODULE_DEVICE_TABLE.  We do not actually
149  * register a pci_driver, because someone else might one day
150  * want to register another driver on the same PCI id.
151  */
152 static struct pci_device_id rng_pci_tbl[] = {
153         { 0x1022, 0x7443, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_amd },
154         { 0x1022, 0x746b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_amd },
155
156         { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
157         { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
158         { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
159         { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
160         { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
161
162         { 0, }, /* terminate list */
163 };
164 MODULE_DEVICE_TABLE (pci, rng_pci_tbl);
165
166
167 /***********************************************************************
168  *
169  * Intel RNG operations
170  *
171  */
172
173 /*
174  * RNG registers (offsets from rng_mem)
175  */
176 #define INTEL_RNG_HW_STATUS                     0
177 #define         INTEL_RNG_PRESENT               0x40
178 #define         INTEL_RNG_ENABLED               0x01
179 #define INTEL_RNG_STATUS                        1
180 #define         INTEL_RNG_DATA_PRESENT          0x01
181 #define INTEL_RNG_DATA                          2
182
183 /*
184  * Magic address at which Intel PCI bridges locate the RNG
185  */
186 #define INTEL_RNG_ADDR                          0xFFBC015F
187 #define INTEL_RNG_ADDR_LEN                      3
188
189 /* token to our ioremap'd RNG register area */
190 static void __iomem *rng_mem;
191
192 static inline u8 intel_hwstatus (void)
193 {
194         assert (rng_mem != NULL);
195         return readb (rng_mem + INTEL_RNG_HW_STATUS);
196 }
197
198 static inline u8 intel_hwstatus_set (u8 hw_status)
199 {
200         assert (rng_mem != NULL);
201         writeb (hw_status, rng_mem + INTEL_RNG_HW_STATUS);
202         return intel_hwstatus ();
203 }
204
205 static unsigned int intel_data_present(void)
206 {
207         assert (rng_mem != NULL);
208
209         return (readb (rng_mem + INTEL_RNG_STATUS) & INTEL_RNG_DATA_PRESENT) ?
210                 1 : 0;
211 }
212
213 static u32 intel_data_read(void)
214 {
215         assert (rng_mem != NULL);
216
217         return readb (rng_mem + INTEL_RNG_DATA);
218 }
219
220 static int __init intel_init (struct pci_dev *dev)
221 {
222         int rc;
223         u8 hw_status;
224
225         DPRINTK ("ENTER\n");
226
227         rng_mem = ioremap (INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN);
228         if (rng_mem == NULL) {
229                 printk (KERN_ERR PFX "cannot ioremap RNG Memory\n");
230                 rc = -EBUSY;
231                 goto err_out;
232         }
233
234         /* Check for Intel 82802 */
235         hw_status = intel_hwstatus ();
236         if ((hw_status & INTEL_RNG_PRESENT) == 0) {
237                 printk (KERN_ERR PFX "RNG not detected\n");
238                 rc = -ENODEV;
239                 goto err_out_free_map;
240         }
241
242         /* turn RNG h/w on, if it's off */
243         if ((hw_status & INTEL_RNG_ENABLED) == 0)
244                 hw_status = intel_hwstatus_set (hw_status | INTEL_RNG_ENABLED);
245         if ((hw_status & INTEL_RNG_ENABLED) == 0) {
246                 printk (KERN_ERR PFX "cannot enable RNG, aborting\n");
247                 rc = -EIO;
248                 goto err_out_free_map;
249         }
250
251         DPRINTK ("EXIT, returning 0\n");
252         return 0;
253
254 err_out_free_map:
255         iounmap (rng_mem);
256         rng_mem = NULL;
257 err_out:
258         DPRINTK ("EXIT, returning %d\n", rc);
259         return rc;
260 }
261
262 static void intel_cleanup(void)
263 {
264         u8 hw_status;
265
266         hw_status = intel_hwstatus ();
267         if (hw_status & INTEL_RNG_ENABLED)
268                 intel_hwstatus_set (hw_status & ~INTEL_RNG_ENABLED);
269         else
270                 printk(KERN_WARNING PFX "unusual: RNG already disabled\n");
271         iounmap(rng_mem);
272         rng_mem = NULL;
273 }
274
275 /***********************************************************************
276  *
277  * AMD RNG operations
278  *
279  */
280
281 static u32 pmbase;                      /* PMxx I/O base */
282 static struct pci_dev *amd_dev;
283
284 static unsigned int amd_data_present (void)
285 {
286         return inl(pmbase + 0xF4) & 1;
287 }
288
289
290 static u32 amd_data_read (void)
291 {
292         return inl(pmbase + 0xF0);
293 }
294
295 static int __init amd_init (struct pci_dev *dev)
296 {
297         int rc;
298         u8 rnen;
299
300         DPRINTK ("ENTER\n");
301
302         pci_read_config_dword(dev, 0x58, &pmbase);
303
304         pmbase &= 0x0000FF00;
305
306         if (pmbase == 0)
307         {
308                 printk (KERN_ERR PFX "power management base not set\n");
309                 rc = -EIO;
310                 goto err_out;
311         }
312
313         pci_read_config_byte(dev, 0x40, &rnen);
314         rnen |= (1 << 7);       /* RNG on */
315         pci_write_config_byte(dev, 0x40, rnen);
316
317         pci_read_config_byte(dev, 0x41, &rnen);
318         rnen |= (1 << 7);       /* PMIO enable */
319         pci_write_config_byte(dev, 0x41, rnen);
320
321         pr_info( PFX "AMD768 system management I/O registers at 0x%X.\n",
322                         pmbase);
323
324         amd_dev = dev;
325
326         DPRINTK ("EXIT, returning 0\n");
327         return 0;
328
329 err_out:
330         DPRINTK ("EXIT, returning %d\n", rc);
331         return rc;
332 }
333
334 static void amd_cleanup(void)
335 {
336         u8 rnen;
337
338         pci_read_config_byte(amd_dev, 0x40, &rnen);
339         rnen &= ~(1 << 7);      /* RNG off */
340         pci_write_config_byte(amd_dev, 0x40, rnen);
341
342         /* FIXME: twiddle pmio, also? */
343 }
344
345 #ifdef __i386__
346 /***********************************************************************
347  *
348  * VIA RNG operations
349  *
350  */
351
352 enum {
353         VIA_STRFILT_CNT_SHIFT   = 16,
354         VIA_STRFILT_FAIL        = (1 << 15),
355         VIA_STRFILT_ENABLE      = (1 << 14),
356         VIA_RAWBITS_ENABLE      = (1 << 13),
357         VIA_RNG_ENABLE          = (1 << 6),
358         VIA_XSTORE_CNT_MASK     = 0x0F,
359
360         VIA_RNG_CHUNK_8         = 0x00, /* 64 rand bits, 64 stored bits */
361         VIA_RNG_CHUNK_4         = 0x01, /* 32 rand bits, 32 stored bits */
362         VIA_RNG_CHUNK_4_MASK    = 0xFFFFFFFF,
363         VIA_RNG_CHUNK_2         = 0x02, /* 16 rand bits, 32 stored bits */
364         VIA_RNG_CHUNK_2_MASK    = 0xFFFF,
365         VIA_RNG_CHUNK_1         = 0x03, /* 8 rand bits, 32 stored bits */
366         VIA_RNG_CHUNK_1_MASK    = 0xFF,
367 };
368
369 static u32 via_rng_datum;
370
371 /*
372  * Investigate using the 'rep' prefix to obtain 32 bits of random data
373  * in one insn.  The upside is potentially better performance.  The
374  * downside is that the instruction becomes no longer atomic.  Due to
375  * this, just like familiar issues with /dev/random itself, the worst
376  * case of a 'rep xstore' could potentially pause a cpu for an
377  * unreasonably long time.  In practice, this condition would likely
378  * only occur when the hardware is failing.  (or so we hope :))
379  *
380  * Another possible performance boost may come from simply buffering
381  * until we have 4 bytes, thus returning a u32 at a time,
382  * instead of the current u8-at-a-time.
383  */
384
385 static inline u32 xstore(u32 *addr, u32 edx_in)
386 {
387         u32 eax_out;
388
389         asm(".byte 0x0F,0xA7,0xC0 /* xstore %%edi (addr=%0) */"
390                 :"=m"(*addr), "=a"(eax_out)
391                 :"D"(addr), "d"(edx_in));
392
393         return eax_out;
394 }
395
396 static unsigned int via_data_present(void)
397 {
398         u32 bytes_out;
399
400         /* We choose the recommended 1-byte-per-instruction RNG rate,
401          * for greater randomness at the expense of speed.  Larger
402          * values 2, 4, or 8 bytes-per-instruction yield greater
403          * speed at lesser randomness.
404          *
405          * If you change this to another VIA_CHUNK_n, you must also
406          * change the ->n_bytes values in rng_vendor_ops[] tables.
407          * VIA_CHUNK_8 requires further code changes.
408          *
409          * A copy of MSR_VIA_RNG is placed in eax_out when xstore
410          * completes.
411          */
412         via_rng_datum = 0; /* paranoia, not really necessary */
413         bytes_out = xstore(&via_rng_datum, VIA_RNG_CHUNK_1) & VIA_XSTORE_CNT_MASK;
414         if (bytes_out == 0)
415                 return 0;
416
417         return 1;
418 }
419
420 static u32 via_data_read(void)
421 {
422         return via_rng_datum;
423 }
424
425 static int __init via_init(struct pci_dev *dev)
426 {
427         u32 lo, hi, old_lo;
428
429         /* Control the RNG via MSR.  Tread lightly and pay very close
430          * close attention to values written, as the reserved fields
431          * are documented to be "undefined and unpredictable"; but it
432          * does not say to write them as zero, so I make a guess that
433          * we restore the values we find in the register.
434          */
435         rdmsr(MSR_VIA_RNG, lo, hi);
436
437         old_lo = lo;
438         lo &= ~(0x7f << VIA_STRFILT_CNT_SHIFT);
439         lo &= ~VIA_XSTORE_CNT_MASK;
440         lo &= ~(VIA_STRFILT_ENABLE | VIA_STRFILT_FAIL | VIA_RAWBITS_ENABLE);
441         lo |= VIA_RNG_ENABLE;
442
443         if (lo != old_lo)
444                 wrmsr(MSR_VIA_RNG, lo, hi);
445
446         /* perhaps-unnecessary sanity check; remove after testing if
447            unneeded */
448         rdmsr(MSR_VIA_RNG, lo, hi);
449         if ((lo & VIA_RNG_ENABLE) == 0) {
450                 printk(KERN_ERR PFX "cannot enable VIA C3 RNG, aborting\n");
451                 return -ENODEV;
452         }
453
454         return 0;
455 }
456
457 static void via_cleanup(void)
458 {
459         /* do nothing */
460 }
461 #endif
462
463
464 /***********************************************************************
465  *
466  * /dev/hwrandom character device handling (major 10, minor 183)
467  *
468  */
469
470 static int rng_dev_open (struct inode *inode, struct file *filp)
471 {
472         /* enforce read-only access to this chrdev */
473         if ((filp->f_mode & FMODE_READ) == 0)
474                 return -EINVAL;
475         if (filp->f_mode & FMODE_WRITE)
476                 return -EINVAL;
477
478         return 0;
479 }
480
481
482 static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
483                                 loff_t * offp)
484 {
485         static DEFINE_SPINLOCK(rng_lock);
486         unsigned int have_data;
487         u32 data = 0;
488         ssize_t ret = 0;
489
490         while (size) {
491                 spin_lock(&rng_lock);
492
493                 have_data = 0;
494                 if (rng_ops->data_present()) {
495                         data = rng_ops->data_read();
496                         have_data = rng_ops->n_bytes;
497                 }
498
499                 spin_unlock (&rng_lock);
500
501                 while (have_data && size) {
502                         if (put_user((u8)data, buf++)) {
503                                 ret = ret ? : -EFAULT;
504                                 break;
505                         }
506                         size--;
507                         ret++;
508                         have_data--;
509                         data>>=8;
510                 }
511
512                 if (filp->f_flags & O_NONBLOCK)
513                         return ret ? : -EAGAIN;
514
515                 if(need_resched())
516                 {
517                         current->state = TASK_INTERRUPTIBLE;
518                         schedule_timeout(1);
519                 }
520                 else
521                         udelay(200);    /* FIXME: We could poll for 250uS ?? */
522
523                 if (signal_pending (current))
524                         return ret ? : -ERESTARTSYS;
525         }
526         return ret;
527 }
528
529
530
531 /*
532  * rng_init_one - look for and attempt to init a single RNG
533  */
534 static int __init rng_init_one (struct pci_dev *dev)
535 {
536         int rc;
537
538         DPRINTK ("ENTER\n");
539
540         assert(rng_ops != NULL);
541
542         rc = rng_ops->init(dev);
543         if (rc)
544                 goto err_out;
545
546         rc = misc_register (&rng_miscdev);
547         if (rc) {
548                 printk (KERN_ERR PFX "misc device register failed\n");
549                 goto err_out_cleanup_hw;
550         }
551
552         DPRINTK ("EXIT, returning 0\n");
553         return 0;
554
555 err_out_cleanup_hw:
556         rng_ops->cleanup();
557 err_out:
558         DPRINTK ("EXIT, returning %d\n", rc);
559         return rc;
560 }
561
562
563
564 MODULE_AUTHOR("The Linux Kernel team");
565 MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver");
566 MODULE_LICENSE("GPL");
567
568
569 /*
570  * rng_init - initialize RNG module
571  */
572 static int __init rng_init (void)
573 {
574         int rc;
575         struct pci_dev *pdev = NULL;
576         const struct pci_device_id *ent;
577
578         DPRINTK ("ENTER\n");
579
580         /* Probe for Intel, AMD RNGs */
581         for_each_pci_dev(pdev) {
582                 ent = pci_match_id(rng_pci_tbl, pdev);
583                 if (ent) {
584                         rng_ops = &rng_vendor_ops[ent->driver_data];
585                         goto match;
586                 }
587         }
588
589 #ifdef __i386__
590         /* Probe for VIA RNG */
591         if (cpu_has_xstore) {
592                 rng_ops = &rng_vendor_ops[rng_hw_via];
593                 pdev = NULL;
594                 goto match;
595         }
596 #endif
597
598         DPRINTK ("EXIT, returning -ENODEV\n");
599         return -ENODEV;
600
601 match:
602         rc = rng_init_one (pdev);
603         if (rc)
604                 return rc;
605
606         pr_info( RNG_DRIVER_NAME " loaded\n");
607
608         DPRINTK ("EXIT, returning 0\n");
609         return 0;
610 }
611
612
613 /*
614  * rng_init - shutdown RNG module
615  */
616 static void __exit rng_cleanup (void)
617 {
618         DPRINTK ("ENTER\n");
619
620         misc_deregister (&rng_miscdev);
621
622         if (rng_ops->cleanup)
623                 rng_ops->cleanup();
624
625         DPRINTK ("EXIT\n");
626 }
627
628
629 module_init (rng_init);
630 module_exit (rng_cleanup);