diff options
Diffstat (limited to 'lib/efi_loader')
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 15 | ||||
-rw-r--r-- | lib/efi_loader/efi_console.c | 22 | ||||
-rw-r--r-- | lib/efi_loader/efi_memory.c | 13 | ||||
-rw-r--r-- | lib/efi_loader/efi_runtime.c | 177 |
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, |