aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Franz <roy.franz@linaro.org>2013-09-22 18:45:33 -0400
committerMatt Fleming <matt.fleming@intel.com>2013-09-25 07:34:38 -0400
commit5fef3870c572a30f9def07c4ded69dc37a9cf5d9 (patch)
tree08fc883ebc4a51e1dc9ff07ed46d0566d2600f3b
parent4a9f3a7c336a6b0ffeef2523bef93e67b0921163 (diff)
efi: Move unicode to ASCII conversion to shared function.
Move the open-coded conversion to a shared function for use by all architectures. Change the allocation to prefer a high address for ARM, as this is required to avoid conflicts with reserved regions in low memory. We don't know the specifics of these regions until after we process the command line and device tree. Signed-off-by: Roy Franz <roy.franz@linaro.org> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--arch/x86/boot/compressed/eboot.c43
-rw-r--r--drivers/firmware/efi/efi-stub-helper.c61
2 files changed, 67 insertions, 37 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 2e997b6fbdb1..5e708c0d466f 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -435,11 +435,10 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
435 struct efi_info *efi; 435 struct efi_info *efi;
436 efi_loaded_image_t *image; 436 efi_loaded_image_t *image;
437 void *options; 437 void *options;
438 u32 load_options_size;
439 efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID; 438 efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
440 int options_size = 0; 439 int options_size = 0;
441 efi_status_t status; 440 efi_status_t status;
442 unsigned long cmdline; 441 char *cmdline_ptr;
443 u16 *s2; 442 u16 *s2;
444 u8 *s1; 443 u8 *s1;
445 int i; 444 int i;
@@ -487,41 +486,11 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
487 hdr->type_of_loader = 0x21; 486 hdr->type_of_loader = 0x21;
488 487
489 /* Convert unicode cmdline to ascii */ 488 /* Convert unicode cmdline to ascii */
490 options = image->load_options; 489 cmdline_ptr = efi_convert_cmdline_to_ascii(sys_table, image,
491 load_options_size = image->load_options_size / 2; /* ASCII */ 490 &options_size);
492 cmdline = 0; 491 if (!cmdline_ptr)
493 s2 = (u16 *)options; 492 goto fail;
494 493 hdr->cmd_line_ptr = (unsigned long)cmdline_ptr;
495 if (s2) {
496 while (*s2 && *s2 != '\n' && options_size < load_options_size) {
497 s2++;
498 options_size++;
499 }
500
501 if (options_size) {
502 if (options_size > hdr->cmdline_size)
503 options_size = hdr->cmdline_size;
504
505 options_size++; /* NUL termination */
506
507 status = efi_low_alloc(sys_table, options_size, 1,
508 &cmdline);
509 if (status != EFI_SUCCESS) {
510 efi_printk(sys_table, "Failed to alloc mem for cmdline\n");
511 goto fail;
512 }
513
514 s1 = (u8 *)(unsigned long)cmdline;
515 s2 = (u16 *)options;
516
517 for (i = 0; i < options_size - 1; i++)
518 *s1++ = *s2++;
519
520 *s1 = '\0';
521 }
522 }
523
524 hdr->cmd_line_ptr = cmdline;
525 494
526 hdr->ramdisk_image = 0; 495 hdr->ramdisk_image = 0;
527 hdr->ramdisk_size = 0; 496 hdr->ramdisk_size = 0;
diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/efi-stub-helper.c
index 361e24d8d665..96665b730c51 100644
--- a/drivers/firmware/efi/efi-stub-helper.c
+++ b/drivers/firmware/efi/efi-stub-helper.c
@@ -554,3 +554,64 @@ static efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
554 554
555 return status; 555 return status;
556} 556}
557
558/*
559 * Convert the unicode UEFI command line to ASCII to pass to kernel.
560 * Size of memory allocated return in *cmd_line_len.
561 * Returns NULL on error.
562 */
563static char *efi_convert_cmdline_to_ascii(efi_system_table_t *sys_table_arg,
564 efi_loaded_image_t *image,
565 int *cmd_line_len)
566{
567 u16 *s2;
568 u8 *s1 = NULL;
569 unsigned long cmdline_addr = 0;
570 int load_options_size = image->load_options_size / 2; /* ASCII */
571 void *options = image->load_options;
572 int options_size = 0;
573 efi_status_t status;
574 int i;
575 u16 zero = 0;
576
577 if (options) {
578 s2 = options;
579 while (*s2 && *s2 != '\n' && options_size < load_options_size) {
580 s2++;
581 options_size++;
582 }
583 }
584
585 if (options_size == 0) {
586 /* No command line options, so return empty string*/
587 options_size = 1;
588 options = &zero;
589 }
590
591 options_size++; /* NUL termination */
592#ifdef CONFIG_ARM
593 /*
594 * For ARM, allocate at a high address to avoid reserved
595 * regions at low addresses that we don't know the specfics of
596 * at the time we are processing the command line.
597 */
598 status = efi_high_alloc(sys_table_arg, options_size, 0,
599 &cmdline_addr, 0xfffff000);
600#else
601 status = efi_low_alloc(sys_table_arg, options_size, 0,
602 &cmdline_addr);
603#endif
604 if (status != EFI_SUCCESS)
605 return NULL;
606
607 s1 = (u8 *)cmdline_addr;
608 s2 = (u16 *)options;
609
610 for (i = 0; i < options_size - 1; i++)
611 *s1++ = *s2++;
612
613 *s1 = '\0';
614
615 *cmd_line_len = options_size;
616 return (char *)cmdline_addr;
617}