cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

efi-stub-helper.c (20607B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Helper functions used by the EFI stub on multiple
      4 * architectures. This should be #included by the EFI stub
      5 * implementation files.
      6 *
      7 * Copyright 2011 Intel Corporation; author Matt Fleming
      8 */
      9
     10#include <linux/stdarg.h>
     11
     12#include <linux/ctype.h>
     13#include <linux/efi.h>
     14#include <linux/kernel.h>
     15#include <linux/printk.h> /* For CONSOLE_LOGLEVEL_* */
     16#include <asm/efi.h>
     17#include <asm/setup.h>
     18
     19#include "efistub.h"
     20
     21bool efi_nochunk;
     22bool efi_nokaslr = !IS_ENABLED(CONFIG_RANDOMIZE_BASE);
     23int efi_loglevel = CONSOLE_LOGLEVEL_DEFAULT;
     24bool efi_novamap;
     25
     26static bool efi_noinitrd;
     27static bool efi_nosoftreserve;
     28static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA);
     29
     30bool __pure __efi_soft_reserve_enabled(void)
     31{
     32	return !efi_nosoftreserve;
     33}
     34
     35/**
     36 * efi_char16_puts() - Write a UCS-2 encoded string to the console
     37 * @str:	UCS-2 encoded string
     38 */
     39void efi_char16_puts(efi_char16_t *str)
     40{
     41	efi_call_proto(efi_table_attr(efi_system_table, con_out),
     42		       output_string, str);
     43}
     44
     45static
     46u32 utf8_to_utf32(const u8 **s8)
     47{
     48	u32 c32;
     49	u8 c0, cx;
     50	size_t clen, i;
     51
     52	c0 = cx = *(*s8)++;
     53	/*
     54	 * The position of the most-significant 0 bit gives us the length of
     55	 * a multi-octet encoding.
     56	 */
     57	for (clen = 0; cx & 0x80; ++clen)
     58		cx <<= 1;
     59	/*
     60	 * If the 0 bit is in position 8, this is a valid single-octet
     61	 * encoding. If the 0 bit is in position 7 or positions 1-3, the
     62	 * encoding is invalid.
     63	 * In either case, we just return the first octet.
     64	 */
     65	if (clen < 2 || clen > 4)
     66		return c0;
     67	/* Get the bits from the first octet. */
     68	c32 = cx >> clen--;
     69	for (i = 0; i < clen; ++i) {
     70		/* Trailing octets must have 10 in most significant bits. */
     71		cx = (*s8)[i] ^ 0x80;
     72		if (cx & 0xc0)
     73			return c0;
     74		c32 = (c32 << 6) | cx;
     75	}
     76	/*
     77	 * Check for validity:
     78	 * - The character must be in the Unicode range.
     79	 * - It must not be a surrogate.
     80	 * - It must be encoded using the correct number of octets.
     81	 */
     82	if (c32 > 0x10ffff ||
     83	    (c32 & 0xf800) == 0xd800 ||
     84	    clen != (c32 >= 0x80) + (c32 >= 0x800) + (c32 >= 0x10000))
     85		return c0;
     86	*s8 += clen;
     87	return c32;
     88}
     89
     90/**
     91 * efi_puts() - Write a UTF-8 encoded string to the console
     92 * @str:	UTF-8 encoded string
     93 */
     94void efi_puts(const char *str)
     95{
     96	efi_char16_t buf[128];
     97	size_t pos = 0, lim = ARRAY_SIZE(buf);
     98	const u8 *s8 = (const u8 *)str;
     99	u32 c32;
    100
    101	while (*s8) {
    102		if (*s8 == '\n')
    103			buf[pos++] = L'\r';
    104		c32 = utf8_to_utf32(&s8);
    105		if (c32 < 0x10000) {
    106			/* Characters in plane 0 use a single word. */
    107			buf[pos++] = c32;
    108		} else {
    109			/*
    110			 * Characters in other planes encode into a surrogate
    111			 * pair.
    112			 */
    113			buf[pos++] = (0xd800 - (0x10000 >> 10)) + (c32 >> 10);
    114			buf[pos++] = 0xdc00 + (c32 & 0x3ff);
    115		}
    116		if (*s8 == '\0' || pos >= lim - 2) {
    117			buf[pos] = L'\0';
    118			efi_char16_puts(buf);
    119			pos = 0;
    120		}
    121	}
    122}
    123
    124/**
    125 * efi_printk() - Print a kernel message
    126 * @fmt:	format string
    127 *
    128 * The first letter of the format string is used to determine the logging level
    129 * of the message. If the level is less then the current EFI logging level, the
    130 * message is suppressed. The message will be truncated to 255 bytes.
    131 *
    132 * Return:	number of printed characters
    133 */
    134int efi_printk(const char *fmt, ...)
    135{
    136	char printf_buf[256];
    137	va_list args;
    138	int printed;
    139	int loglevel = printk_get_level(fmt);
    140
    141	switch (loglevel) {
    142	case '0' ... '9':
    143		loglevel -= '0';
    144		break;
    145	default:
    146		/*
    147		 * Use loglevel -1 for cases where we just want to print to
    148		 * the screen.
    149		 */
    150		loglevel = -1;
    151		break;
    152	}
    153
    154	if (loglevel >= efi_loglevel)
    155		return 0;
    156
    157	if (loglevel >= 0)
    158		efi_puts("EFI stub: ");
    159
    160	fmt = printk_skip_level(fmt);
    161
    162	va_start(args, fmt);
    163	printed = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args);
    164	va_end(args);
    165
    166	efi_puts(printf_buf);
    167	if (printed >= sizeof(printf_buf)) {
    168		efi_puts("[Message truncated]\n");
    169		return -1;
    170	}
    171
    172	return printed;
    173}
    174
    175/**
    176 * efi_parse_options() - Parse EFI command line options
    177 * @cmdline:	kernel command line
    178 *
    179 * Parse the ASCII string @cmdline for EFI options, denoted by the efi=
    180 * option, e.g. efi=nochunk.
    181 *
    182 * It should be noted that efi= is parsed in two very different
    183 * environments, first in the early boot environment of the EFI boot
    184 * stub, and subsequently during the kernel boot.
    185 *
    186 * Return:	status code
    187 */
    188efi_status_t efi_parse_options(char const *cmdline)
    189{
    190	size_t len;
    191	efi_status_t status;
    192	char *str, *buf;
    193
    194	if (!cmdline)
    195		return EFI_SUCCESS;
    196
    197	len = strnlen(cmdline, COMMAND_LINE_SIZE - 1) + 1;
    198	status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, len, (void **)&buf);
    199	if (status != EFI_SUCCESS)
    200		return status;
    201
    202	memcpy(buf, cmdline, len - 1);
    203	buf[len - 1] = '\0';
    204	str = skip_spaces(buf);
    205
    206	while (*str) {
    207		char *param, *val;
    208
    209		str = next_arg(str, &param, &val);
    210		if (!val && !strcmp(param, "--"))
    211			break;
    212
    213		if (!strcmp(param, "nokaslr")) {
    214			efi_nokaslr = true;
    215		} else if (!strcmp(param, "quiet")) {
    216			efi_loglevel = CONSOLE_LOGLEVEL_QUIET;
    217		} else if (!strcmp(param, "noinitrd")) {
    218			efi_noinitrd = true;
    219		} else if (!strcmp(param, "efi") && val) {
    220			efi_nochunk = parse_option_str(val, "nochunk");
    221			efi_novamap = parse_option_str(val, "novamap");
    222
    223			efi_nosoftreserve = IS_ENABLED(CONFIG_EFI_SOFT_RESERVE) &&
    224					    parse_option_str(val, "nosoftreserve");
    225
    226			if (parse_option_str(val, "disable_early_pci_dma"))
    227				efi_disable_pci_dma = true;
    228			if (parse_option_str(val, "no_disable_early_pci_dma"))
    229				efi_disable_pci_dma = false;
    230			if (parse_option_str(val, "debug"))
    231				efi_loglevel = CONSOLE_LOGLEVEL_DEBUG;
    232		} else if (!strcmp(param, "video") &&
    233			   val && strstarts(val, "efifb:")) {
    234			efi_parse_option_graphics(val + strlen("efifb:"));
    235		}
    236	}
    237	efi_bs_call(free_pool, buf);
    238	return EFI_SUCCESS;
    239}
    240
    241/*
    242 * The EFI_LOAD_OPTION descriptor has the following layout:
    243 *	u32 Attributes;
    244 *	u16 FilePathListLength;
    245 *	u16 Description[];
    246 *	efi_device_path_protocol_t FilePathList[];
    247 *	u8 OptionalData[];
    248 *
    249 * This function validates and unpacks the variable-size data fields.
    250 */
    251static
    252bool efi_load_option_unpack(efi_load_option_unpacked_t *dest,
    253			    const efi_load_option_t *src, size_t size)
    254{
    255	const void *pos;
    256	u16 c;
    257	efi_device_path_protocol_t header;
    258	const efi_char16_t *description;
    259	const efi_device_path_protocol_t *file_path_list;
    260
    261	if (size < offsetof(efi_load_option_t, variable_data))
    262		return false;
    263	pos = src->variable_data;
    264	size -= offsetof(efi_load_option_t, variable_data);
    265
    266	if ((src->attributes & ~EFI_LOAD_OPTION_MASK) != 0)
    267		return false;
    268
    269	/* Scan description. */
    270	description = pos;
    271	do {
    272		if (size < sizeof(c))
    273			return false;
    274		c = *(const u16 *)pos;
    275		pos += sizeof(c);
    276		size -= sizeof(c);
    277	} while (c != L'\0');
    278
    279	/* Scan file_path_list. */
    280	file_path_list = pos;
    281	do {
    282		if (size < sizeof(header))
    283			return false;
    284		header = *(const efi_device_path_protocol_t *)pos;
    285		if (header.length < sizeof(header))
    286			return false;
    287		if (size < header.length)
    288			return false;
    289		pos += header.length;
    290		size -= header.length;
    291	} while ((header.type != EFI_DEV_END_PATH && header.type != EFI_DEV_END_PATH2) ||
    292		 (header.sub_type != EFI_DEV_END_ENTIRE));
    293	if (pos != (const void *)file_path_list + src->file_path_list_length)
    294		return false;
    295
    296	dest->attributes = src->attributes;
    297	dest->file_path_list_length = src->file_path_list_length;
    298	dest->description = description;
    299	dest->file_path_list = file_path_list;
    300	dest->optional_data_size = size;
    301	dest->optional_data = size ? pos : NULL;
    302
    303	return true;
    304}
    305
    306/*
    307 * At least some versions of Dell firmware pass the entire contents of the
    308 * Boot#### variable, i.e. the EFI_LOAD_OPTION descriptor, rather than just the
    309 * OptionalData field.
    310 *
    311 * Detect this case and extract OptionalData.
    312 */
    313void efi_apply_loadoptions_quirk(const void **load_options, int *load_options_size)
    314{
    315	const efi_load_option_t *load_option = *load_options;
    316	efi_load_option_unpacked_t load_option_unpacked;
    317
    318	if (!IS_ENABLED(CONFIG_X86))
    319		return;
    320	if (!load_option)
    321		return;
    322	if (*load_options_size < sizeof(*load_option))
    323		return;
    324	if ((load_option->attributes & ~EFI_LOAD_OPTION_BOOT_MASK) != 0)
    325		return;
    326
    327	if (!efi_load_option_unpack(&load_option_unpacked, load_option, *load_options_size))
    328		return;
    329
    330	efi_warn_once(FW_BUG "LoadOptions is an EFI_LOAD_OPTION descriptor\n");
    331	efi_warn_once(FW_BUG "Using OptionalData as a workaround\n");
    332
    333	*load_options = load_option_unpacked.optional_data;
    334	*load_options_size = load_option_unpacked.optional_data_size;
    335}
    336
    337/*
    338 * Convert the unicode UEFI command line to ASCII to pass to kernel.
    339 * Size of memory allocated return in *cmd_line_len.
    340 * Returns NULL on error.
    341 */
    342char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len)
    343{
    344	const u16 *s2;
    345	unsigned long cmdline_addr = 0;
    346	int options_chars = efi_table_attr(image, load_options_size);
    347	const u16 *options = efi_table_attr(image, load_options);
    348	int options_bytes = 0, safe_options_bytes = 0;  /* UTF-8 bytes */
    349	bool in_quote = false;
    350	efi_status_t status;
    351
    352	efi_apply_loadoptions_quirk((const void **)&options, &options_chars);
    353	options_chars /= sizeof(*options);
    354
    355	if (options) {
    356		s2 = options;
    357		while (options_bytes < COMMAND_LINE_SIZE && options_chars--) {
    358			u16 c = *s2++;
    359
    360			if (c < 0x80) {
    361				if (c == L'\0' || c == L'\n')
    362					break;
    363				if (c == L'"')
    364					in_quote = !in_quote;
    365				else if (!in_quote && isspace((char)c))
    366					safe_options_bytes = options_bytes;
    367
    368				options_bytes++;
    369				continue;
    370			}
    371
    372			/*
    373			 * Get the number of UTF-8 bytes corresponding to a
    374			 * UTF-16 character.
    375			 * The first part handles everything in the BMP.
    376			 */
    377			options_bytes += 2 + (c >= 0x800);
    378			/*
    379			 * Add one more byte for valid surrogate pairs. Invalid
    380			 * surrogates will be replaced with 0xfffd and take up
    381			 * only 3 bytes.
    382			 */
    383			if ((c & 0xfc00) == 0xd800) {
    384				/*
    385				 * If the very last word is a high surrogate,
    386				 * we must ignore it since we can't access the
    387				 * low surrogate.
    388				 */
    389				if (!options_chars) {
    390					options_bytes -= 3;
    391				} else if ((*s2 & 0xfc00) == 0xdc00) {
    392					options_bytes++;
    393					options_chars--;
    394					s2++;
    395				}
    396			}
    397		}
    398		if (options_bytes >= COMMAND_LINE_SIZE) {
    399			options_bytes = safe_options_bytes;
    400			efi_err("Command line is too long: truncated to %d bytes\n",
    401				options_bytes);
    402		}
    403	}
    404
    405	options_bytes++;	/* NUL termination */
    406
    407	status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, options_bytes,
    408			     (void **)&cmdline_addr);
    409	if (status != EFI_SUCCESS)
    410		return NULL;
    411
    412	snprintf((char *)cmdline_addr, options_bytes, "%.*ls",
    413		 options_bytes - 1, options);
    414
    415	*cmd_line_len = options_bytes;
    416	return (char *)cmdline_addr;
    417}
    418
    419/**
    420 * efi_exit_boot_services() - Exit boot services
    421 * @handle:	handle of the exiting image
    422 * @map:	pointer to receive the memory map
    423 * @priv:	argument to be passed to @priv_func
    424 * @priv_func:	function to process the memory map before exiting boot services
    425 *
    426 * Handle calling ExitBootServices according to the requirements set out by the
    427 * spec.  Obtains the current memory map, and returns that info after calling
    428 * ExitBootServices.  The client must specify a function to perform any
    429 * processing of the memory map data prior to ExitBootServices.  A client
    430 * specific structure may be passed to the function via priv.  The client
    431 * function may be called multiple times.
    432 *
    433 * Return:	status code
    434 */
    435efi_status_t efi_exit_boot_services(void *handle,
    436				    struct efi_boot_memmap *map,
    437				    void *priv,
    438				    efi_exit_boot_map_processing priv_func)
    439{
    440	efi_status_t status;
    441
    442	status = efi_get_memory_map(map);
    443
    444	if (status != EFI_SUCCESS)
    445		goto fail;
    446
    447	status = priv_func(map, priv);
    448	if (status != EFI_SUCCESS)
    449		goto free_map;
    450
    451	if (efi_disable_pci_dma)
    452		efi_pci_disable_bridge_busmaster();
    453
    454	status = efi_bs_call(exit_boot_services, handle, *map->key_ptr);
    455
    456	if (status == EFI_INVALID_PARAMETER) {
    457		/*
    458		 * The memory map changed between efi_get_memory_map() and
    459		 * exit_boot_services().  Per the UEFI Spec v2.6, Section 6.4:
    460		 * EFI_BOOT_SERVICES.ExitBootServices we need to get the
    461		 * updated map, and try again.  The spec implies one retry
    462		 * should be sufficent, which is confirmed against the EDK2
    463		 * implementation.  Per the spec, we can only invoke
    464		 * get_memory_map() and exit_boot_services() - we cannot alloc
    465		 * so efi_get_memory_map() cannot be used, and we must reuse
    466		 * the buffer.  For all practical purposes, the headroom in the
    467		 * buffer should account for any changes in the map so the call
    468		 * to get_memory_map() is expected to succeed here.
    469		 */
    470		*map->map_size = *map->buff_size;
    471		status = efi_bs_call(get_memory_map,
    472				     map->map_size,
    473				     *map->map,
    474				     map->key_ptr,
    475				     map->desc_size,
    476				     map->desc_ver);
    477
    478		/* exit_boot_services() was called, thus cannot free */
    479		if (status != EFI_SUCCESS)
    480			goto fail;
    481
    482		status = priv_func(map, priv);
    483		/* exit_boot_services() was called, thus cannot free */
    484		if (status != EFI_SUCCESS)
    485			goto fail;
    486
    487		status = efi_bs_call(exit_boot_services, handle, *map->key_ptr);
    488	}
    489
    490	/* exit_boot_services() was called, thus cannot free */
    491	if (status != EFI_SUCCESS)
    492		goto fail;
    493
    494	return EFI_SUCCESS;
    495
    496free_map:
    497	efi_bs_call(free_pool, *map->map);
    498fail:
    499	return status;
    500}
    501
    502/**
    503 * get_efi_config_table() - retrieve UEFI configuration table
    504 * @guid:	GUID of the configuration table to be retrieved
    505 * Return:	pointer to the configuration table or NULL
    506 */
    507void *get_efi_config_table(efi_guid_t guid)
    508{
    509	unsigned long tables = efi_table_attr(efi_system_table, tables);
    510	int nr_tables = efi_table_attr(efi_system_table, nr_tables);
    511	int i;
    512
    513	for (i = 0; i < nr_tables; i++) {
    514		efi_config_table_t *t = (void *)tables;
    515
    516		if (efi_guidcmp(t->guid, guid) == 0)
    517			return efi_table_attr(t, table);
    518
    519		tables += efi_is_native() ? sizeof(efi_config_table_t)
    520					  : sizeof(efi_config_table_32_t);
    521	}
    522	return NULL;
    523}
    524
    525/*
    526 * The LINUX_EFI_INITRD_MEDIA_GUID vendor media device path below provides a way
    527 * for the firmware or bootloader to expose the initrd data directly to the stub
    528 * via the trivial LoadFile2 protocol, which is defined in the UEFI spec, and is
    529 * very easy to implement. It is a simple Linux initrd specific conduit between
    530 * kernel and firmware, allowing us to put the EFI stub (being part of the
    531 * kernel) in charge of where and when to load the initrd, while leaving it up
    532 * to the firmware to decide whether it needs to expose its filesystem hierarchy
    533 * via EFI protocols.
    534 */
    535static const struct {
    536	struct efi_vendor_dev_path	vendor;
    537	struct efi_generic_dev_path	end;
    538} __packed initrd_dev_path = {
    539	{
    540		{
    541			EFI_DEV_MEDIA,
    542			EFI_DEV_MEDIA_VENDOR,
    543			sizeof(struct efi_vendor_dev_path),
    544		},
    545		LINUX_EFI_INITRD_MEDIA_GUID
    546	}, {
    547		EFI_DEV_END_PATH,
    548		EFI_DEV_END_ENTIRE,
    549		sizeof(struct efi_generic_dev_path)
    550	}
    551};
    552
    553/**
    554 * efi_load_initrd_dev_path() - load the initrd from the Linux initrd device path
    555 * @load_addr:	pointer to store the address where the initrd was loaded
    556 * @load_size:	pointer to store the size of the loaded initrd
    557 * @max:	upper limit for the initrd memory allocation
    558 *
    559 * Return:
    560 * * %EFI_SUCCESS if the initrd was loaded successfully, in which
    561 *   case @load_addr and @load_size are assigned accordingly
    562 * * %EFI_NOT_FOUND if no LoadFile2 protocol exists on the initrd device path
    563 * * %EFI_INVALID_PARAMETER if load_addr == NULL or load_size == NULL
    564 * * %EFI_OUT_OF_RESOURCES if memory allocation failed
    565 * * %EFI_LOAD_ERROR in all other cases
    566 */
    567static
    568efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr,
    569				      unsigned long *load_size,
    570				      unsigned long max)
    571{
    572	efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
    573	efi_device_path_protocol_t *dp;
    574	efi_load_file2_protocol_t *lf2;
    575	unsigned long initrd_addr;
    576	unsigned long initrd_size;
    577	efi_handle_t handle;
    578	efi_status_t status;
    579
    580	dp = (efi_device_path_protocol_t *)&initrd_dev_path;
    581	status = efi_bs_call(locate_device_path, &lf2_proto_guid, &dp, &handle);
    582	if (status != EFI_SUCCESS)
    583		return status;
    584
    585	status = efi_bs_call(handle_protocol, handle, &lf2_proto_guid,
    586			     (void **)&lf2);
    587	if (status != EFI_SUCCESS)
    588		return status;
    589
    590	status = efi_call_proto(lf2, load_file, dp, false, &initrd_size, NULL);
    591	if (status != EFI_BUFFER_TOO_SMALL)
    592		return EFI_LOAD_ERROR;
    593
    594	status = efi_allocate_pages(initrd_size, &initrd_addr, max);
    595	if (status != EFI_SUCCESS)
    596		return status;
    597
    598	status = efi_call_proto(lf2, load_file, dp, false, &initrd_size,
    599				(void *)initrd_addr);
    600	if (status != EFI_SUCCESS) {
    601		efi_free(initrd_size, initrd_addr);
    602		return EFI_LOAD_ERROR;
    603	}
    604
    605	*load_addr = initrd_addr;
    606	*load_size = initrd_size;
    607	return EFI_SUCCESS;
    608}
    609
    610static
    611efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image,
    612				     unsigned long *load_addr,
    613				     unsigned long *load_size,
    614				     unsigned long soft_limit,
    615				     unsigned long hard_limit)
    616{
    617	if (!IS_ENABLED(CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER) ||
    618	    (IS_ENABLED(CONFIG_X86) && (!efi_is_native() || image == NULL))) {
    619		*load_addr = *load_size = 0;
    620		return EFI_SUCCESS;
    621	}
    622
    623	return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2,
    624				    soft_limit, hard_limit,
    625				    load_addr, load_size);
    626}
    627
    628static const struct {
    629	efi_tcg2_event_t	event_data;
    630	efi_tcg2_tagged_event_t tagged_event;
    631	u8			tagged_event_data[];
    632} initrd_tcg2_event = {
    633	{
    634		sizeof(initrd_tcg2_event) + sizeof("Linux initrd"),
    635		{
    636			sizeof(initrd_tcg2_event.event_data.event_header),
    637			EFI_TCG2_EVENT_HEADER_VERSION,
    638			9,
    639			EV_EVENT_TAG,
    640		},
    641	},
    642	{
    643		INITRD_EVENT_TAG_ID,
    644		sizeof("Linux initrd"),
    645	},
    646	{ "Linux initrd" },
    647};
    648
    649static void efi_measure_initrd(unsigned long load_addr, unsigned long load_size)
    650{
    651	efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
    652	efi_tcg2_protocol_t *tcg2 = NULL;
    653	efi_status_t status;
    654
    655	efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2);
    656	if (tcg2) {
    657		status = efi_call_proto(tcg2, hash_log_extend_event,
    658					0, load_addr, load_size,
    659					&initrd_tcg2_event.event_data);
    660		if (status != EFI_SUCCESS)
    661			efi_warn("Failed to measure initrd data: 0x%lx\n",
    662				 status);
    663		else
    664			efi_info("Measured initrd data into PCR %d\n",
    665				 initrd_tcg2_event.event_data.event_header.pcr_index);
    666	}
    667}
    668
    669/**
    670 * efi_load_initrd() - Load initial RAM disk
    671 * @image:	EFI loaded image protocol
    672 * @load_addr:	pointer to loaded initrd
    673 * @load_size:	size of loaded initrd
    674 * @soft_limit:	preferred address for loading the initrd
    675 * @hard_limit:	upper limit address for loading the initrd
    676 *
    677 * Return:	status code
    678 */
    679efi_status_t efi_load_initrd(efi_loaded_image_t *image,
    680			     unsigned long *load_addr,
    681			     unsigned long *load_size,
    682			     unsigned long soft_limit,
    683			     unsigned long hard_limit)
    684{
    685	efi_status_t status;
    686
    687	if (efi_noinitrd) {
    688		*load_addr = *load_size = 0;
    689		status = EFI_SUCCESS;
    690	} else {
    691		status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit);
    692		if (status == EFI_SUCCESS) {
    693			efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
    694			if (*load_size > 0)
    695				efi_measure_initrd(*load_addr, *load_size);
    696		} else if (status == EFI_NOT_FOUND) {
    697			status = efi_load_initrd_cmdline(image, load_addr, load_size,
    698							 soft_limit, hard_limit);
    699			if (status == EFI_SUCCESS && *load_size > 0)
    700				efi_info("Loaded initrd from command line option\n");
    701		}
    702		if (status != EFI_SUCCESS) {
    703			efi_err("Failed to load initrd: 0x%lx\n", status);
    704			*load_addr = *load_size = 0;
    705		}
    706	}
    707
    708	return status;
    709}
    710
    711/**
    712 * efi_wait_for_key() - Wait for key stroke
    713 * @usec:	number of microseconds to wait for key stroke
    714 * @key:	key entered
    715 *
    716 * Wait for up to @usec microseconds for a key stroke.
    717 *
    718 * Return:	status code, EFI_SUCCESS if key received
    719 */
    720efi_status_t efi_wait_for_key(unsigned long usec, efi_input_key_t *key)
    721{
    722	efi_event_t events[2], timer;
    723	unsigned long index;
    724	efi_simple_text_input_protocol_t *con_in;
    725	efi_status_t status;
    726
    727	con_in = efi_table_attr(efi_system_table, con_in);
    728	if (!con_in)
    729		return EFI_UNSUPPORTED;
    730	efi_set_event_at(events, 0, efi_table_attr(con_in, wait_for_key));
    731
    732	status = efi_bs_call(create_event, EFI_EVT_TIMER, 0, NULL, NULL, &timer);
    733	if (status != EFI_SUCCESS)
    734		return status;
    735
    736	status = efi_bs_call(set_timer, timer, EfiTimerRelative,
    737			     EFI_100NSEC_PER_USEC * usec);
    738	if (status != EFI_SUCCESS)
    739		return status;
    740	efi_set_event_at(events, 1, timer);
    741
    742	status = efi_bs_call(wait_for_event, 2, events, &index);
    743	if (status == EFI_SUCCESS) {
    744		if (index == 0)
    745			status = efi_call_proto(con_in, read_keystroke, key);
    746		else
    747			status = EFI_TIMEOUT;
    748	}
    749
    750	efi_bs_call(close_event, timer);
    751
    752	return status;
    753}