Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /*
  2. * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * Based in part on pci.c from Etherboot 5.4, by Ken Yap and David
  5. * Munro, in turn based on the Linux kernel's PCI implementation.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of the
  10. * License, or any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. #include <stdint.h>
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <errno.h>
  26. #include <gpxe/tables.h>
  27. #include <gpxe/device.h>
  28. #include <gpxe/pci.h>
  29. /** @file
  30. *
  31. * PCI bus
  32. *
  33. */
  34. static struct pci_driver pci_drivers[0]
  35. __table_start ( struct pci_driver, pci_drivers );
  36. static struct pci_driver pci_drivers_end[0]
  37. __table_end ( struct pci_driver, pci_drivers );
  38. static void pcibus_remove ( struct root_device *rootdev );
  39. /**
  40. * Read PCI BAR
  41. *
  42. * @v pci PCI device
  43. * @v reg PCI register number
  44. * @ret bar Base address register
  45. *
  46. * Reads the specified PCI base address register, including the flags
  47. * portion. 64-bit BARs will be handled automatically. If the value
  48. * of the 64-bit BAR exceeds the size of an unsigned long (i.e. if the
  49. * high dword is non-zero on a 32-bit platform), then the value
  50. * returned will be zero plus the flags for a 64-bit BAR. Unreachable
  51. * 64-bit BARs are therefore returned as uninitialised 64-bit BARs.
  52. */
  53. static unsigned long pci_bar ( struct pci_device *pci, unsigned int reg ) {
  54. uint32_t low;
  55. uint32_t high;
  56. pci_read_config_dword ( pci, reg, &low );
  57. if ( ( low & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK) )
  58. == (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64) ){
  59. pci_read_config_dword ( pci, reg + 4, &high );
  60. if ( high ) {
  61. if ( sizeof ( unsigned long ) > sizeof ( uint32_t ) ) {
  62. return ( ( ( uint64_t ) high << 32 ) | low );
  63. } else {
  64. DBG ( "Unhandled 64-bit BAR %08lx%08lx\n",
  65. high, low );
  66. return PCI_BASE_ADDRESS_MEM_TYPE_64;
  67. }
  68. }
  69. }
  70. return low;
  71. }
  72. /**
  73. * Find the start of a PCI BAR
  74. *
  75. * @v pci PCI device
  76. * @v reg PCI register number
  77. * @ret start BAR start address
  78. *
  79. * Reads the specified PCI base address register, and returns the
  80. * address portion of the BAR (i.e. without the flags).
  81. *
  82. * If the address exceeds the size of an unsigned long (i.e. if a
  83. * 64-bit BAR has a non-zero high dword on a 32-bit machine), the
  84. * return value will be zero.
  85. */
  86. unsigned long pci_bar_start ( struct pci_device *pci, unsigned int reg ) {
  87. unsigned long bar;
  88. bar = pci_bar ( pci, reg );
  89. if ( (bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY ){
  90. return ( bar & PCI_BASE_ADDRESS_MEM_MASK );
  91. } else {
  92. return ( bar & PCI_BASE_ADDRESS_IO_MASK );
  93. }
  94. }
  95. /**
  96. * Read membase and ioaddr for a PCI device
  97. *
  98. * @v pci PCI device
  99. *
  100. * This scans through all PCI BARs on the specified device. The first
  101. * valid memory BAR is recorded as pci_device::membase, and the first
  102. * valid IO BAR is recorded as pci_device::ioaddr.
  103. *
  104. * 64-bit BARs are handled automatically. On a 32-bit platform, if a
  105. * 64-bit BAR has a non-zero high dword, it will be regarded as
  106. * invalid.
  107. */
  108. static void pci_read_bases ( struct pci_device *pci ) {
  109. unsigned long bar;
  110. int reg;
  111. for ( reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4 ) {
  112. bar = pci_bar ( pci, reg );
  113. if ( bar & PCI_BASE_ADDRESS_SPACE_IO ) {
  114. if ( ! pci->ioaddr )
  115. pci->ioaddr =
  116. ( bar & PCI_BASE_ADDRESS_IO_MASK );
  117. } else {
  118. if ( ! pci->membase )
  119. pci->membase =
  120. ( bar & PCI_BASE_ADDRESS_MEM_MASK );
  121. /* Skip next BAR if 64-bit */
  122. if ( bar & PCI_BASE_ADDRESS_MEM_TYPE_64 )
  123. reg += 4;
  124. }
  125. }
  126. }
  127. /**
  128. * Enable PCI device
  129. *
  130. * @v pci PCI device
  131. *
  132. * Set device to be a busmaster in case BIOS neglected to do so. Also
  133. * adjust PCI latency timer to a reasonable value, 32.
  134. */
  135. void adjust_pci_device ( struct pci_device *pci ) {
  136. unsigned short new_command, pci_command;
  137. unsigned char pci_latency;
  138. pci_read_config_word ( pci, PCI_COMMAND, &pci_command );
  139. new_command = pci_command | PCI_COMMAND_MASTER | PCI_COMMAND_IO;
  140. if ( pci_command != new_command ) {
  141. DBG ( "PCI BIOS has not enabled device %02x:%02x.%x! "
  142. "Updating PCI command %04x->%04x\n", pci->bus,
  143. PCI_SLOT ( pci->devfn ), PCI_FUNC ( pci->devfn ),
  144. pci_command, new_command );
  145. pci_write_config_word ( pci, PCI_COMMAND, new_command );
  146. }
  147. pci_read_config_byte ( pci, PCI_LATENCY_TIMER, &pci_latency);
  148. if ( pci_latency < 32 ) {
  149. DBG ( "PCI device %02x:%02x.%x latency timer is unreasonably "
  150. "low at %d. Setting to 32.\n", pci->bus,
  151. PCI_SLOT ( pci->devfn ), PCI_FUNC ( pci->devfn ),
  152. pci_latency );
  153. pci_write_config_byte ( pci, PCI_LATENCY_TIMER, 32);
  154. }
  155. }
  156. /**
  157. * Probe a PCI device
  158. *
  159. * @v pci PCI device
  160. * @ret rc Return status code
  161. *
  162. * Searches for a driver for the PCI device. If a driver is found,
  163. * its probe() routine is called.
  164. */
  165. static int pci_probe ( struct pci_device *pci ) {
  166. struct pci_driver *driver;
  167. struct pci_device_id *id;
  168. unsigned int i;
  169. int rc;
  170. DBG ( "Adding PCI device %02x:%02x.%x (%04x:%04x mem %lx io %lx "
  171. "irq %d)\n", pci->bus, PCI_SLOT ( pci->devfn ),
  172. PCI_FUNC ( pci->devfn ), pci->vendor, pci->device,
  173. pci->membase, pci->ioaddr, pci->irq );
  174. for ( driver = pci_drivers ; driver < pci_drivers_end ; driver++ ) {
  175. for ( i = 0 ; i < driver->id_count ; i++ ) {
  176. id = &driver->ids[i];
  177. if ( ( id->vendor != PCI_ANY_ID ) &&
  178. ( id->vendor != pci->vendor ) )
  179. continue;
  180. if ( ( id->device != PCI_ANY_ID ) &&
  181. ( id->device != pci->device ) )
  182. continue;
  183. pci->driver = driver;
  184. pci->driver_name = id->name;
  185. DBG ( "...using driver %s\n", pci->driver_name );
  186. if ( ( rc = driver->probe ( pci, id ) ) != 0 ) {
  187. DBG ( "......probe failed\n" );
  188. continue;
  189. }
  190. return 0;
  191. }
  192. }
  193. DBG ( "...no driver found\n" );
  194. return -ENOTTY;
  195. }
  196. /**
  197. * Remove a PCI device
  198. *
  199. * @v pci PCI device
  200. */
  201. static void pci_remove ( struct pci_device *pci ) {
  202. pci->driver->remove ( pci );
  203. DBG ( "Removed PCI device %02x:%02x.%x\n", pci->bus,
  204. PCI_SLOT ( pci->devfn ), PCI_FUNC ( pci->devfn ) );
  205. }
  206. /**
  207. * Probe PCI root bus
  208. *
  209. * @v rootdev PCI bus root device
  210. *
  211. * Scans the PCI bus for devices and registers all devices it can
  212. * find.
  213. */
  214. static int pcibus_probe ( struct root_device *rootdev ) {
  215. struct pci_device *pci = NULL;
  216. unsigned int max_bus;
  217. unsigned int bus;
  218. unsigned int devfn;
  219. uint8_t hdrtype = 0;
  220. uint32_t tmp;
  221. int rc;
  222. max_bus = pci_max_bus();
  223. for ( bus = 0 ; bus <= max_bus ; bus++ ) {
  224. for ( devfn = 0 ; devfn <= 0xff ; devfn++ ) {
  225. /* Allocate struct pci_device */
  226. if ( ! pci )
  227. pci = malloc ( sizeof ( *pci ) );
  228. if ( ! pci ) {
  229. rc = -ENOMEM;
  230. goto err;
  231. }
  232. memset ( pci, 0, sizeof ( *pci ) );
  233. pci->bus = bus;
  234. pci->devfn = devfn;
  235. /* Skip all but the first function on
  236. * non-multifunction cards
  237. */
  238. if ( PCI_FUNC ( devfn ) == 0 ) {
  239. pci_read_config_byte ( pci, PCI_HEADER_TYPE,
  240. &hdrtype );
  241. } else if ( ! ( hdrtype & 0x80 ) ) {
  242. continue;
  243. }
  244. /* Check for physical device presence */
  245. pci_read_config_dword ( pci, PCI_VENDOR_ID, &tmp );
  246. if ( ( tmp == 0xffffffff ) || ( tmp == 0 ) )
  247. continue;
  248. /* Populate struct pci_device */
  249. pci->vendor = ( tmp & 0xffff );
  250. pci->device = ( tmp >> 16 );
  251. pci_read_config_dword ( pci, PCI_REVISION, &tmp );
  252. pci->class = ( tmp >> 8 );
  253. pci_read_config_byte ( pci, PCI_INTERRUPT_LINE,
  254. &pci->irq );
  255. pci_read_bases ( pci );
  256. /* Add to device hierarchy */
  257. snprintf ( pci->dev.name, sizeof ( pci->dev.name ),
  258. "PCI%02x:%02x.%x", bus,
  259. PCI_SLOT ( devfn ), PCI_FUNC ( devfn ) );
  260. pci->dev.desc.bus_type = BUS_TYPE_PCI;
  261. pci->dev.desc.pci.busdevfn = PCI_BUSDEVFN (bus, devfn);
  262. pci->dev.desc.pci.vendor = pci->vendor;
  263. pci->dev.desc.pci.device = pci->device;
  264. pci->dev.parent = &rootdev->dev;
  265. list_add ( &pci->dev.siblings, &rootdev->dev.children);
  266. INIT_LIST_HEAD ( &pci->dev.children );
  267. /* Look for a driver */
  268. if ( pci_probe ( pci ) == 0 ) {
  269. /* pcidev registered, we can drop our ref */
  270. pci = NULL;
  271. } else {
  272. /* Not registered; re-use struct pci_device */
  273. list_del ( &pci->dev.siblings );
  274. }
  275. }
  276. }
  277. free ( pci );
  278. return 0;
  279. err:
  280. free ( pci );
  281. pcibus_remove ( rootdev );
  282. return rc;
  283. }
  284. /**
  285. * Remove PCI root bus
  286. *
  287. * @v rootdev PCI bus root device
  288. */
  289. static void pcibus_remove ( struct root_device *rootdev ) {
  290. struct pci_device *pci;
  291. struct pci_device *tmp;
  292. list_for_each_entry_safe ( pci, tmp, &rootdev->dev.children,
  293. dev.siblings ) {
  294. pci_remove ( pci );
  295. list_del ( &pci->dev.siblings );
  296. free ( pci );
  297. }
  298. }
  299. /** PCI bus root device driver */
  300. static struct root_driver pci_root_driver = {
  301. .probe = pcibus_probe,
  302. .remove = pcibus_remove,
  303. };
  304. /** PCI bus root device */
  305. struct root_device pci_root_device __root_device = {
  306. .dev = { .name = "PCI" },
  307. .driver = &pci_root_driver,
  308. };