efi-stub-helper.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. /*
  2. * Helper functions used by the EFI stub on multiple
  3. * architectures. This should be #included by the EFI stub
  4. * implementation files.
  5. *
  6. * Copyright 2011 Intel Corporation; author Matt Fleming
  7. *
  8. * This file is part of the Linux kernel, and is made available
  9. * under the terms of the GNU General Public License version 2.
  10. *
  11. */
  12. #define EFI_READ_CHUNK_SIZE (1024 * 1024)
  13. struct initrd {
  14. efi_file_handle_t *handle;
  15. u64 size;
  16. };
  17. static void efi_char16_printk(efi_char16_t *str)
  18. {
  19. struct efi_simple_text_output_protocol *out;
  20. out = (struct efi_simple_text_output_protocol *)sys_table->con_out;
  21. efi_call_phys2(out->output_string, out, str);
  22. }
  23. static void efi_printk(char *str)
  24. {
  25. char *s8;
  26. for (s8 = str; *s8; s8++) {
  27. efi_char16_t ch[2] = { 0 };
  28. ch[0] = *s8;
  29. if (*s8 == '\n') {
  30. efi_char16_t nl[2] = { '\r', 0 };
  31. efi_char16_printk(nl);
  32. }
  33. efi_char16_printk(ch);
  34. }
  35. }
  36. static efi_status_t __get_map(efi_memory_desc_t **map, unsigned long *map_size,
  37. unsigned long *desc_size)
  38. {
  39. efi_memory_desc_t *m = NULL;
  40. efi_status_t status;
  41. unsigned long key;
  42. u32 desc_version;
  43. *map_size = sizeof(*m) * 32;
  44. again:
  45. /*
  46. * Add an additional efi_memory_desc_t because we're doing an
  47. * allocation which may be in a new descriptor region.
  48. */
  49. *map_size += sizeof(*m);
  50. status = efi_call_phys3(sys_table->boottime->allocate_pool,
  51. EFI_LOADER_DATA, *map_size, (void **)&m);
  52. if (status != EFI_SUCCESS)
  53. goto fail;
  54. status = efi_call_phys5(sys_table->boottime->get_memory_map, map_size,
  55. m, &key, desc_size, &desc_version);
  56. if (status == EFI_BUFFER_TOO_SMALL) {
  57. efi_call_phys1(sys_table->boottime->free_pool, m);
  58. goto again;
  59. }
  60. if (status != EFI_SUCCESS)
  61. efi_call_phys1(sys_table->boottime->free_pool, m);
  62. fail:
  63. *map = m;
  64. return status;
  65. }
  66. /*
  67. * Allocate at the highest possible address that is not above 'max'.
  68. */
  69. static efi_status_t high_alloc(unsigned long size, unsigned long align,
  70. unsigned long *addr, unsigned long max)
  71. {
  72. unsigned long map_size, desc_size;
  73. efi_memory_desc_t *map;
  74. efi_status_t status;
  75. unsigned long nr_pages;
  76. u64 max_addr = 0;
  77. int i;
  78. status = __get_map(&map, &map_size, &desc_size);
  79. if (status != EFI_SUCCESS)
  80. goto fail;
  81. nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
  82. again:
  83. for (i = 0; i < map_size / desc_size; i++) {
  84. efi_memory_desc_t *desc;
  85. unsigned long m = (unsigned long)map;
  86. u64 start, end;
  87. desc = (efi_memory_desc_t *)(m + (i * desc_size));
  88. if (desc->type != EFI_CONVENTIONAL_MEMORY)
  89. continue;
  90. if (desc->num_pages < nr_pages)
  91. continue;
  92. start = desc->phys_addr;
  93. end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
  94. if ((start + size) > end || (start + size) > max)
  95. continue;
  96. if (end - size > max)
  97. end = max;
  98. if (round_down(end - size, align) < start)
  99. continue;
  100. start = round_down(end - size, align);
  101. /*
  102. * Don't allocate at 0x0. It will confuse code that
  103. * checks pointers against NULL.
  104. */
  105. if (start == 0x0)
  106. continue;
  107. if (start > max_addr)
  108. max_addr = start;
  109. }
  110. if (!max_addr)
  111. status = EFI_NOT_FOUND;
  112. else {
  113. status = efi_call_phys4(sys_table->boottime->allocate_pages,
  114. EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
  115. nr_pages, &max_addr);
  116. if (status != EFI_SUCCESS) {
  117. max = max_addr;
  118. max_addr = 0;
  119. goto again;
  120. }
  121. *addr = max_addr;
  122. }
  123. free_pool:
  124. efi_call_phys1(sys_table->boottime->free_pool, map);
  125. fail:
  126. return status;
  127. }
  128. /*
  129. * Allocate at the lowest possible address.
  130. */
  131. static efi_status_t low_alloc(unsigned long size, unsigned long align,
  132. unsigned long *addr)
  133. {
  134. unsigned long map_size, desc_size;
  135. efi_memory_desc_t *map;
  136. efi_status_t status;
  137. unsigned long nr_pages;
  138. int i;
  139. status = __get_map(&map, &map_size, &desc_size);
  140. if (status != EFI_SUCCESS)
  141. goto fail;
  142. nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
  143. for (i = 0; i < map_size / desc_size; i++) {
  144. efi_memory_desc_t *desc;
  145. unsigned long m = (unsigned long)map;
  146. u64 start, end;
  147. desc = (efi_memory_desc_t *)(m + (i * desc_size));
  148. if (desc->type != EFI_CONVENTIONAL_MEMORY)
  149. continue;
  150. if (desc->num_pages < nr_pages)
  151. continue;
  152. start = desc->phys_addr;
  153. end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
  154. /*
  155. * Don't allocate at 0x0. It will confuse code that
  156. * checks pointers against NULL. Skip the first 8
  157. * bytes so we start at a nice even number.
  158. */
  159. if (start == 0x0)
  160. start += 8;
  161. start = round_up(start, align);
  162. if ((start + size) > end)
  163. continue;
  164. status = efi_call_phys4(sys_table->boottime->allocate_pages,
  165. EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
  166. nr_pages, &start);
  167. if (status == EFI_SUCCESS) {
  168. *addr = start;
  169. break;
  170. }
  171. }
  172. if (i == map_size / desc_size)
  173. status = EFI_NOT_FOUND;
  174. free_pool:
  175. efi_call_phys1(sys_table->boottime->free_pool, map);
  176. fail:
  177. return status;
  178. }
  179. static void low_free(unsigned long size, unsigned long addr)
  180. {
  181. unsigned long nr_pages;
  182. nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
  183. efi_call_phys2(sys_table->boottime->free_pages, addr, nr_pages);
  184. }
  185. /*
  186. * Check the cmdline for a LILO-style initrd= arguments.
  187. *
  188. * We only support loading an initrd from the same filesystem as the
  189. * kernel image.
  190. */
  191. static efi_status_t handle_ramdisks(efi_loaded_image_t *image,
  192. struct setup_header *hdr)
  193. {
  194. struct initrd *initrds;
  195. unsigned long initrd_addr;
  196. efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
  197. u64 initrd_total;
  198. efi_file_io_interface_t *io;
  199. efi_file_handle_t *fh;
  200. efi_status_t status;
  201. int nr_initrds;
  202. char *str;
  203. int i, j, k;
  204. initrd_addr = 0;
  205. initrd_total = 0;
  206. str = (char *)(unsigned long)hdr->cmd_line_ptr;
  207. j = 0; /* See close_handles */
  208. if (!str || !*str)
  209. return EFI_SUCCESS;
  210. for (nr_initrds = 0; *str; nr_initrds++) {
  211. str = strstr(str, "initrd=");
  212. if (!str)
  213. break;
  214. str += 7;
  215. /* Skip any leading slashes */
  216. while (*str == '/' || *str == '\\')
  217. str++;
  218. while (*str && *str != ' ' && *str != '\n')
  219. str++;
  220. }
  221. if (!nr_initrds)
  222. return EFI_SUCCESS;
  223. status = efi_call_phys3(sys_table->boottime->allocate_pool,
  224. EFI_LOADER_DATA,
  225. nr_initrds * sizeof(*initrds),
  226. &initrds);
  227. if (status != EFI_SUCCESS) {
  228. efi_printk("Failed to alloc mem for initrds\n");
  229. goto fail;
  230. }
  231. str = (char *)(unsigned long)hdr->cmd_line_ptr;
  232. for (i = 0; i < nr_initrds; i++) {
  233. struct initrd *initrd;
  234. efi_file_handle_t *h;
  235. efi_file_info_t *info;
  236. efi_char16_t filename_16[256];
  237. unsigned long info_sz;
  238. efi_guid_t info_guid = EFI_FILE_INFO_ID;
  239. efi_char16_t *p;
  240. u64 file_sz;
  241. str = strstr(str, "initrd=");
  242. if (!str)
  243. break;
  244. str += 7;
  245. initrd = &initrds[i];
  246. p = filename_16;
  247. /* Skip any leading slashes */
  248. while (*str == '/' || *str == '\\')
  249. str++;
  250. while (*str && *str != ' ' && *str != '\n') {
  251. if ((u8 *)p >= (u8 *)filename_16 + sizeof(filename_16))
  252. break;
  253. if (*str == '/') {
  254. *p++ = '\\';
  255. *str++;
  256. } else {
  257. *p++ = *str++;
  258. }
  259. }
  260. *p = '\0';
  261. /* Only open the volume once. */
  262. if (!i) {
  263. efi_boot_services_t *boottime;
  264. boottime = sys_table->boottime;
  265. status = efi_call_phys3(boottime->handle_protocol,
  266. image->device_handle, &fs_proto, &io);
  267. if (status != EFI_SUCCESS) {
  268. efi_printk("Failed to handle fs_proto\n");
  269. goto free_initrds;
  270. }
  271. status = efi_call_phys2(io->open_volume, io, &fh);
  272. if (status != EFI_SUCCESS) {
  273. efi_printk("Failed to open volume\n");
  274. goto free_initrds;
  275. }
  276. }
  277. status = efi_call_phys5(fh->open, fh, &h, filename_16,
  278. EFI_FILE_MODE_READ, (u64)0);
  279. if (status != EFI_SUCCESS) {
  280. efi_printk("Failed to open initrd file: ");
  281. efi_char16_printk(filename_16);
  282. efi_printk("\n");
  283. goto close_handles;
  284. }
  285. initrd->handle = h;
  286. info_sz = 0;
  287. status = efi_call_phys4(h->get_info, h, &info_guid,
  288. &info_sz, NULL);
  289. if (status != EFI_BUFFER_TOO_SMALL) {
  290. efi_printk("Failed to get initrd info size\n");
  291. goto close_handles;
  292. }
  293. grow:
  294. status = efi_call_phys3(sys_table->boottime->allocate_pool,
  295. EFI_LOADER_DATA, info_sz, &info);
  296. if (status != EFI_SUCCESS) {
  297. efi_printk("Failed to alloc mem for initrd info\n");
  298. goto close_handles;
  299. }
  300. status = efi_call_phys4(h->get_info, h, &info_guid,
  301. &info_sz, info);
  302. if (status == EFI_BUFFER_TOO_SMALL) {
  303. efi_call_phys1(sys_table->boottime->free_pool, info);
  304. goto grow;
  305. }
  306. file_sz = info->file_size;
  307. efi_call_phys1(sys_table->boottime->free_pool, info);
  308. if (status != EFI_SUCCESS) {
  309. efi_printk("Failed to get initrd info\n");
  310. goto close_handles;
  311. }
  312. initrd->size = file_sz;
  313. initrd_total += file_sz;
  314. }
  315. if (initrd_total) {
  316. unsigned long addr;
  317. /*
  318. * Multiple initrd's need to be at consecutive
  319. * addresses in memory, so allocate enough memory for
  320. * all the initrd's.
  321. */
  322. status = high_alloc(initrd_total, 0x1000,
  323. &initrd_addr, hdr->initrd_addr_max);
  324. if (status != EFI_SUCCESS) {
  325. efi_printk("Failed to alloc highmem for initrds\n");
  326. goto close_handles;
  327. }
  328. /* We've run out of free low memory. */
  329. if (initrd_addr > hdr->initrd_addr_max) {
  330. efi_printk("We've run out of free low memory\n");
  331. status = EFI_INVALID_PARAMETER;
  332. goto free_initrd_total;
  333. }
  334. addr = initrd_addr;
  335. for (j = 0; j < nr_initrds; j++) {
  336. u64 size;
  337. size = initrds[j].size;
  338. while (size) {
  339. u64 chunksize;
  340. if (size > EFI_READ_CHUNK_SIZE)
  341. chunksize = EFI_READ_CHUNK_SIZE;
  342. else
  343. chunksize = size;
  344. status = efi_call_phys3(fh->read,
  345. initrds[j].handle,
  346. &chunksize, addr);
  347. if (status != EFI_SUCCESS) {
  348. efi_printk("Failed to read initrd\n");
  349. goto free_initrd_total;
  350. }
  351. addr += chunksize;
  352. size -= chunksize;
  353. }
  354. efi_call_phys1(fh->close, initrds[j].handle);
  355. }
  356. }
  357. efi_call_phys1(sys_table->boottime->free_pool, initrds);
  358. hdr->ramdisk_image = initrd_addr;
  359. hdr->ramdisk_size = initrd_total;
  360. return status;
  361. free_initrd_total:
  362. low_free(initrd_total, initrd_addr);
  363. close_handles:
  364. for (k = j; k < i; k++)
  365. efi_call_phys1(fh->close, initrds[k].handle);
  366. free_initrds:
  367. efi_call_phys1(sys_table->boottime->free_pool, initrds);
  368. fail:
  369. hdr->ramdisk_image = 0;
  370. hdr->ramdisk_size = 0;
  371. return status;
  372. }