Skip to content

Commit

Permalink
efi: Move unicode to ASCII conversion to shared function.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Roy Franz authored and Matt Fleming committed Sep 25, 2013
1 parent 4a9f3a7 commit 5fef387
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 37 deletions.
43 changes: 6 additions & 37 deletions arch/x86/boot/compressed/eboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,11 +435,10 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
struct efi_info *efi;
efi_loaded_image_t *image;
void *options;
u32 load_options_size;
efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
int options_size = 0;
efi_status_t status;
unsigned long cmdline;
char *cmdline_ptr;
u16 *s2;
u8 *s1;
int i;
Expand Down Expand Up @@ -487,41 +486,11 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
hdr->type_of_loader = 0x21;

/* Convert unicode cmdline to ascii */
options = image->load_options;
load_options_size = image->load_options_size / 2; /* ASCII */
cmdline = 0;
s2 = (u16 *)options;

if (s2) {
while (*s2 && *s2 != '\n' && options_size < load_options_size) {
s2++;
options_size++;
}

if (options_size) {
if (options_size > hdr->cmdline_size)
options_size = hdr->cmdline_size;

options_size++; /* NUL termination */

status = efi_low_alloc(sys_table, options_size, 1,
&cmdline);
if (status != EFI_SUCCESS) {
efi_printk(sys_table, "Failed to alloc mem for cmdline\n");
goto fail;
}

s1 = (u8 *)(unsigned long)cmdline;
s2 = (u16 *)options;

for (i = 0; i < options_size - 1; i++)
*s1++ = *s2++;

*s1 = '\0';
}
}

hdr->cmd_line_ptr = cmdline;
cmdline_ptr = efi_convert_cmdline_to_ascii(sys_table, image,
&options_size);
if (!cmdline_ptr)
goto fail;
hdr->cmd_line_ptr = (unsigned long)cmdline_ptr;

hdr->ramdisk_image = 0;
hdr->ramdisk_size = 0;
Expand Down
61 changes: 61 additions & 0 deletions drivers/firmware/efi/efi-stub-helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -554,3 +554,64 @@ static efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,

return status;
}

/*
* Convert the unicode UEFI command line to ASCII to pass to kernel.
* Size of memory allocated return in *cmd_line_len.
* Returns NULL on error.
*/
static char *efi_convert_cmdline_to_ascii(efi_system_table_t *sys_table_arg,
efi_loaded_image_t *image,
int *cmd_line_len)
{
u16 *s2;
u8 *s1 = NULL;
unsigned long cmdline_addr = 0;
int load_options_size = image->load_options_size / 2; /* ASCII */
void *options = image->load_options;
int options_size = 0;
efi_status_t status;
int i;
u16 zero = 0;

if (options) {
s2 = options;
while (*s2 && *s2 != '\n' && options_size < load_options_size) {
s2++;
options_size++;
}
}

if (options_size == 0) {
/* No command line options, so return empty string*/
options_size = 1;
options = &zero;
}

options_size++; /* NUL termination */
#ifdef CONFIG_ARM
/*
* For ARM, allocate at a high address to avoid reserved
* regions at low addresses that we don't know the specfics of
* at the time we are processing the command line.
*/
status = efi_high_alloc(sys_table_arg, options_size, 0,
&cmdline_addr, 0xfffff000);
#else
status = efi_low_alloc(sys_table_arg, options_size, 0,
&cmdline_addr);
#endif
if (status != EFI_SUCCESS)
return NULL;

s1 = (u8 *)cmdline_addr;
s2 = (u16 *)options;

for (i = 0; i < options_size - 1; i++)
*s1++ = *s2++;

*s1 = '\0';

*cmd_line_len = options_size;
return (char *)cmdline_addr;
}

0 comments on commit 5fef387

Please sign in to comment.