Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

efi_block.c 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  1. /*
  2. * Copyright (C) 2016 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. /**
  25. * @file
  26. *
  27. * EFI block device protocols
  28. *
  29. */
  30. #include <stddef.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <errno.h>
  34. #include <ipxe/refcnt.h>
  35. #include <ipxe/list.h>
  36. #include <ipxe/uri.h>
  37. #include <ipxe/interface.h>
  38. #include <ipxe/blockdev.h>
  39. #include <ipxe/xfer.h>
  40. #include <ipxe/open.h>
  41. #include <ipxe/retry.h>
  42. #include <ipxe/timer.h>
  43. #include <ipxe/process.h>
  44. #include <ipxe/sanboot.h>
  45. #include <ipxe/iso9660.h>
  46. #include <ipxe/efi/efi.h>
  47. #include <ipxe/efi/Protocol/BlockIo.h>
  48. #include <ipxe/efi/Protocol/SimpleFileSystem.h>
  49. #include <ipxe/efi/efi_driver.h>
  50. #include <ipxe/efi/efi_strings.h>
  51. #include <ipxe/efi/efi_snp.h>
  52. #include <ipxe/efi/efi_utils.h>
  53. #include <ipxe/efi/efi_block.h>
  54. /** Timeout for EFI block device commands (in ticks) */
  55. #define EFI_BLOCK_TIMEOUT ( 15 * TICKS_PER_SEC )
  56. /** Boot filename */
  57. static wchar_t efi_block_boot_filename[] = EFI_REMOVABLE_MEDIA_FILE_NAME;
  58. /** iPXE EFI block device vendor device path GUID */
  59. #define IPXE_BLOCK_DEVICE_PATH_GUID \
  60. { 0x8998b594, 0xf531, 0x4e87, \
  61. { 0x8b, 0xdf, 0x8f, 0x88, 0x54, 0x3e, 0x99, 0xd4 } }
  62. /** iPXE EFI block device vendor device path GUID */
  63. static EFI_GUID ipxe_block_device_path_guid
  64. = IPXE_BLOCK_DEVICE_PATH_GUID;
  65. /** An iPXE EFI block device vendor device path */
  66. struct efi_block_vendor_path {
  67. /** Generic vendor device path */
  68. VENDOR_DEVICE_PATH vendor;
  69. /** Block device URI */
  70. CHAR16 uri[0];
  71. } __attribute__ (( packed ));
  72. /** An EFI block device */
  73. struct efi_block {
  74. /** Reference count */
  75. struct refcnt refcnt;
  76. /** List of all registered block devices */
  77. struct list_head list;
  78. /** Block device URI */
  79. struct uri *uri;
  80. /** Drive number */
  81. unsigned int drive;
  82. /** Underlying block device interface */
  83. struct interface intf;
  84. /** Current device status */
  85. int block_rc;
  86. /** Raw block device capacity */
  87. struct block_device_capacity capacity;
  88. /** Block size shift
  89. *
  90. * To allow for emulation of CD-ROM access, this represents
  91. * the left-shift required to translate from EFI I/O blocks to
  92. * underlying blocks.
  93. *
  94. * Note that the LogicalBlocksPerPhysicalBlock field in
  95. * EFI_BLOCK_IO_MEDIA is unable to encapsulate this
  96. * information, since it does not allow us to describe a
  97. * situation in which there are multiple "physical"
  98. * (i.e. underlying) blocks per logical (i.e. exposed) block.
  99. */
  100. unsigned int blksize_shift;
  101. /** EFI handle */
  102. EFI_HANDLE handle;
  103. /** Media descriptor */
  104. EFI_BLOCK_IO_MEDIA media;
  105. /** Block I/O protocol */
  106. EFI_BLOCK_IO_PROTOCOL block_io;
  107. /** Device path protocol */
  108. EFI_DEVICE_PATH_PROTOCOL *path;
  109. /** Command interface */
  110. struct interface command;
  111. /** Command timeout timer */
  112. struct retry_timer timer;
  113. /** Command status */
  114. int command_rc;
  115. };
  116. /**
  117. * Free EFI block device
  118. *
  119. * @v refcnt Reference count
  120. */
  121. static void efi_block_free ( struct refcnt *refcnt ) {
  122. struct efi_block *block =
  123. container_of ( refcnt, struct efi_block, refcnt );
  124. assert ( ! timer_running ( &block->timer ) );
  125. uri_put ( block->uri );
  126. free ( block->path );
  127. free ( block );
  128. }
  129. /** List of EFI block devices */
  130. static LIST_HEAD ( efi_block_devices );
  131. /**
  132. * Find EFI block device
  133. *
  134. * @v drive Drive number
  135. * @ret block Block device, or NULL if not found
  136. */
  137. static struct efi_block * efi_block_find ( unsigned int drive ) {
  138. struct efi_block *block;
  139. list_for_each_entry ( block, &efi_block_devices, list ) {
  140. if ( block->drive == drive )
  141. return block;
  142. }
  143. return NULL;
  144. }
  145. /**
  146. * Close EFI block device command
  147. *
  148. * @v block Block device
  149. * @v rc Reason for close
  150. */
  151. static void efi_block_cmd_close ( struct efi_block *block, int rc ) {
  152. /* Stop timer */
  153. stop_timer ( &block->timer );
  154. /* Restart interface */
  155. intf_restart ( &block->command, rc );
  156. /* Record command status */
  157. block->command_rc = rc;
  158. }
  159. /**
  160. * Record EFI block device capacity
  161. *
  162. * @v block Block device
  163. * @v capacity Block device capacity
  164. */
  165. static void efi_block_cmd_capacity ( struct efi_block *block,
  166. struct block_device_capacity *capacity ) {
  167. /* Record raw capacity information */
  168. memcpy ( &block->capacity, capacity, sizeof ( block->capacity ) );
  169. }
  170. /** EFI block device command interface operations */
  171. static struct interface_operation efi_block_cmd_op[] = {
  172. INTF_OP ( intf_close, struct efi_block *, efi_block_cmd_close ),
  173. INTF_OP ( block_capacity, struct efi_block *, efi_block_cmd_capacity ),
  174. };
  175. /** EFI block device command interface descriptor */
  176. static struct interface_descriptor efi_block_cmd_desc =
  177. INTF_DESC ( struct efi_block, command, efi_block_cmd_op );
  178. /**
  179. * Handle EFI block device command timeout
  180. *
  181. * @v retry Retry timer
  182. */
  183. static void efi_block_cmd_expired ( struct retry_timer *timer,
  184. int over __unused ) {
  185. struct efi_block *block =
  186. container_of ( timer, struct efi_block, timer );
  187. efi_block_cmd_close ( block, -ETIMEDOUT );
  188. }
  189. /**
  190. * Restart EFI block device interface
  191. *
  192. * @v block Block device
  193. * @v rc Reason for restart
  194. */
  195. static void efi_block_restart ( struct efi_block *block, int rc ) {
  196. /* Restart block device interface */
  197. intf_nullify ( &block->command ); /* avoid potential loops */
  198. intf_restart ( &block->intf, rc );
  199. /* Close any outstanding command */
  200. efi_block_cmd_close ( block, rc );
  201. /* Record device error */
  202. block->block_rc = rc;
  203. }
  204. /**
  205. * (Re)open EFI block device
  206. *
  207. * @v block Block device
  208. * @ret rc Return status code
  209. *
  210. * This function will block until the device is available.
  211. */
  212. static int efi_block_reopen ( struct efi_block *block ) {
  213. int rc;
  214. /* Close any outstanding command and restart interface */
  215. efi_block_restart ( block, -ECONNRESET );
  216. /* Mark device as being not yet open */
  217. block->block_rc = -EINPROGRESS;
  218. /* Open block device interface */
  219. if ( ( rc = xfer_open_uri ( &block->intf, block->uri ) ) != 0 ) {
  220. DBGC ( block, "EFIBLK %#02x could not (re)open URI: %s\n",
  221. block->drive, strerror ( rc ) );
  222. return rc;
  223. }
  224. /* Wait for device to become available */
  225. while ( block->block_rc == -EINPROGRESS ) {
  226. step();
  227. if ( xfer_window ( &block->intf ) != 0 ) {
  228. block->block_rc = 0;
  229. return 0;
  230. }
  231. }
  232. DBGC ( block, "EFIBLK %#02x never became available: %s\n",
  233. block->drive, strerror ( block->block_rc ) );
  234. return block->block_rc;
  235. }
  236. /**
  237. * Handle closure of underlying block device interface
  238. *
  239. * @v block Block device
  240. * @ret rc Reason for close
  241. */
  242. static void efi_block_close ( struct efi_block *block, int rc ) {
  243. /* Any closure is an error from our point of view */
  244. if ( rc == 0 )
  245. rc = -ENOTCONN;
  246. DBGC ( block, "EFIBLK %#02x went away: %s\n",
  247. block->drive, strerror ( rc ) );
  248. /* Close any outstanding command and restart interface */
  249. efi_block_restart ( block, rc );
  250. }
  251. /**
  252. * Check EFI block device flow control window
  253. *
  254. * @v block Block device
  255. */
  256. static size_t efi_block_window ( struct efi_block *block __unused ) {
  257. /* We are never ready to receive data via this interface.
  258. * This prevents objects that support both block and stream
  259. * interfaces from attempting to send us stream data.
  260. */
  261. return 0;
  262. }
  263. /** EFI block device interface operations */
  264. static struct interface_operation efi_block_op[] = {
  265. INTF_OP ( intf_close, struct efi_block *, efi_block_close ),
  266. INTF_OP ( xfer_window, struct efi_block *, efi_block_window ),
  267. };
  268. /** EFI block device interface descriptor */
  269. static struct interface_descriptor efi_block_desc =
  270. INTF_DESC ( struct efi_block, intf, efi_block_op );
  271. /** EFI block device command context */
  272. struct efi_block_command_context {
  273. /** Starting LBA (using EFI block numbering) */
  274. uint64_t lba;
  275. /** Data buffer */
  276. void *data;
  277. /** Length of data buffer */
  278. size_t len;
  279. /** Block device read/write operation (if any) */
  280. int ( * block_rw ) ( struct interface *control, struct interface *data,
  281. uint64_t lba, unsigned int count,
  282. userptr_t buffer, size_t len );
  283. };
  284. /**
  285. * Initiate EFI block device command
  286. *
  287. * @v block Block device
  288. * @v op Command operation
  289. * @v context Command context, or NULL if not required
  290. * @ret rc Return status code
  291. */
  292. static int efi_block_command ( struct efi_block *block,
  293. int ( * op ) ( struct efi_block *block,
  294. struct efi_block_command_context
  295. *context ),
  296. struct efi_block_command_context *context ) {
  297. int rc;
  298. /* Sanity check */
  299. assert ( ! timer_running ( &block->timer ) );
  300. /* Reopen block device if applicable */
  301. if ( ( block->block_rc != 0 ) &&
  302. ( ( rc = efi_block_reopen ( block ) ) != 0 ) ) {
  303. goto err_reopen;
  304. }
  305. /* Start expiry timer */
  306. start_timer_fixed ( &block->timer, EFI_BLOCK_TIMEOUT );
  307. /* Initiate block device operation */
  308. if ( ( rc = op ( block, context ) ) != 0 )
  309. goto err_op;
  310. /* Wait for command to complete */
  311. while ( timer_running ( &block->timer ) )
  312. step();
  313. /* Collect return status */
  314. rc = block->command_rc;
  315. return rc;
  316. err_op:
  317. stop_timer ( &block->timer );
  318. err_reopen:
  319. return rc;
  320. }
  321. /**
  322. * Initiate EFI block device read/write command
  323. *
  324. * @v block Block device
  325. * @v context Command context
  326. * @ret rc Return status code
  327. */
  328. static int efi_block_cmd_rw ( struct efi_block *block,
  329. struct efi_block_command_context *context ) {
  330. uint64_t lba;
  331. unsigned int count;
  332. int rc;
  333. /* Calculate underlying starting LBA and block count */
  334. if ( block->capacity.blksize == 0 ) {
  335. DBGC ( block, "EFIBLK %#02x has zero block size\n",
  336. block->drive );
  337. return -EINVAL;
  338. }
  339. lba = ( context->lba << block->blksize_shift );
  340. count = ( context->len / block->capacity.blksize );
  341. if ( ( count * block->capacity.blksize ) != context->len ) {
  342. DBGC ( block, "EFIBLK %#02x invalid read/write length %#zx\n",
  343. block->drive, context->len );
  344. return -EINVAL;
  345. }
  346. /* Initiate read/write command */
  347. if ( ( rc = context->block_rw ( &block->intf, &block->command, lba,
  348. count, virt_to_user ( context->data ),
  349. context->len ) ) != 0 ) {
  350. DBGC ( block, "EFIBLK %#02x could not initiate read/write: "
  351. "%s\n", block->drive, strerror ( rc ) );
  352. return rc;
  353. }
  354. return 0;
  355. }
  356. /**
  357. * Initiate EFI block device read capacity command
  358. *
  359. * @v block Block device
  360. * @v context Command context
  361. * @ret rc Return status code
  362. */
  363. static int efi_block_cmd_read_capacity ( struct efi_block *block,
  364. struct efi_block_command_context
  365. *context __unused ) {
  366. int rc;
  367. /* Initiate read capacity command */
  368. if ( ( rc = block_read_capacity ( &block->intf,
  369. &block->command ) ) != 0 ) {
  370. DBGC ( block, "EFIBLK %#02x could not read capacity: %s\n",
  371. block->drive, strerror ( rc ) );
  372. return rc;
  373. }
  374. return 0;
  375. }
  376. /**
  377. * Reset EFI block device
  378. *
  379. * @v block_io Block I/O protocol
  380. * @v verify Perform extended verification
  381. * @ret efirc EFI status code
  382. */
  383. static EFI_STATUS EFIAPI efi_block_io_reset ( EFI_BLOCK_IO_PROTOCOL *block_io,
  384. BOOLEAN verify __unused ) {
  385. struct efi_block *block =
  386. container_of ( block_io, struct efi_block, block_io );
  387. int rc;
  388. DBGC2 ( block, "EFIBLK %#02x reset\n", block->drive );
  389. /* Claim network devices for use by iPXE */
  390. efi_snp_claim();
  391. /* Reopen block device */
  392. if ( ( rc = efi_block_reopen ( block ) ) != 0 )
  393. goto err_reopen;
  394. err_reopen:
  395. efi_snp_release();
  396. return EFIRC ( rc );
  397. }
  398. /**
  399. * Read from EFI block device
  400. *
  401. * @v block_io Block I/O protocol
  402. * @v media Media identifier
  403. * @v lba Starting LBA
  404. * @v len Size of buffer
  405. * @v data Data buffer
  406. * @ret efirc EFI status code
  407. */
  408. static EFI_STATUS EFIAPI
  409. efi_block_io_read ( EFI_BLOCK_IO_PROTOCOL *block_io, UINT32 media __unused,
  410. EFI_LBA lba, UINTN len, VOID *data ) {
  411. struct efi_block *block =
  412. container_of ( block_io, struct efi_block, block_io );
  413. struct efi_block_command_context context = {
  414. .lba = lba,
  415. .data = data,
  416. .len = len,
  417. .block_rw = block_read,
  418. };
  419. int rc;
  420. DBGC2 ( block, "EFIBLK %#02x read LBA %#08llx to %p+%#08zx\n",
  421. block->drive, context.lba, context.data, context.len );
  422. /* Claim network devices for use by iPXE */
  423. efi_snp_claim();
  424. /* Issue read command */
  425. if ( ( rc = efi_block_command ( block, efi_block_cmd_rw,
  426. &context ) ) != 0 )
  427. goto err_command;
  428. err_command:
  429. efi_snp_release();
  430. return EFIRC ( rc );
  431. }
  432. /**
  433. * Write to EFI block device
  434. *
  435. * @v block_io Block I/O protocol
  436. * @v media Media identifier
  437. * @v lba Starting LBA
  438. * @v len Size of buffer
  439. * @v data Data buffer
  440. * @ret efirc EFI status code
  441. */
  442. static EFI_STATUS EFIAPI
  443. efi_block_io_write ( EFI_BLOCK_IO_PROTOCOL *block_io, UINT32 media __unused,
  444. EFI_LBA lba, UINTN len, VOID *data ) {
  445. struct efi_block *block =
  446. container_of ( block_io, struct efi_block, block_io );
  447. struct efi_block_command_context context = {
  448. .lba = lba,
  449. .data = data,
  450. .len = len,
  451. .block_rw = block_write,
  452. };
  453. int rc;
  454. DBGC2 ( block, "EFIBLK %#02x write LBA %#08llx from %p+%#08zx\n",
  455. block->drive, context.lba, context.data, context.len );
  456. /* Claim network devices for use by iPXE */
  457. efi_snp_claim();
  458. /* Issue write command */
  459. if ( ( rc = efi_block_command ( block, efi_block_cmd_rw,
  460. &context ) ) != 0 )
  461. goto err_command;
  462. err_command:
  463. efi_snp_release();
  464. return EFIRC ( rc );
  465. }
  466. /**
  467. * Flush data to EFI block device
  468. *
  469. * @v block_io Block I/O protocol
  470. * @ret efirc EFI status code
  471. */
  472. static EFI_STATUS EFIAPI
  473. efi_block_io_flush ( EFI_BLOCK_IO_PROTOCOL *block_io ) {
  474. struct efi_block *block =
  475. container_of ( block_io, struct efi_block, block_io );
  476. DBGC2 ( block, "EFIBLK %#02x flush\n", block->drive );
  477. /* Nothing to do */
  478. return 0;
  479. }
  480. /**
  481. * Create device path for EFI block device
  482. *
  483. * @v uri Block device URI
  484. * @v parent Parent device path
  485. * @ret path Device path, or NULL on failure
  486. *
  487. * The caller must eventually free() the device path.
  488. */
  489. static EFI_DEVICE_PATH_PROTOCOL *
  490. efi_block_path ( struct uri *uri, EFI_DEVICE_PATH_PROTOCOL *parent ) {
  491. EFI_DEVICE_PATH_PROTOCOL *path;
  492. struct efi_block_vendor_path *vendor;
  493. EFI_DEVICE_PATH_PROTOCOL *end;
  494. size_t prefix_len;
  495. size_t uri_len;
  496. size_t vendor_len;
  497. size_t len;
  498. char *uri_buf;
  499. /* Calculate device path lengths */
  500. end = efi_devpath_end ( parent );
  501. prefix_len = ( ( void * ) end - ( void * ) parent );
  502. uri_len = format_uri ( uri, NULL, 0 );
  503. vendor_len = ( sizeof ( *vendor ) +
  504. ( ( uri_len + 1 /* NUL */ ) * sizeof ( wchar_t ) ) );
  505. len = ( prefix_len + vendor_len + sizeof ( *end ) );
  506. /* Allocate device path and space for URI buffer */
  507. path = zalloc ( len + uri_len + 1 /* NUL */ );
  508. if ( ! path )
  509. return NULL;
  510. uri_buf = ( ( ( void * ) path ) + len );
  511. /* Construct device path */
  512. memcpy ( path, parent, prefix_len );
  513. vendor = ( ( ( void * ) path ) + prefix_len );
  514. vendor->vendor.Header.Type = HARDWARE_DEVICE_PATH;
  515. vendor->vendor.Header.SubType = HW_VENDOR_DP;
  516. vendor->vendor.Header.Length[0] = ( vendor_len & 0xff );
  517. vendor->vendor.Header.Length[1] = ( vendor_len >> 8 );
  518. memcpy ( &vendor->vendor.Guid, &ipxe_block_device_path_guid,
  519. sizeof ( vendor->vendor.Guid ) );
  520. format_uri ( uri, uri_buf, ( uri_len + 1 /* NUL */ ) );
  521. efi_snprintf ( vendor->uri, ( uri_len + 1 /* NUL */ ), "%s", uri_buf );
  522. end = ( ( ( void * ) vendor ) + vendor_len );
  523. end->Type = END_DEVICE_PATH_TYPE;
  524. end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
  525. end->Length[0] = sizeof ( *end );
  526. return path;
  527. }
  528. /**
  529. * Configure EFI block device as a CD-ROM, if applicable
  530. *
  531. * @v block Block device
  532. * @v scratch Scratch data area
  533. * @ret rc Return status code
  534. *
  535. * The EDK2 code will ignore CD-ROM devices with a block size other
  536. * than 2048. While we could require the user to configure the block
  537. * size appropriately, this is non-trivial and would impose a
  538. * substantial learning effort on the user. Instead, we perform
  539. * essentially the same auto-detection as under a BIOS SAN boot; if
  540. * the ISO9660 primary volume descriptor is present then we force a
  541. * block size of 2048 and map read/write requests appropriately.
  542. */
  543. static int efi_block_parse_iso9660 ( struct efi_block *block, void *scratch ) {
  544. static const struct iso9660_primary_descriptor_fixed primary_check = {
  545. .type = ISO9660_TYPE_PRIMARY,
  546. .id = ISO9660_ID,
  547. };
  548. struct iso9660_primary_descriptor *primary = scratch;
  549. struct efi_block_command_context context;
  550. unsigned int blksize;
  551. unsigned int blksize_shift;
  552. int rc;
  553. /* Calculate required blocksize shift for potential CD-ROM access */
  554. blksize = block->capacity.blksize;
  555. blksize_shift = 0;
  556. while ( blksize < ISO9660_BLKSIZE ) {
  557. blksize <<= 1;
  558. blksize_shift++;
  559. }
  560. if ( blksize > ISO9660_BLKSIZE ) {
  561. /* Cannot be a CD-ROM */
  562. return 0;
  563. }
  564. /* Read primary volume descriptor */
  565. memset ( &context, 0, sizeof ( context ) );
  566. context.lba = ( ISO9660_PRIMARY_LBA << blksize_shift );
  567. context.data = primary;
  568. context.len = ISO9660_BLKSIZE;
  569. context.block_rw = block_read;
  570. if ( ( rc = efi_block_command ( block, efi_block_cmd_rw,
  571. &context ) ) != 0 ) {
  572. DBGC ( block, "EFIBLK %#02x could not read ISO9660 primary "
  573. "volume descriptor: %s\n",
  574. block->drive, strerror ( rc ) );
  575. return rc;
  576. }
  577. /* Do nothing unless this is an ISO image */
  578. if ( memcmp ( primary, &primary_check, sizeof ( primary_check ) ) != 0 )
  579. return 0;
  580. DBGC ( block, "EFIBLK %#02x contains an ISO9660 filesystem; treating "
  581. "as CD-ROM\n", block->drive );
  582. block->blksize_shift = blksize_shift;
  583. return 0;
  584. }
  585. /**
  586. * Determing EFI block device capacity and block size
  587. *
  588. * @v block Block device
  589. * @ret rc Return status code
  590. */
  591. static int efi_block_capacity ( struct efi_block *block ) {
  592. size_t scratch_len;
  593. void *scratch;
  594. int rc;
  595. /* Read read block capacity */
  596. if ( ( rc = efi_block_command ( block, efi_block_cmd_read_capacity,
  597. NULL ) ) != 0 )
  598. goto err_read_capacity;
  599. block->blksize_shift = 0;
  600. /* Allocate scratch area */
  601. scratch_len = ( block->capacity.blksize );
  602. if ( scratch_len < ISO9660_BLKSIZE )
  603. scratch_len = ISO9660_BLKSIZE;
  604. scratch = malloc ( scratch_len );
  605. if ( ! scratch ) {
  606. rc = -ENOMEM;
  607. goto err_alloc;
  608. }
  609. /* Configure as a CD-ROM, if applicable */
  610. if ( ( rc = efi_block_parse_iso9660 ( block, scratch ) ) != 0 )
  611. goto err_parse_iso9660;
  612. /* Update media descriptor */
  613. block->media.BlockSize =
  614. ( block->capacity.blksize << block->blksize_shift );
  615. block->media.LastBlock =
  616. ( ( block->capacity.blocks >> block->blksize_shift ) - 1 );
  617. /* Success */
  618. rc = 0;
  619. err_parse_iso9660:
  620. free ( scratch );
  621. err_alloc:
  622. err_read_capacity:
  623. return rc;
  624. }
  625. /**
  626. * Connect all possible drivers to EFI block device
  627. *
  628. * @v block Block device
  629. */
  630. static void efi_block_connect ( struct efi_block *block ) {
  631. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  632. EFI_STATUS efirc;
  633. int rc;
  634. /* Try to connect all possible drivers to this block device */
  635. if ( ( efirc = bs->ConnectController ( block->handle, NULL,
  636. NULL, 1 ) ) != 0 ) {
  637. rc = -EEFI ( efirc );
  638. DBGC ( block, "EFIBLK %#02x could not connect drivers: %s\n",
  639. block->drive, strerror ( rc ) );
  640. /* May not be an error; may already be connected */
  641. }
  642. DBGC2 ( block, "EFIBLK %#02x supports protocols:\n", block->drive );
  643. DBGC2_EFI_PROTOCOLS ( block, block->handle );
  644. }
  645. /**
  646. * Hook EFI block device
  647. *
  648. * @v uri URI
  649. * @v drive Drive number
  650. * @ret drive Drive number, or negative error
  651. */
  652. static int efi_block_hook ( struct uri *uri, unsigned int drive ) {
  653. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  654. struct efi_snp_device *snpdev;
  655. struct efi_block *block;
  656. EFI_STATUS efirc;
  657. int rc;
  658. /* Check that drive number is not already in use */
  659. if ( efi_block_find ( drive ) ) {
  660. rc = -EADDRINUSE;
  661. goto err_in_use;
  662. }
  663. /* Allocate and initialise structure */
  664. block = zalloc ( sizeof ( *block ) );
  665. if ( ! block ) {
  666. rc = -ENOMEM;
  667. goto err_zalloc;
  668. }
  669. ref_init ( &block->refcnt, efi_block_free );
  670. intf_init ( &block->intf, &efi_block_desc, &block->refcnt );
  671. block->uri = uri_get ( uri );
  672. block->drive = drive;
  673. block->block_rc = -EINPROGRESS;
  674. block->media.MediaPresent = 1;
  675. block->media.LogicalBlocksPerPhysicalBlock = 1;
  676. block->block_io.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
  677. block->block_io.Media = &block->media;
  678. block->block_io.Reset = efi_block_io_reset;
  679. block->block_io.ReadBlocks = efi_block_io_read;
  680. block->block_io.WriteBlocks = efi_block_io_write;
  681. block->block_io.FlushBlocks = efi_block_io_flush;
  682. intf_init ( &block->command, &efi_block_cmd_desc, &block->refcnt );
  683. timer_init ( &block->timer, efi_block_cmd_expired, &block->refcnt );
  684. /* Find an appropriate parent device handle */
  685. snpdev = last_opened_snpdev();
  686. if ( ! snpdev ) {
  687. DBGC ( block, "EFIBLK %#02x could not identify SNP device\n",
  688. block->drive );
  689. rc = -ENODEV;
  690. goto err_no_snpdev;
  691. }
  692. /* Construct device path */
  693. block->path = efi_block_path ( block->uri, snpdev->path );
  694. if ( ! block->path ) {
  695. rc = -ENOMEM;
  696. goto err_path;
  697. }
  698. DBGC ( block, "EFIBLK %#02x has device path %s\n",
  699. block->drive, efi_devpath_text ( block->path ) );
  700. /* Add to list of block devices */
  701. list_add ( &block->list, &efi_block_devices );
  702. /* Open block device interface */
  703. if ( ( rc = efi_block_reopen ( block ) ) != 0 )
  704. goto err_reopen;
  705. /* Determine capacity and block size */
  706. if ( ( rc = efi_block_capacity ( block ) ) != 0 )
  707. goto err_capacity;
  708. /* Install protocols */
  709. if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
  710. &block->handle,
  711. &efi_block_io_protocol_guid, &block->block_io,
  712. &efi_device_path_protocol_guid, block->path,
  713. NULL ) ) != 0 ) {
  714. rc = -EEFI ( efirc );
  715. DBGC ( block, "EFIBLK %#02x could not install protocols: %s\n",
  716. block->drive, strerror ( rc ) );
  717. goto err_install;
  718. }
  719. /* Connect all possible protocols */
  720. efi_block_connect ( block );
  721. return drive;
  722. bs->UninstallMultipleProtocolInterfaces (
  723. block->handle,
  724. &efi_block_io_protocol_guid, &block->block_io,
  725. &efi_device_path_protocol_guid, block->path, NULL );
  726. err_install:
  727. err_capacity:
  728. efi_block_restart ( block, rc );
  729. intf_shutdown ( &block->intf, rc );
  730. err_reopen:
  731. list_del ( &block->list );
  732. err_no_snpdev:
  733. err_path:
  734. ref_put ( &block->refcnt );
  735. err_zalloc:
  736. err_in_use:
  737. return rc;
  738. }
  739. /**
  740. * Unhook EFI block device
  741. *
  742. * @v drive Drive number
  743. */
  744. static void efi_block_unhook ( unsigned int drive ) {
  745. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  746. struct efi_block *block;
  747. /* Find block device */
  748. block = efi_block_find ( drive );
  749. if ( ! block ) {
  750. DBG ( "EFIBLK cannot find drive %#02x\n", drive );
  751. return;
  752. }
  753. /* Uninstall protocols */
  754. bs->UninstallMultipleProtocolInterfaces (
  755. block->handle,
  756. &efi_block_io_protocol_guid, &block->block_io,
  757. &efi_device_path_protocol_guid, block->path, NULL );
  758. /* Close any outstanding commands and shut down interface */
  759. efi_block_restart ( block, 0 );
  760. intf_shutdown ( &block->intf, 0 );
  761. /* Remove from list of block devices */
  762. list_del ( &block->list );
  763. /* Drop list's reference to drive */
  764. ref_put ( &block->refcnt );
  765. }
  766. /**
  767. * Describe EFI block device
  768. *
  769. * @v drive Drive number
  770. * @ret rc Return status code
  771. */
  772. static int efi_block_describe ( unsigned int drive ) {
  773. struct efi_block *block;
  774. /* Find block device */
  775. block = efi_block_find ( drive );
  776. if ( ! block ) {
  777. DBG ( "EFIBLK cannot find drive %#02x\n", drive );
  778. return -ENODEV;
  779. }
  780. return 0;
  781. }
  782. /**
  783. * Try booting from child device of EFI block device
  784. *
  785. * @v block Block device
  786. * @v handle EFI handle
  787. * @ret rc Return status code
  788. */
  789. static int efi_block_boot_image ( struct efi_block *block,
  790. EFI_HANDLE handle, EFI_HANDLE *image ) {
  791. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  792. union {
  793. EFI_DEVICE_PATH_PROTOCOL *path;
  794. void *interface;
  795. } path;
  796. EFI_DEVICE_PATH_PROTOCOL *boot_path;
  797. FILEPATH_DEVICE_PATH *filepath;
  798. EFI_DEVICE_PATH_PROTOCOL *end;
  799. size_t prefix_len;
  800. size_t filepath_len;
  801. size_t boot_path_len;
  802. EFI_STATUS efirc;
  803. int rc;
  804. /* Identify device path */
  805. if ( ( efirc = bs->OpenProtocol ( handle,
  806. &efi_device_path_protocol_guid,
  807. &path.interface, efi_image_handle,
  808. handle,
  809. EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
  810. DBGC ( block, "EFIBLK %#02x found filesystem with no device "
  811. "path??", block->drive );
  812. rc = -EEFI ( efirc );
  813. goto err_open_device_path;
  814. }
  815. /* Check if this device is a child of our block device */
  816. end = efi_devpath_end ( block->path );
  817. prefix_len = ( ( ( void * ) end ) - ( ( void * ) block->path ) );
  818. if ( memcmp ( path.path, block->path, prefix_len ) != 0 ) {
  819. /* Not a child device */
  820. rc = -ENOTTY;
  821. goto err_not_child;
  822. }
  823. DBGC ( block, "EFIBLK %#02x found child device %s\n",
  824. block->drive, efi_devpath_text ( path.path ) );
  825. /* Construct device path for boot image */
  826. end = efi_devpath_end ( path.path );
  827. prefix_len = ( ( ( void * ) end ) - ( ( void * ) path.path ) );
  828. filepath_len = ( SIZE_OF_FILEPATH_DEVICE_PATH +
  829. sizeof ( efi_block_boot_filename ) );
  830. boot_path_len = ( prefix_len + filepath_len + sizeof ( *end ) );
  831. boot_path = zalloc ( boot_path_len );
  832. if ( ! boot_path ) {
  833. rc = -ENOMEM;
  834. goto err_alloc_path;
  835. }
  836. memcpy ( boot_path, path.path, prefix_len );
  837. filepath = ( ( ( void * ) boot_path ) + prefix_len );
  838. filepath->Header.Type = MEDIA_DEVICE_PATH;
  839. filepath->Header.SubType = MEDIA_FILEPATH_DP;
  840. filepath->Header.Length[0] = ( filepath_len & 0xff );
  841. filepath->Header.Length[1] = ( filepath_len >> 8 );
  842. memcpy ( filepath->PathName, efi_block_boot_filename,
  843. sizeof ( efi_block_boot_filename ) );
  844. end = ( ( ( void * ) filepath ) + filepath_len );
  845. end->Type = END_DEVICE_PATH_TYPE;
  846. end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
  847. end->Length[0] = sizeof ( *end );
  848. DBGC ( block, "EFIBLK %#02x trying to load %s\n",
  849. block->drive, efi_devpath_text ( boot_path ) );
  850. /* Try loading boot image from this device */
  851. if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, boot_path,
  852. NULL, 0, image ) ) != 0 ) {
  853. rc = -EEFI ( efirc );
  854. DBGC ( block, "EFIBLK %#02x could not load image: %s\n",
  855. block->drive, strerror ( rc ) );
  856. goto err_load_image;
  857. }
  858. /* Success */
  859. rc = 0;
  860. err_load_image:
  861. free ( boot_path );
  862. err_alloc_path:
  863. err_not_child:
  864. err_open_device_path:
  865. return rc;
  866. }
  867. /**
  868. * Boot from EFI block device
  869. *
  870. * @v drive Drive number
  871. * @ret rc Return status code
  872. */
  873. static int efi_block_boot ( unsigned int drive ) {
  874. EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
  875. struct efi_block *block;
  876. EFI_HANDLE *handles;
  877. EFI_HANDLE image = NULL;
  878. UINTN count;
  879. unsigned int i;
  880. EFI_STATUS efirc;
  881. int rc;
  882. /* Find block device */
  883. block = efi_block_find ( drive );
  884. if ( ! block ) {
  885. DBG ( "EFIBLK cannot find drive %#02x\n", drive );
  886. rc = -ENODEV;
  887. goto err_block_find;
  888. }
  889. /* Connect all possible protocols */
  890. efi_block_connect ( block );
  891. /* Locate all handles supporting the Simple File System protocol */
  892. if ( ( efirc = bs->LocateHandleBuffer (
  893. ByProtocol, &efi_simple_file_system_protocol_guid,
  894. NULL, &count, &handles ) ) != 0 ) {
  895. rc = -EEFI ( efirc );
  896. DBGC ( block, "EFIBLK %#02x cannot locate file systems: %s\n",
  897. block->drive, strerror ( rc ) );
  898. goto err_locate_file_systems;
  899. }
  900. /* Try booting from any available child device containing a
  901. * suitable boot image. This is something of a wild stab in
  902. * the dark, but should end up conforming to user expectations
  903. * most of the time.
  904. */
  905. rc = -ENOENT;
  906. for ( i = 0 ; i < count ; i++ ) {
  907. if ( ( rc = efi_block_boot_image ( block, handles[i],
  908. &image ) ) != 0 )
  909. continue;
  910. DBGC ( block, "EFIBLK %#02x found boot image\n", block->drive );
  911. efirc = bs->StartImage ( image, NULL, NULL );
  912. rc = ( efirc ? -EEFI ( efirc ) : 0 );
  913. bs->UnloadImage ( image );
  914. DBGC ( block, "EFIBLK %#02x boot image returned: %s\n",
  915. block->drive, strerror ( rc ) );
  916. break;
  917. }
  918. bs->FreePool ( handles );
  919. err_locate_file_systems:
  920. err_block_find:
  921. return rc;
  922. }
  923. PROVIDE_SANBOOT_INLINE ( efi, san_default_drive );
  924. PROVIDE_SANBOOT ( efi, san_hook, efi_block_hook );
  925. PROVIDE_SANBOOT ( efi, san_unhook, efi_block_unhook );
  926. PROVIDE_SANBOOT ( efi, san_describe, efi_block_describe );
  927. PROVIDE_SANBOOT ( efi, san_boot, efi_block_boot );