Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

efi_pci.c 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /*
  2. * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. *
  19. * You can also choose to distribute this program under the terms of
  20. * the Unmodified Binary Distribution Licence (as given in the file
  21. * COPYING.UBDL), provided that you have satisfied its requirements.
  22. */
  23. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. #include <stdlib.h>
  25. #include <errno.h>
  26. #include <ipxe/pci.h>
  27. #include <ipxe/efi/efi.h>
  28. #include <ipxe/efi/efi_pci.h>
  29. #include <ipxe/efi/efi_driver.h>
  30. #include <ipxe/efi/Protocol/PciIo.h>
  31. #include <ipxe/efi/Protocol/PciRootBridgeIo.h>
  32. /** @file
  33. *
  34. * iPXE PCI I/O API for EFI
  35. *
  36. */
  37. /* Disambiguate the various error causes */
  38. #define EINFO_EEFI_PCI \
  39. __einfo_uniqify ( EINFO_EPLATFORM, 0x01, \
  40. "Could not open PCI I/O protocol" )
  41. #define EINFO_EEFI_PCI_NOT_PCI \
  42. __einfo_platformify ( EINFO_EEFI_PCI, EFI_UNSUPPORTED, \
  43. "Not a PCI device" )
  44. #define EEFI_PCI_NOT_PCI __einfo_error ( EINFO_EEFI_PCI_NOT_PCI )
  45. #define EINFO_EEFI_PCI_IN_USE \
  46. __einfo_platformify ( EINFO_EEFI_PCI, EFI_ACCESS_DENIED, \
  47. "PCI device already has a driver" )
  48. #define EEFI_PCI_IN_USE __einfo_error ( EINFO_EEFI_PCI_IN_USE )
  49. #define EEFI_PCI( efirc ) \
  50. EPLATFORM ( EINFO_EEFI_PCI, efirc, \
  51. EEFI_PCI_NOT_PCI, EEFI_PCI_IN_USE )
  52. /******************************************************************************
  53. *
  54. * iPXE PCI API
  55. *
  56. ******************************************************************************
  57. */
  58. /** PCI root bridge I/O protocol */
  59. static EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *efipci;
  60. EFI_REQUEST_PROTOCOL ( EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL, &efipci );
  61. static unsigned long efipci_address ( struct pci_device *pci,
  62. unsigned long location ) {
  63. return EFI_PCI_ADDRESS ( PCI_BUS ( pci->busdevfn ),
  64. PCI_SLOT ( pci->busdevfn ),
  65. PCI_FUNC ( pci->busdevfn ),
  66. EFIPCI_OFFSET ( location ) );
  67. }
  68. int efipci_read ( struct pci_device *pci, unsigned long location,
  69. void *value ) {
  70. EFI_STATUS efirc;
  71. int rc;
  72. if ( ! efipci )
  73. return -ENOTSUP;
  74. if ( ( efirc = efipci->Pci.Read ( efipci, EFIPCI_WIDTH ( location ),
  75. efipci_address ( pci, location ), 1,
  76. value ) ) != 0 ) {
  77. rc = -EEFI ( efirc );
  78. DBG ( "EFIPCI config read from " PCI_FMT " offset %02lx "
  79. "failed: %s\n", PCI_ARGS ( pci ),
  80. EFIPCI_OFFSET ( location ), strerror ( rc ) );
  81. return -EIO;
  82. }
  83. return 0;
  84. }
  85. int efipci_write ( struct pci_device *pci, unsigned long location,
  86. unsigned long value ) {
  87. EFI_STATUS efirc;
  88. int rc;
  89. if ( ! efipci )
  90. return -ENOTSUP;
  91. if ( ( efirc = efipci->Pci.Write ( efipci, EFIPCI_WIDTH ( location ),
  92. efipci_address ( pci, location ), 1,
  93. &value ) ) != 0 ) {
  94. rc = -EEFI ( efirc );
  95. DBG ( "EFIPCI config write to " PCI_FMT " offset %02lx "
  96. "failed: %s\n", PCI_ARGS ( pci ),
  97. EFIPCI_OFFSET ( location ), strerror ( rc ) );
  98. return -EIO;
  99. }
  100. return 0;
  101. }
  102. PROVIDE_PCIAPI_INLINE ( efi, pci_num_bus );
  103. PROVIDE_PCIAPI_INLINE ( efi, pci_read_config_byte );
  104. PROVIDE_PCIAPI_INLINE ( efi, pci_read_config_word );
  105. PROVIDE_PCIAPI_INLINE ( efi, pci_read_config_dword );
  106. PROVIDE_PCIAPI_INLINE ( efi, pci_write_config_byte );
  107. PROVIDE_PCIAPI_INLINE ( efi, pci_write_config_word );
  108. PROVIDE_PCIAPI_INLINE ( efi, pci_write_config_dword );
  109. /******************************************************************************
  110. *
  111. * EFI PCI device instantiation
  112. *
  113. ******************************************************************************
  114. */
  115. /**
  116. * Open EFI PCI device
  117. *
  118. * @v device EFI device handle
  119. * @v attributes Protocol opening attributes
  120. * @v pci PCI device to fill in
  121. * @ret rc Return status code
  122. */
  123. int efipci_open ( EFI_HANDLE device, UINT32 attributes,
  124. struct pci_device *pci ) {
  125. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  126. union {
  127. EFI_PCI_IO_PROTOCOL *pci_io;
  128. void *interface;
  129. } pci_io;
  130. UINTN pci_segment, pci_bus, pci_dev, pci_fn;
  131. EFI_STATUS efirc;
  132. int rc;
  133. /* See if device is a PCI device */
  134. if ( ( efirc = bs->OpenProtocol ( device, &efi_pci_io_protocol_guid,
  135. &pci_io.interface, efi_image_handle,
  136. device, attributes ) ) != 0 ) {
  137. rc = -EEFI_PCI ( efirc );
  138. DBGCP ( device, "EFIPCI %s cannot open PCI protocols: %s\n",
  139. efi_handle_name ( device ), strerror ( rc ) );
  140. goto err_open_protocol;
  141. }
  142. /* Get PCI bus:dev.fn address */
  143. if ( ( efirc = pci_io.pci_io->GetLocation ( pci_io.pci_io, &pci_segment,
  144. &pci_bus, &pci_dev,
  145. &pci_fn ) ) != 0 ) {
  146. rc = -EEFI ( efirc );
  147. DBGC ( device, "EFIPCI %s could not get PCI location: %s\n",
  148. efi_handle_name ( device ), strerror ( rc ) );
  149. goto err_get_location;
  150. }
  151. DBGC2 ( device, "EFIPCI %s is PCI %04lx:%02lx:%02lx.%lx\n",
  152. efi_handle_name ( device ), ( ( unsigned long ) pci_segment ),
  153. ( ( unsigned long ) pci_bus ), ( ( unsigned long ) pci_dev ),
  154. ( ( unsigned long ) pci_fn ) );
  155. /* Try to enable I/O cycles, memory cycles, and bus mastering.
  156. * Some platforms will 'helpfully' report errors if these bits
  157. * can't be enabled (for example, if the card doesn't actually
  158. * support I/O cycles). Work around any such platforms by
  159. * enabling bits individually and simply ignoring any errors.
  160. */
  161. pci_io.pci_io->Attributes ( pci_io.pci_io,
  162. EfiPciIoAttributeOperationEnable,
  163. EFI_PCI_IO_ATTRIBUTE_IO, NULL );
  164. pci_io.pci_io->Attributes ( pci_io.pci_io,
  165. EfiPciIoAttributeOperationEnable,
  166. EFI_PCI_IO_ATTRIBUTE_MEMORY, NULL );
  167. pci_io.pci_io->Attributes ( pci_io.pci_io,
  168. EfiPciIoAttributeOperationEnable,
  169. EFI_PCI_IO_ATTRIBUTE_BUS_MASTER, NULL );
  170. /* Populate PCI device */
  171. pci_init ( pci, PCI_BUSDEVFN ( pci_bus, pci_dev, pci_fn ) );
  172. if ( ( rc = pci_read_config ( pci ) ) != 0 ) {
  173. DBGC ( device, "EFIPCI %s cannot read PCI configuration: %s\n",
  174. efi_handle_name ( device ), strerror ( rc ) );
  175. goto err_pci_read_config;
  176. }
  177. return 0;
  178. err_pci_read_config:
  179. err_get_location:
  180. bs->CloseProtocol ( device, &efi_pci_io_protocol_guid,
  181. efi_image_handle, device );
  182. err_open_protocol:
  183. return rc;
  184. }
  185. /**
  186. * Close EFI PCI device
  187. *
  188. * @v device EFI device handle
  189. */
  190. void efipci_close ( EFI_HANDLE device ) {
  191. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  192. bs->CloseProtocol ( device, &efi_pci_io_protocol_guid,
  193. efi_image_handle, device );
  194. }
  195. /**
  196. * Get EFI PCI device information
  197. *
  198. * @v device EFI device handle
  199. * @v pci PCI device to fill in
  200. * @ret rc Return status code
  201. */
  202. int efipci_info ( EFI_HANDLE device, struct pci_device *pci ) {
  203. int rc;
  204. /* Open PCI device, if possible */
  205. if ( ( rc = efipci_open ( device, EFI_OPEN_PROTOCOL_GET_PROTOCOL,
  206. pci ) ) != 0 )
  207. return rc;
  208. /* Close PCI device */
  209. efipci_close ( device );
  210. return 0;
  211. }
  212. /******************************************************************************
  213. *
  214. * EFI PCI driver
  215. *
  216. ******************************************************************************
  217. */
  218. /**
  219. * Check to see if driver supports a device
  220. *
  221. * @v device EFI device handle
  222. * @ret rc Return status code
  223. */
  224. static int efipci_supported ( EFI_HANDLE device ) {
  225. struct pci_device pci;
  226. int rc;
  227. /* Get PCI device information */
  228. if ( ( rc = efipci_info ( device, &pci ) ) != 0 )
  229. return rc;
  230. /* Look for a driver */
  231. if ( ( rc = pci_find_driver ( &pci ) ) != 0 ) {
  232. DBGCP ( device, "EFIPCI %s has no driver\n",
  233. efi_handle_name ( device ) );
  234. return rc;
  235. }
  236. DBGC ( device, "EFIPCI %s has driver \"%s\"\n",
  237. efi_handle_name ( device ), pci.id->name );
  238. return 0;
  239. }
  240. /**
  241. * Attach driver to device
  242. *
  243. * @v efidev EFI device
  244. * @ret rc Return status code
  245. */
  246. static int efipci_start ( struct efi_device *efidev ) {
  247. EFI_HANDLE device = efidev->device;
  248. struct pci_device *pci;
  249. int rc;
  250. /* Allocate PCI device */
  251. pci = zalloc ( sizeof ( *pci ) );
  252. if ( ! pci ) {
  253. rc = -ENOMEM;
  254. goto err_alloc;
  255. }
  256. /* Open PCI device */
  257. if ( ( rc = efipci_open ( device, ( EFI_OPEN_PROTOCOL_BY_DRIVER |
  258. EFI_OPEN_PROTOCOL_EXCLUSIVE ),
  259. pci ) ) != 0 ) {
  260. DBGC ( device, "EFIPCI %s could not open PCI device: %s\n",
  261. efi_handle_name ( device ), strerror ( rc ) );
  262. DBGC_EFI_OPENERS ( device, device, &efi_pci_io_protocol_guid );
  263. goto err_open;
  264. }
  265. /* Find driver */
  266. if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
  267. DBGC ( device, "EFIPCI %s has no driver\n",
  268. efi_handle_name ( device ) );
  269. goto err_find_driver;
  270. }
  271. /* Mark PCI device as a child of the EFI device */
  272. pci->dev.parent = &efidev->dev;
  273. list_add ( &pci->dev.siblings, &efidev->dev.children );
  274. /* Probe driver */
  275. if ( ( rc = pci_probe ( pci ) ) != 0 ) {
  276. DBGC ( device, "EFIPCI %s could not probe driver \"%s\": %s\n",
  277. efi_handle_name ( device ), pci->id->name,
  278. strerror ( rc ) );
  279. goto err_probe;
  280. }
  281. DBGC ( device, "EFIPCI %s using driver \"%s\"\n",
  282. efi_handle_name ( device ), pci->id->name );
  283. efidev_set_drvdata ( efidev, pci );
  284. return 0;
  285. pci_remove ( pci );
  286. err_probe:
  287. list_del ( &pci->dev.siblings );
  288. err_find_driver:
  289. efipci_close ( device );
  290. err_open:
  291. free ( pci );
  292. err_alloc:
  293. return rc;
  294. }
  295. /**
  296. * Detach driver from device
  297. *
  298. * @v efidev EFI device
  299. */
  300. static void efipci_stop ( struct efi_device *efidev ) {
  301. struct pci_device *pci = efidev_get_drvdata ( efidev );
  302. EFI_HANDLE device = efidev->device;
  303. pci_remove ( pci );
  304. list_del ( &pci->dev.siblings );
  305. efipci_close ( device );
  306. free ( pci );
  307. }
  308. /** EFI PCI driver */
  309. struct efi_driver efipci_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
  310. .name = "PCI",
  311. .supported = efipci_supported,
  312. .start = efipci_start,
  313. .stop = efipci_stop,
  314. };