aboutsummaryrefslogtreecommitdiff
path: root/lib/efi_loader
diff options
context:
space:
mode:
Diffstat (limited to 'lib/efi_loader')
-rw-r--r--lib/efi_loader/efi_boottime.c15
-rw-r--r--lib/efi_loader/efi_console.c22
-rw-r--r--lib/efi_loader/efi_memory.c13
-rw-r--r--lib/efi_loader/efi_runtime.c177
4 files changed, 195 insertions, 32 deletions
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index b9e54f551a..3935e4f1ce 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -154,18 +154,6 @@ const char *__efi_nesting_dec(void)
}
/**
- * efi_update_table_header_crc32() - Update CRC32 in table header
- *
- * @table: EFI table
- */
-static void efi_update_table_header_crc32(struct efi_table_hdr *table)
-{
- table->crc32 = 0;
- table->crc32 = crc32(0, (const unsigned char *)table,
- table->headersize);
-}
-
-/**
* efi_queue_event() - queue an EFI event
* @event: event to signal
* @check_tpl: check the TPL level
@@ -627,7 +615,8 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
return EFI_INVALID_PARAMETER;
}
- if (is_valid_tpl(notify_tpl) != EFI_SUCCESS)
+ if ((type & (EVT_NOTIFY_WAIT | EVT_NOTIFY_SIGNAL)) &&
+ (is_valid_tpl(notify_tpl) != EFI_SUCCESS))
return EFI_INVALID_PARAMETER;
evt = calloc(1, sizeof(struct efi_event));
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index 3fd0d2fd51..b487288785 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -105,14 +105,6 @@ static int term_read_reply(int *n, int num, char end_char)
return 0;
}
-static efi_status_t EFIAPI efi_cout_reset(
- struct efi_simple_text_output_protocol *this,
- char extended_verification)
-{
- EFI_ENTRY("%p, %d", this, extended_verification);
- return EFI_EXIT(EFI_UNSUPPORTED);
-}
-
static efi_status_t EFIAPI efi_cout_output_string(
struct efi_simple_text_output_protocol *this,
const efi_string_t string)
@@ -341,6 +333,20 @@ static efi_status_t EFIAPI efi_cout_clear_screen(
return EFI_EXIT(EFI_SUCCESS);
}
+static efi_status_t EFIAPI efi_cout_reset(
+ struct efi_simple_text_output_protocol *this,
+ char extended_verification)
+{
+ EFI_ENTRY("%p, %d", this, extended_verification);
+
+ /* Clear screen */
+ EFI_CALL(efi_cout_clear_screen(this));
+ /* Set default colors */
+ printf(ESC "[0;37;40m");
+
+ return EFI_EXIT(EFI_SUCCESS);
+}
+
static efi_status_t EFIAPI efi_cout_set_cursor_position(
struct efi_simple_text_output_protocol *this,
unsigned long column, unsigned long row)
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 967c3f733e..e2b40aa85b 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -178,14 +178,13 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
switch (memory_type) {
case EFI_RUNTIME_SERVICES_CODE:
case EFI_RUNTIME_SERVICES_DATA:
- newlist->desc.attribute = (1 << EFI_MEMORY_WB_SHIFT) |
- (1ULL << EFI_MEMORY_RUNTIME_SHIFT);
+ newlist->desc.attribute = EFI_MEMORY_WB | EFI_MEMORY_RUNTIME;
break;
case EFI_MMAP_IO:
- newlist->desc.attribute = 1ULL << EFI_MEMORY_RUNTIME_SHIFT;
+ newlist->desc.attribute = EFI_MEMORY_RUNTIME;
break;
default:
- newlist->desc.attribute = 1 << EFI_MEMORY_WB_SHIFT;
+ newlist->desc.attribute = EFI_MEMORY_WB;
break;
}
@@ -305,7 +304,7 @@ efi_status_t efi_allocate_pages(int type, int memory_type,
switch (type) {
case EFI_ALLOCATE_ANY_PAGES:
/* Any page */
- addr = efi_find_free_memory(len, -1ULL);
+ addr = efi_find_free_memory(len, gd->start_addr_sp);
if (!addr) {
r = EFI_NOT_FOUND;
break;
@@ -457,11 +456,13 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
efi_uintn_t map_size = 0;
int map_entries = 0;
struct list_head *lhandle;
- efi_uintn_t provided_map_size = *memory_map_size;
+ efi_uintn_t provided_map_size;
if (!memory_map_size)
return EFI_INVALID_PARAMETER;
+ provided_map_size = *memory_map_size;
+
list_for_each(lhandle, &efi_mem)
map_entries++;
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index 06958f23fa..27136cbedd 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -84,6 +84,32 @@ struct elf_rela {
* handle a good number of runtime callbacks
*/
+/**
+ * efi_update_table_header_crc32() - Update crc32 in table header
+ *
+ * @table: EFI table
+ */
+void __efi_runtime efi_update_table_header_crc32(struct efi_table_hdr *table)
+{
+ table->crc32 = 0;
+ table->crc32 = crc32(0, (const unsigned char *)table,
+ table->headersize);
+}
+
+/**
+ * efi_reset_system_boottime() - reset system at boottime
+ *
+ * This function implements the ResetSystem() runtime service before
+ * SetVirtualAddressMap() is called.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * @reset_type: type of reset to perform
+ * @reset_status: status code for the reset
+ * @data_size: size of reset_data
+ * @reset_data: information about the reset
+ */
static void EFIAPI efi_reset_system_boottime(
enum efi_reset_type reset_type,
efi_status_t reset_status,
@@ -118,15 +144,17 @@ static void EFIAPI efi_reset_system_boottime(
}
/**
- * efi_get_time_boottime - get current time
+ * efi_get_time_boottime() - get current time at boottime
+ *
+ * This function implements the GetTime runtime service before
+ * SetVirtualAddressMap() is called.
*
- * This function implements the GetTime runtime service.
* See the Unified Extensible Firmware Interface (UEFI) specification
* for details.
*
* @time: pointer to structure to receive current time
* @capabilities: pointer to structure to receive RTC properties
- * Return Value: status code
+ * Returns: status code
*/
static efi_status_t EFIAPI efi_get_time_boottime(
struct efi_time *time,
@@ -179,8 +207,22 @@ out:
#endif
}
-/* Boards may override the helpers below to implement RTS functionality */
+/**
+ * efi_reset_system() - reset system
+ *
+ * This function implements the ResetSystem() runtime service after
+ * SetVirtualAddressMap() is called. It only executes an endless loop.
+ * Boards may override the helpers below to implement reset functionality.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * @reset_type: type of reset to perform
+ * @reset_status: status code for the reset
+ * @data_size: size of reset_data
+ * @reset_data: information about the reset
+ */
void __weak __efi_runtime EFIAPI efi_reset_system(
enum efi_reset_type reset_type,
efi_status_t reset_status,
@@ -190,11 +232,30 @@ void __weak __efi_runtime EFIAPI efi_reset_system(
while (1) { }
}
+/**
+ * efi_reset_system_init() - initialize the reset driver
+ *
+ * Boards may override this function to initialize the reset driver.
+ */
efi_status_t __weak efi_reset_system_init(void)
{
return EFI_SUCCESS;
}
+/**
+ * efi_get_time() - get current time
+ *
+ * This function implements the GetTime runtime service after
+ * SetVirtualAddressMap() is called. As the U-Boot driver are not available
+ * anymore only an error code is returned.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * @time: pointer to structure to receive current time
+ * @capabilities: pointer to structure to receive RTC properties
+ * Returns: status code
+ */
efi_status_t __weak __efi_runtime EFIAPI efi_get_time(
struct efi_time *time,
struct efi_time_cap *capabilities)
@@ -273,6 +334,9 @@ static void efi_runtime_detach(ulong offset)
debug("%s: Setting %p to %lx\n", __func__, p, newaddr);
*p = newaddr;
}
+
+ /* Update crc32 */
+ efi_update_table_header_crc32(&efi_runtime_services.hdr);
}
/* Relocate EFI runtime to uboot_reloc_base = offset */
@@ -338,6 +402,20 @@ void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map)
invalidate_icache_all();
}
+/**
+ * efi_set_virtual_address_map() - change from physical to virtual mapping
+ *
+ * This function implements the SetVirtualAddressMap() runtime service.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * @memory_map_size: size of the virtual map
+ * @descriptor_size: size of an entry in the map
+ * @descriptor_version: version of the map entries
+ * @virtmap: virtual address mapping information
+ * Return: status code
+ */
static efi_status_t EFIAPI efi_set_virtual_address_map(
unsigned long memory_map_size,
unsigned long descriptor_size,
@@ -360,6 +438,7 @@ static efi_status_t EFIAPI efi_set_virtual_address_map(
efi_physical_addr_t map_start = map->physical_start;
efi_physical_addr_t map_len = map->num_pages << EFI_PAGE_SHIFT;
efi_physical_addr_t map_end = map_start + map_len;
+ u64 off = map->virtual_start - map_start;
/* Adjust all mmio pointers in this region */
list_for_each(lhandle, &efi_runtime_mmio) {
@@ -370,11 +449,17 @@ static efi_status_t EFIAPI efi_set_virtual_address_map(
link);
if ((map_start <= lmmio->paddr) &&
(map_end >= lmmio->paddr)) {
- u64 off = map->virtual_start - map_start;
uintptr_t new_addr = lmmio->paddr + off;
*lmmio->ptr = (void *)new_addr;
}
}
+ if ((map_start <= (uintptr_t)systab.tables) &&
+ (map_end >= (uintptr_t)systab.tables)) {
+ char *ptr = (char *)systab.tables;
+
+ ptr += off;
+ systab.tables = (struct efi_configuration_table *)ptr;
+ }
}
/* Move the actual runtime code over */
@@ -397,6 +482,16 @@ static efi_status_t EFIAPI efi_set_virtual_address_map(
return EFI_EXIT(EFI_INVALID_PARAMETER);
}
+/**
+ * efi_add_runtime_mmio() - add memory-mapped IO region
+ *
+ * This function adds a memory-mapped IO region to the memory map to make it
+ * available at runtime.
+ *
+ * @mmio_ptr: address of the memory-mapped IO region
+ * @len: size of thememory-mapped IO region
+ * Returns: status code
+ */
efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len)
{
struct efi_runtime_mmio_list *newmmio;
@@ -439,21 +534,61 @@ efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len)
* address map calls.
*/
+/**
+ * efi_unimplemented() - replacement function, returns EFI_UNSUPPORTED
+ *
+ * This function is used after SetVirtualAddressMap() is called as replacement
+ * for services that are not available anymore due to constraints of the U-Boot
+ * implementation.
+ *
+ * Return: EFI_UNSUPPORTED
+ */
static efi_status_t __efi_runtime EFIAPI efi_unimplemented(void)
{
return EFI_UNSUPPORTED;
}
+/**
+ * efi_device_error() - replacement function, returns EFI_DEVICE_ERROR
+ *
+ * This function is used after SetVirtualAddressMap() is called as replacement
+ * for services that are not available anymore due to constraints of the U-Boot
+ * implementation.
+ *
+ * Return: EFI_DEVICE_ERROR
+ */
static efi_status_t __efi_runtime EFIAPI efi_device_error(void)
{
return EFI_DEVICE_ERROR;
}
+/**
+ * efi_invalid_parameter() - replacement function, returns EFI_INVALID_PARAMETER
+ *
+ * This function is used after SetVirtualAddressMap() is called as replacement
+ * for services that are not available anymore due to constraints of the U-Boot
+ * implementation.
+ *
+ * Return: EFI_INVALID_PARAMETER
+ */
static efi_status_t __efi_runtime EFIAPI efi_invalid_parameter(void)
{
return EFI_INVALID_PARAMETER;
}
+/**
+ * efi_update_capsule() - process information from operating system
+ *
+ * This function implements the UpdateCapsule() runtime service.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * @capsule_header_array: pointer to array of virtual pointers
+ * @capsule_count: number of pointers in capsule_header_array
+ * @scatter_gather_list: pointer to arry of physical pointers
+ * Returns: status code
+ */
efi_status_t __efi_runtime EFIAPI efi_update_capsule(
struct efi_capsule_header **capsule_header_array,
efi_uintn_t capsule_count,
@@ -462,6 +597,20 @@ efi_status_t __efi_runtime EFIAPI efi_update_capsule(
return EFI_UNSUPPORTED;
}
+/**
+ * efi_query_capsule_caps() - check if capsule is supported
+ *
+ * This function implements the QueryCapsuleCapabilities() runtime service.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * @capsule_header_array: pointer to array of virtual pointers
+ * @capsule_count: number of pointers in capsule_header_array
+ * @capsule_size: maximum capsule size
+ * @reset_type: type of reset needed for capsule update
+ * Returns: status code
+ */
efi_status_t __efi_runtime EFIAPI efi_query_capsule_caps(
struct efi_capsule_header **capsule_header_array,
efi_uintn_t capsule_count,
@@ -471,6 +620,24 @@ efi_status_t __efi_runtime EFIAPI efi_query_capsule_caps(
return EFI_UNSUPPORTED;
}
+/**
+ * efi_query_variable_info() - get information about EFI variables
+ *
+ * This function implements the QueryVariableInfo() runtime service.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * @attributes: bitmask to select variables to be
+ * queried
+ * @maximum_variable_storage_size: maximum size of storage area for the
+ * selected variable types
+ * @remaining_variable_storage_size: remaining size of storage are for the
+ * selected variable types
+ * @maximum_variable_size: maximum size of a variable of the
+ * selected type
+ * Returns: status code
+ */
efi_status_t __efi_runtime EFIAPI efi_query_variable_info(
u32 attributes,
u64 *maximum_variable_storage_size,