From 60f7b43349c2ed961459a1902165a41799d58c90 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Sun, 25 Jan 2015 16:50:58 -0500 Subject: [PATCH 1/5] EFI: Call GetNextVariableName during normal init. Along with some extra debugging code to help diagnose the issue. Signed-off-by: Konrad Rzeszutek Wilk --- xen/arch/x86/efi/stub.c | 1 + xen/arch/x86/setup.c | 7 +++ xen/common/efi/boot.c | 3 + xen/common/efi/runtime.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++- xen/include/xen/efi.h | 1 + 5 files changed, 159 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/efi/stub.c b/xen/arch/x86/efi/stub.c index b8f49f8..cefd18d 100644 --- a/xen/arch/x86/efi/stub.c +++ b/xen/arch/x86/efi/stub.c @@ -21,6 +21,7 @@ unsigned long efi_get_time(void) return 0; } +long efi_debug(void) { return -ENOSYS; } void efi_halt_system(void) { } void efi_reset_system(bool_t warm) { } diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 39f2a4d..f82e3c0 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -1316,6 +1316,13 @@ void __init noreturn __start_xen(unsigned long mbi_p) console_init_postirq(); + if ( efi_enabled ) + { + long ret = efi_debug(); + if ( ret ) + printk("efi_debug return code: %lx\n", ret); + } + system_state = SYS_STATE_smp_boot; do_presmp_initcalls(); diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c index ac6881e..c04e0a2 100644 --- a/xen/common/efi/boot.c +++ b/xen/common/efi/boot.c @@ -1163,7 +1163,10 @@ void __init efi_init_memory(void) desc->Type, desc->Attribute); if ( !efi_rs_enable || !(desc->Attribute & EFI_MEMORY_RUNTIME) ) + { + printk(XENLOG_INFO " .. skipped!\n"); continue; + } desc->VirtualStart = INVALID_VIRTUAL_ADDRESS; diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c index c840e08..ef6b1df 100644 --- a/xen/common/efi/runtime.c +++ b/xen/common/efi/runtime.c @@ -5,7 +5,8 @@ #include #include #include - +#include +#include DEFINE_XEN_GUEST_HANDLE(CHAR16); #ifndef COMPAT @@ -128,6 +129,151 @@ unsigned long efi_get_time(void) time.Hour, time.Minute, time.Second); } +static void _delay(void) +{ + unsigned int i; + + printk("Delay of 3 seconds: "); + for (i = 0; i < 3; i++) + { + unsigned int j; + printk("..%d", (3 - i)); + for (j = 0; j < 100; j++) + { + process_pending_softirqs(); + mdelay(10); + } + } + printk("\n"); +} +#define DUMP_LEN 1024 +static void __init _dumpcode(unsigned long s, unsigned long e) +{ + unsigned long idx, e_idx; + unsigned long cr3; + unsigned int i; + char *code; + + if ( s > e ) + return; + + idx = s; + + code = xzalloc_bytes(DUMP_LEN); + if ( !code ) + return; + + printk("%lx -> %lx\nCode:", s, e); + do { + e_idx = idx + DUMP_LEN - 1; + if ( e_idx > e ) + e_idx = e; + + process_pending_softirqs(); + + memset(code, 0, DUMP_LEN); + + cr3 = efi_rs_enter(); + memcpy(code, (void *)idx, e_idx - idx); + efi_rs_leave(cr3); + + for ( i = 0; i < e_idx - idx ;i++) + { + if ( i & 0xFF ) + process_pending_softirqs(); + printk(" %02x", (unsigned short)code[i] & 0xFF); + } + printk("\n"); + idx = e_idx + 1; + } while ( idx < e ); + xfree(code); + printk("\n"); + _delay(); +} + +long __init efi_debug(void) +{ + unsigned long cr3 = efi_rs_enter(); + union { + CHAR16 *str; + unsigned char *raw; + } name; + char *p; + UINTN size = 1024; + struct xenpf_efi_guid guid; + EFI_STATUS status; + unsigned int i, idx; + unsigned int rev; + unsigned long get; + + if ( !cr3 ) + return -EOPNOTSUPP; + efi_rs_leave(cr3); + + name.raw = xzalloc_bytes(size); + if ( !name.raw ) + return -ENOMEM; + + p = xzalloc_bytes(size); + if ( !p ) + { + xfree(name.raw); + return -ENOMEM; + } + + printk("EFI v"); + + cr3 = efi_rs_enter(); + rev = efi_rs->Hdr.Revision; + efi_rs_leave(cr3); + + printk("%d.%d", rev >> 16, rev & 0xF); + + cr3 = efi_rs_enter(); + get = (unsigned long)efi_rs->GetNextVariableName; + efi_rs_leave(cr3); + + printk(", GetNextVariableName: %lx\n", get); + + _dumpcode(get, get+1024); + + idx = 1; + do { + printk("%4d:", idx++); + + cr3 = efi_rs_enter(); + if ( !cr3 ) + break; + + size = 1024; + status = efi_rs->GetNextVariableName(&size, name.str, (void *)&guid); + efi_rs_leave(cr3); + + if ( !EFI_ERROR(status) ) + { + unsigned int j; + + printk("%04x-%02x-%02x-", guid.data1, guid.data2, guid.data3); + for ( i = 0; i < 8; i++) + printk("-%02x", guid.data4[i]); + + for ( i = 0, j = 0; i < size && j < size / sizeof(CHAR16); i++, j++) + p[j] = name.str[i] & 0xFF; + + p[j] = '\0'; + printk(": %s [%lx]\n", p, status); + } else + printk("EFI_ERROR: %lx\n", status); + } while ( !EFI_ERROR(status) ); + + xfree(p); + xfree(name.raw); + + if ( EFI_ERROR(EFI_NOT_FOUND) ) + return 0; + + return status; +} void efi_halt_system(void) { EFI_STATUS status; diff --git a/xen/include/xen/efi.h b/xen/include/xen/efi.h index 5e02724..4e9ffbf 100644 --- a/xen/include/xen/efi.h +++ b/xen/include/xen/efi.h @@ -30,6 +30,7 @@ struct compat_pf_efi_runtime_call; void efi_init_memory(void); paddr_t efi_rs_page_table(void); unsigned long efi_get_time(void); +long efi_debug(void); void efi_halt_system(void); void efi_reset_system(bool_t warm); #ifndef COMPAT -- 2.1.0