You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

efi_pci.c 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  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 %p %s cannot open PCI protocols: %s\n",
  139. device, 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 %p %s could not get PCI location: %s\n",
  148. device, efi_handle_name ( device ), strerror ( rc ) );
  149. goto err_get_location;
  150. }
  151. DBGC2 ( device, "EFIPCI %p %s is PCI %04lx:%02lx:%02lx.%lx\n", device,
  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 %p %s cannot read PCI configuration: "
  174. "%s\n", device, efi_handle_name ( device ),
  175. strerror ( rc ) );
  176. goto err_pci_read_config;
  177. }
  178. return 0;
  179. err_pci_read_config:
  180. err_get_location:
  181. bs->CloseProtocol ( device, &efi_pci_io_protocol_guid,
  182. efi_image_handle, device );
  183. err_open_protocol:
  184. return rc;
  185. }
  186. /**
  187. * Close EFI PCI device
  188. *
  189. * @v device EFI device handle
  190. */
  191. void efipci_close ( EFI_HANDLE device ) {
  192. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  193. bs->CloseProtocol ( device, &efi_pci_io_protocol_guid,
  194. efi_image_handle, device );
  195. }
  196. /**
  197. * Get EFI PCI device information
  198. *
  199. * @v device EFI device handle
  200. * @v pci PCI device to fill in
  201. * @ret rc Return status code
  202. */
  203. int efipci_info ( EFI_HANDLE device, struct pci_device *pci ) {
  204. int rc;
  205. /* Open PCI device, if possible */
  206. if ( ( rc = efipci_open ( device, EFI_OPEN_PROTOCOL_GET_PROTOCOL,
  207. pci ) ) != 0 )
  208. return rc;
  209. /* Close PCI device */
  210. efipci_close ( device );
  211. return 0;
  212. }
  213. /******************************************************************************
  214. *
  215. * EFI PCI driver
  216. *
  217. ******************************************************************************
  218. */
  219. /**
  220. * Check to see if driver supports a device
  221. *
  222. * @v device EFI device handle
  223. * @ret rc Return status code
  224. */
  225. static int efipci_supported ( EFI_HANDLE device ) {
  226. struct pci_device pci;
  227. int rc;
  228. /* Get PCI device information */
  229. if ( ( rc = efipci_info ( device, &pci ) ) != 0 )
  230. return rc;
  231. /* Look for a driver */
  232. if ( ( rc = pci_find_driver ( &pci ) ) != 0 ) {
  233. DBGCP ( device, "EFIPCI %p %s has no driver\n",
  234. device, efi_handle_name ( device ) );
  235. return rc;
  236. }
  237. DBGC ( device, "EFIPCI %p %s has driver \"%s\"\n",
  238. device, efi_handle_name ( device ), pci.id->name );
  239. return 0;
  240. }
  241. /**
  242. * Attach driver to device
  243. *
  244. * @v efidev EFI device
  245. * @ret rc Return status code
  246. */
  247. static int efipci_start ( struct efi_device *efidev ) {
  248. EFI_HANDLE device = efidev->device;
  249. struct pci_device *pci;
  250. int rc;
  251. /* Allocate PCI device */
  252. pci = zalloc ( sizeof ( *pci ) );
  253. if ( ! pci ) {
  254. rc = -ENOMEM;
  255. goto err_alloc;
  256. }
  257. /* Open PCI device */
  258. if ( ( rc = efipci_open ( device, ( EFI_OPEN_PROTOCOL_BY_DRIVER |
  259. EFI_OPEN_PROTOCOL_EXCLUSIVE ),
  260. pci ) ) != 0 ) {
  261. DBGC ( device, "EFIPCI %p %s could not open PCI device: %s\n",
  262. device, efi_handle_name ( device ), strerror ( rc ) );
  263. DBGC_EFI_OPENERS ( device, device, &efi_pci_io_protocol_guid );
  264. goto err_open;
  265. }
  266. /* Find driver */
  267. if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
  268. DBGC ( device, "EFIPCI %p %s has no driver\n",
  269. device, efi_handle_name ( device ) );
  270. goto err_find_driver;
  271. }
  272. /* Mark PCI device as a child of the EFI device */
  273. pci->dev.parent = &efidev->dev;
  274. list_add ( &pci->dev.siblings, &efidev->dev.children );
  275. /* Probe driver */
  276. if ( ( rc = pci_probe ( pci ) ) != 0 ) {
  277. DBGC ( device, "EFIPCI %p %s could not probe driver \"%s\": "
  278. "%s\n", device, efi_handle_name ( device ),
  279. pci->id->name, strerror ( rc ) );
  280. goto err_probe;
  281. }
  282. DBGC ( device, "EFIPCI %p %s using driver \"%s\"\n",
  283. device, efi_handle_name ( device ), pci->id->name );
  284. efidev_set_drvdata ( efidev, pci );
  285. return 0;
  286. pci_remove ( pci );
  287. err_probe:
  288. list_del ( &pci->dev.siblings );
  289. err_find_driver:
  290. efipci_close ( device );
  291. err_open:
  292. free ( pci );
  293. err_alloc:
  294. return rc;
  295. }
  296. /**
  297. * Detach driver from device
  298. *
  299. * @v efidev EFI device
  300. */
  301. static void efipci_stop ( struct efi_device *efidev ) {
  302. struct pci_device *pci = efidev_get_drvdata ( efidev );
  303. EFI_HANDLE device = efidev->device;
  304. pci_remove ( pci );
  305. list_del ( &pci->dev.siblings );
  306. efipci_close ( device );
  307. free ( pci );
  308. }
  309. /** EFI PCI driver */
  310. struct efi_driver efipci_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
  311. .name = "PCI",
  312. .supported = efipci_supported,
  313. .start = efipci_start,
  314. .stop = efipci_stop,
  315. };