intel-rng.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. * RNG driver for Intel RNGs
  3. *
  4. * Copyright 2005 (c) MontaVista Software, Inc.
  5. *
  6. * with the majority of the code coming from:
  7. *
  8. * Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
  9. * (c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
  10. *
  11. * derived from
  12. *
  13. * Hardware driver for the AMD 768 Random Number Generator (RNG)
  14. * (c) Copyright 2001 Red Hat Inc <alan@redhat.com>
  15. *
  16. * derived from
  17. *
  18. * Hardware driver for Intel i810 Random Number Generator (RNG)
  19. * Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
  20. * Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
  21. *
  22. * This file is licensed under the terms of the GNU General Public
  23. * License version 2. This program is licensed "as is" without any
  24. * warranty of any kind, whether express or implied.
  25. */
  26. #include <linux/module.h>
  27. #include <linux/kernel.h>
  28. #include <linux/pci.h>
  29. #include <linux/hw_random.h>
  30. #include <asm/io.h>
  31. #define PFX KBUILD_MODNAME ": "
  32. /*
  33. * RNG registers
  34. */
  35. #define INTEL_RNG_HW_STATUS 0
  36. #define INTEL_RNG_PRESENT 0x40
  37. #define INTEL_RNG_ENABLED 0x01
  38. #define INTEL_RNG_STATUS 1
  39. #define INTEL_RNG_DATA_PRESENT 0x01
  40. #define INTEL_RNG_DATA 2
  41. /*
  42. * Magic address at which Intel PCI bridges locate the RNG
  43. */
  44. #define INTEL_RNG_ADDR 0xFFBC015F
  45. #define INTEL_RNG_ADDR_LEN 3
  46. /*
  47. * LPC bridge PCI config space registers
  48. */
  49. #define FWH_DEC_EN1_REG_OLD 0xe3
  50. #define FWH_DEC_EN1_REG_NEW 0xd9 /* high byte of 16-bit register */
  51. #define FWH_F8_EN_MASK 0x80
  52. #define BIOS_CNTL_REG_OLD 0x4e
  53. #define BIOS_CNTL_REG_NEW 0xdc
  54. #define BIOS_CNTL_WRITE_ENABLE_MASK 0x01
  55. #define BIOS_CNTL_LOCK_ENABLE_MASK 0x02
  56. /*
  57. * Magic address at which Intel Firmware Hubs get accessed
  58. */
  59. #define INTEL_FWH_ADDR 0xffff0000
  60. #define INTEL_FWH_ADDR_LEN 2
  61. /*
  62. * Intel Firmware Hub command codes (write to any address inside the device)
  63. */
  64. #define INTEL_FWH_RESET_CMD 0xff /* aka READ_ARRAY */
  65. #define INTEL_FWH_READ_ID_CMD 0x90
  66. /*
  67. * Intel Firmware Hub Read ID command result addresses
  68. */
  69. #define INTEL_FWH_MANUFACTURER_CODE_ADDRESS 0x000000
  70. #define INTEL_FWH_DEVICE_CODE_ADDRESS 0x000001
  71. /*
  72. * Intel Firmware Hub Read ID command result values
  73. */
  74. #define INTEL_FWH_MANUFACTURER_CODE 0x89
  75. #define INTEL_FWH_DEVICE_CODE_8M 0xac
  76. #define INTEL_FWH_DEVICE_CODE_4M 0xad
  77. /*
  78. * Data for PCI driver interface
  79. *
  80. * This data only exists for exporting the supported
  81. * PCI ids via MODULE_DEVICE_TABLE. We do not actually
  82. * register a pci_driver, because someone else might one day
  83. * want to register another driver on the same PCI id.
  84. */
  85. static const struct pci_device_id pci_tbl[] = {
  86. /* AA
  87. { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
  88. { 0x8086, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AA */
  89. /* AB
  90. { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
  91. { 0x8086, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AB */
  92. /* ??
  93. { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
  94. /* BAM, CAM, DBM, FBM, GxM
  95. { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
  96. { 0x8086, 0x244c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BAM */
  97. { 0x8086, 0x248c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CAM */
  98. { 0x8086, 0x24cc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DBM */
  99. { 0x8086, 0x2641, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* FBM */
  100. { 0x8086, 0x27b9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM */
  101. { 0x8086, 0x27bd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM DH */
  102. /* BA, CA, DB, Ex, 6300, Fx, 631x/632x, Gx
  103. { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
  104. { 0x8086, 0x2440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BA */
  105. { 0x8086, 0x2480, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CA */
  106. { 0x8086, 0x24c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DB */
  107. { 0x8086, 0x24d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ex */
  108. { 0x8086, 0x25a1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 6300 */
  109. { 0x8086, 0x2640, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Fx */
  110. { 0x8086, 0x2670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  111. { 0x8086, 0x2671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  112. { 0x8086, 0x2672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  113. { 0x8086, 0x2673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  114. { 0x8086, 0x2674, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  115. { 0x8086, 0x2675, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  116. { 0x8086, 0x2676, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  117. { 0x8086, 0x2677, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  118. { 0x8086, 0x2678, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  119. { 0x8086, 0x2679, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  120. { 0x8086, 0x267a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  121. { 0x8086, 0x267b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  122. { 0x8086, 0x267c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  123. { 0x8086, 0x267d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  124. { 0x8086, 0x267e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  125. { 0x8086, 0x267f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
  126. { 0x8086, 0x27b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Gx */
  127. /* E
  128. { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
  129. { 0x8086, 0x2450, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* E */
  130. { 0, }, /* terminate list */
  131. };
  132. MODULE_DEVICE_TABLE(pci, pci_tbl);
  133. static __initdata int no_fwh_detect;
  134. module_param(no_fwh_detect, int, 0);
  135. MODULE_PARM_DESC(no_fwh_detect, "Skip FWH detection:\n"
  136. " positive value - skip if FWH space locked read-only\n"
  137. " negative value - skip always");
  138. static inline u8 hwstatus_get(void __iomem *mem)
  139. {
  140. return readb(mem + INTEL_RNG_HW_STATUS);
  141. }
  142. static inline u8 hwstatus_set(void __iomem *mem,
  143. u8 hw_status)
  144. {
  145. writeb(hw_status, mem + INTEL_RNG_HW_STATUS);
  146. return hwstatus_get(mem);
  147. }
  148. static int intel_rng_data_present(struct hwrng *rng)
  149. {
  150. void __iomem *mem = (void __iomem *)rng->priv;
  151. return !!(readb(mem + INTEL_RNG_STATUS) & INTEL_RNG_DATA_PRESENT);
  152. }
  153. static int intel_rng_data_read(struct hwrng *rng, u32 *data)
  154. {
  155. void __iomem *mem = (void __iomem *)rng->priv;
  156. *data = readb(mem + INTEL_RNG_DATA);
  157. return 1;
  158. }
  159. static int intel_rng_init(struct hwrng *rng)
  160. {
  161. void __iomem *mem = (void __iomem *)rng->priv;
  162. u8 hw_status;
  163. int err = -EIO;
  164. hw_status = hwstatus_get(mem);
  165. /* turn RNG h/w on, if it's off */
  166. if ((hw_status & INTEL_RNG_ENABLED) == 0)
  167. hw_status = hwstatus_set(mem, hw_status | INTEL_RNG_ENABLED);
  168. if ((hw_status & INTEL_RNG_ENABLED) == 0) {
  169. printk(KERN_ERR PFX "cannot enable RNG, aborting\n");
  170. goto out;
  171. }
  172. err = 0;
  173. out:
  174. return err;
  175. }
  176. static void intel_rng_cleanup(struct hwrng *rng)
  177. {
  178. void __iomem *mem = (void __iomem *)rng->priv;
  179. u8 hw_status;
  180. hw_status = hwstatus_get(mem);
  181. if (hw_status & INTEL_RNG_ENABLED)
  182. hwstatus_set(mem, hw_status & ~INTEL_RNG_ENABLED);
  183. else
  184. printk(KERN_WARNING PFX "unusual: RNG already disabled\n");
  185. }
  186. static struct hwrng intel_rng = {
  187. .name = "intel",
  188. .init = intel_rng_init,
  189. .cleanup = intel_rng_cleanup,
  190. .data_present = intel_rng_data_present,
  191. .data_read = intel_rng_data_read,
  192. };
  193. #ifdef CONFIG_SMP
  194. static char __initdata waitflag;
  195. static void __init intel_init_wait(void *unused)
  196. {
  197. while (waitflag)
  198. cpu_relax();
  199. }
  200. #endif
  201. static int __init mod_init(void)
  202. {
  203. int err = -ENODEV;
  204. unsigned i;
  205. struct pci_dev *dev = NULL;
  206. void __iomem *mem;
  207. unsigned long flags;
  208. u8 bios_cntl_off, fwh_dec_en1_off;
  209. u8 bios_cntl_val = 0xff, fwh_dec_en1_val = 0xff;
  210. u8 hw_status, mfc, dvc;
  211. for (i = 0; !dev && pci_tbl[i].vendor; ++i)
  212. dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, NULL);
  213. if (!dev)
  214. goto out; /* Device not found. */
  215. if (no_fwh_detect < 0) {
  216. pci_dev_put(dev);
  217. goto fwh_done;
  218. }
  219. /* Check for Intel 82802 */
  220. if (dev->device < 0x2640) {
  221. fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD;
  222. bios_cntl_off = BIOS_CNTL_REG_OLD;
  223. } else {
  224. fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW;
  225. bios_cntl_off = BIOS_CNTL_REG_NEW;
  226. }
  227. pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val);
  228. pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val);
  229. if ((bios_cntl_val &
  230. (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))
  231. == BIOS_CNTL_LOCK_ENABLE_MASK) {
  232. static __initdata /*const*/ char warning[] =
  233. KERN_WARNING PFX "Firmware space is locked read-only. If you can't or\n"
  234. KERN_WARNING PFX "don't want to disable this in firmware setup, and if\n"
  235. KERN_WARNING PFX "you are certain that your system has a functional\n"
  236. KERN_WARNING PFX "RNG, try using the 'no_fwh_detect' option.\n";
  237. pci_dev_put(dev);
  238. if (no_fwh_detect)
  239. goto fwh_done;
  240. printk(warning);
  241. err = -EBUSY;
  242. goto out;
  243. }
  244. mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN);
  245. if (mem == NULL) {
  246. pci_dev_put(dev);
  247. err = -EBUSY;
  248. goto out;
  249. }
  250. /*
  251. * Since the BIOS code/data is going to disappear from its normal
  252. * location with the Read ID command, all activity on the system
  253. * must be stopped until the state is back to normal.
  254. */
  255. #ifdef CONFIG_SMP
  256. set_mb(waitflag, 1);
  257. if (smp_call_function(intel_init_wait, NULL, 1, 0) != 0) {
  258. set_mb(waitflag, 0);
  259. pci_dev_put(dev);
  260. printk(KERN_ERR PFX "cannot run on all processors\n");
  261. err = -EAGAIN;
  262. goto err_unmap;
  263. }
  264. #endif
  265. local_irq_save(flags);
  266. if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
  267. pci_write_config_byte(dev,
  268. fwh_dec_en1_off,
  269. fwh_dec_en1_val | FWH_F8_EN_MASK);
  270. if (!(bios_cntl_val & BIOS_CNTL_WRITE_ENABLE_MASK))
  271. pci_write_config_byte(dev,
  272. bios_cntl_off,
  273. bios_cntl_val | BIOS_CNTL_WRITE_ENABLE_MASK);
  274. writeb(INTEL_FWH_RESET_CMD, mem);
  275. writeb(INTEL_FWH_READ_ID_CMD, mem);
  276. mfc = readb(mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS);
  277. dvc = readb(mem + INTEL_FWH_DEVICE_CODE_ADDRESS);
  278. writeb(INTEL_FWH_RESET_CMD, mem);
  279. if (!(bios_cntl_val &
  280. (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
  281. pci_write_config_byte(dev, bios_cntl_off, bios_cntl_val);
  282. if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
  283. pci_write_config_byte(dev, fwh_dec_en1_off, fwh_dec_en1_val);
  284. local_irq_restore(flags);
  285. #ifdef CONFIG_SMP
  286. /* Tell other CPUs to resume. */
  287. set_mb(waitflag, 0);
  288. #endif
  289. iounmap(mem);
  290. pci_dev_put(dev);
  291. if (mfc != INTEL_FWH_MANUFACTURER_CODE ||
  292. (dvc != INTEL_FWH_DEVICE_CODE_8M &&
  293. dvc != INTEL_FWH_DEVICE_CODE_4M)) {
  294. printk(KERN_ERR PFX "FWH not detected\n");
  295. err = -ENODEV;
  296. goto out;
  297. }
  298. fwh_done:
  299. err = -ENOMEM;
  300. mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN);
  301. if (!mem)
  302. goto out;
  303. intel_rng.priv = (unsigned long)mem;
  304. /* Check for Random Number Generator */
  305. err = -ENODEV;
  306. hw_status = hwstatus_get(mem);
  307. if ((hw_status & INTEL_RNG_PRESENT) == 0)
  308. goto err_unmap;
  309. printk(KERN_INFO "Intel 82802 RNG detected\n");
  310. err = hwrng_register(&intel_rng);
  311. if (err) {
  312. printk(KERN_ERR PFX "RNG registering failed (%d)\n",
  313. err);
  314. goto err_unmap;
  315. }
  316. out:
  317. return err;
  318. err_unmap:
  319. iounmap(mem);
  320. goto out;
  321. }
  322. static void __exit mod_exit(void)
  323. {
  324. void __iomem *mem = (void __iomem *)intel_rng.priv;
  325. hwrng_unregister(&intel_rng);
  326. iounmap(mem);
  327. }
  328. module_init(mod_init);
  329. module_exit(mod_exit);
  330. MODULE_DESCRIPTION("H/W RNG driver for Intel chipsets");
  331. MODULE_LICENSE("GPL");