All of lore.kernel.org
 help / color / mirror / Atom feed
From: Roy Franz <roy.franz@linaro.org>
To: xen-devel@lists.xen.org, ian.campbell@citrix.com,
	stefano.stabellini@citrix.com, tim@xen.org, jbeulich@suse.com,
	keir@xen.org
Cc: Roy Franz <roy.franz@linaro.org>,
	fu.wei@linaro.org, linaro-uefi@lists.linaro.org
Subject: [PATCH V2 09/12] Move shared EFI functions to efi-shared.c
Date: Mon, 21 Jul 2014 17:43:32 -0700	[thread overview]
Message-ID: <1405989815-25236-10-git-send-email-roy.franz@linaro.org> (raw)
In-Reply-To: <1405989815-25236-1-git-send-email-roy.franz@linaro.org>

Move all of the shareable functions from boot.c to the the shared EFI
code.  These functions will be used by the arm64 EFI stub.

Signed-off-by: Roy Franz <roy.franz@linaro.org>
---
 xen/arch/x86/efi/boot.c      | 501 ------------------------------------------
 xen/common/efi/efi-shared.c  | 506 +++++++++++++++++++++++++++++++++++++++++++
 xen/include/efi/efi-shared.h |  22 ++
 3 files changed, 528 insertions(+), 501 deletions(-)

diff --git a/xen/arch/x86/efi/boot.c b/xen/arch/x86/efi/boot.c
index edbdb8a..348e237 100644
--- a/xen/arch/x86/efi/boot.c
+++ b/xen/arch/x86/efi/boot.c
@@ -7,7 +7,6 @@
 #include <xen/ctype.h>
 #include <xen/dmi.h>
 #include <xen/init.h>
-#include <xen/keyhandler.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
 #include <xen/multiboot.h>
@@ -91,55 +90,6 @@ static void __init noreturn blexit(const CHAR16 *str)
     unreachable(); /* not reached */
 }
 
-/* generic routine for printing error messages */
-void __init PrintErrMesg(const CHAR16 *mesg, EFI_STATUS ErrCode)
-{
-    StdOut = StdErr;
-    PrintErr((CHAR16 *)mesg);
-    PrintErr(L": ");
-
-    switch (ErrCode)
-    {
-    case EFI_NOT_FOUND:
-        mesg = L"Not found";
-        break;
-    case EFI_NO_MEDIA:
-        mesg = L"The device has no media";
-        break;
-    case EFI_MEDIA_CHANGED:
-        mesg = L"Media changed";
-        break;
-    case EFI_DEVICE_ERROR:
-        mesg = L"Device error";
-        break;
-    case EFI_VOLUME_CORRUPTED:
-        mesg = L"Volume corrupted";
-        break;
-    case EFI_ACCESS_DENIED:
-        mesg = L"Access denied";
-        break;
-    case EFI_OUT_OF_RESOURCES:
-        mesg = L"Out of resources";
-        break;
-    case EFI_VOLUME_FULL:
-        mesg = L"Volume is full";
-        break;
-    case EFI_SECURITY_VIOLATION:
-        mesg = L"Security violation";
-        break;
-    case EFI_CRC_ERROR:
-        mesg = L"CRC error";
-        break;
-    case EFI_COMPROMISED_DATA:
-        mesg = L"Compromised data";
-        break;
-    default:
-        PrintErr(L"ErrCode: ");
-        DisplayUint(ErrCode, 0);
-        mesg = NULL;
-        break;
-    }
-}
 
 /* generic routine for printing error messages */
 static void __init PrintErrMesgExit(const CHAR16 *mesg, EFI_STATUS ErrCode)
@@ -174,311 +124,6 @@ static void __init place_string(u32 *addr, const char *s)
     *addr = (long)alloc;
 }
 
-static unsigned int __init get_argv(unsigned int argc, CHAR16 **argv,
-                                    CHAR16 *cmdline, UINTN cmdsize,
-                                    CHAR16 **cmdline_remain)
-{
-    CHAR16 *ptr = (CHAR16 *)(argv + argc + 1), *prev = NULL;
-    bool_t prev_sep = TRUE;
-
-    for ( ; cmdsize > sizeof(*cmdline) && *cmdline;
-            cmdsize -= sizeof(*cmdline), ++cmdline )
-    {
-        bool_t cur_sep = *cmdline == L' ' || *cmdline == L'\t';
-
-        if ( !prev_sep )
-        {
-            if ( cur_sep )
-                ++ptr;
-            else if ( argv )
-            {
-                *ptr = *cmdline;
-                *++ptr = 0;
-            }
-        }
-        else if ( !cur_sep )
-        {
-            if ( !argv )
-                ++argc;
-            else if ( prev && wstrcmp(prev, L"--") == 0 )
-            {
-                --argv;
-                if (**cmdline_remain)
-                    *cmdline_remain = cmdline;
-                break;
-            }
-            else
-            {
-                *argv++ = prev = ptr;
-                *ptr = *cmdline;
-                *++ptr = 0;
-            }
-        }
-        prev_sep = cur_sep;
-    }
-    if ( argv )
-        *argv = NULL;
-    return argc;
-}
-
-static EFI_FILE_HANDLE __init get_parent_handle(EFI_LOADED_IMAGE *loaded_image,
-                                                CHAR16 **leaf)
-{
-    static EFI_GUID __initdata fs_protocol = SIMPLE_FILE_SYSTEM_PROTOCOL;
-    EFI_FILE_HANDLE dir_handle;
-    EFI_DEVICE_PATH *dp;
-    CHAR16 *pathend, *ptr;
-    EFI_STATUS ret;
-
-    do {
-        EFI_FILE_IO_INTERFACE *fio;
-
-        /* Get the file system interface. */
-        ret = efi_bs->HandleProtocol(loaded_image->DeviceHandle,
-                                     &fs_protocol, (void **)&fio);
-        if ( EFI_ERROR(ret) )
-        {
-            PrintErrMesg(L"Couldn't obtain the File System Protocol Interface",
-                         ret);
-            return NULL;
-        }
-        ret = fio->OpenVolume(fio, &dir_handle);
-    } while ( ret == EFI_MEDIA_CHANGED );
-    if ( ret != EFI_SUCCESS )
-    {
-        PrintErrMesg(L"OpenVolume failure", ret);
-        return NULL;
-    }
-
-#define buffer ((CHAR16 *)keyhandler_scratch)
-#define BUFFERSIZE sizeof(keyhandler_scratch)
-    for ( dp = loaded_image->FilePath, *buffer = 0;
-          DevicePathType(dp) != END_DEVICE_PATH_TYPE;
-          dp = (void *)dp + DevicePathNodeLength(dp) )
-    {
-        FILEPATH_DEVICE_PATH *fp;
-
-        if ( DevicePathType(dp) != MEDIA_DEVICE_PATH ||
-             DevicePathSubType(dp) != MEDIA_FILEPATH_DP )
-        {
-            PrintErr(L"Unsupported device path component");
-            return NULL;
-        }
-
-        if ( *buffer )
-        {
-            EFI_FILE_HANDLE new_handle;
-
-            ret = dir_handle->Open(dir_handle, &new_handle, buffer,
-                                   EFI_FILE_MODE_READ, 0);
-            if ( ret != EFI_SUCCESS )
-            {
-                PrintErr(L"Open failed for ");
-                PrintErrMesg(buffer, ret);
-                return NULL;
-            }
-            dir_handle->Close(dir_handle);
-            dir_handle = new_handle;
-        }
-        fp = (void *)dp;
-        if ( BUFFERSIZE < DevicePathNodeLength(dp) -
-                          sizeof(*dp) + sizeof(*buffer) )
-        {
-            PrintErr(L"Increase BUFFERSIZE");
-            return NULL;
-        }
-        memcpy(buffer, fp->PathName, DevicePathNodeLength(dp) - sizeof(*dp));
-        buffer[(DevicePathNodeLength(dp) - sizeof(*dp)) / sizeof(*buffer)] = 0;
-    }
-    for ( ptr = buffer, pathend = NULL; *ptr; ++ptr )
-        if ( *ptr == L'\\' )
-            pathend = ptr;
-    if ( pathend )
-    {
-        *pathend = 0;
-        *leaf = pathend + 1;
-        if ( *buffer )
-        {
-            EFI_FILE_HANDLE new_handle;
-
-            ret = dir_handle->Open(dir_handle, &new_handle, buffer,
-                                   EFI_FILE_MODE_READ, 0);
-            if ( ret != EFI_SUCCESS ) {
-                PrintErr(L"Open failed for ");
-                PrintErrMesg(buffer, ret);
-                return NULL;
-            }
-            dir_handle->Close(dir_handle);
-            dir_handle = new_handle;
-        }
-    }
-    else
-        *leaf = buffer;
-#undef BUFFERSIZE
-#undef buffer
-
-    return dir_handle;
-}
-
-static CHAR16 *__init point_tail(CHAR16 *fn)
-{
-    CHAR16 *tail = NULL;
-
-    for ( ; ; ++fn )
-        switch ( *fn )
-        {
-        case 0:
-            return tail;
-        case L'.':
-        case L'-':
-        case L'_':
-            tail = fn;
-            break;
-        }
-}
-
-static bool_t __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
-                               struct file *file, EFI_PHYSICAL_ADDRESS max_addr)
-{
-    EFI_FILE_HANDLE FileHandle = NULL;
-    UINT64 size;
-    EFI_STATUS ret;
-    CHAR16 *what = NULL;
-
-    if ( !name )
-    {
-        PrintErrMesg(L"No Filename", EFI_OUT_OF_RESOURCES);
-        return 0;
-    }
-
-    ret = dir_handle->Open(dir_handle, &FileHandle, name,
-                           EFI_FILE_MODE_READ, 0);
-
-    if ( EFI_ERROR(ret) )
-        what = L"Open";
-    else
-        ret = FileHandle->SetPosition(FileHandle, -1);
-    if ( EFI_ERROR(ret) )
-        what = what ?: L"Seek";
-    else
-        ret = FileHandle->GetPosition(FileHandle, &size);
-    if ( EFI_ERROR(ret) )
-        what = what ?: L"Get size";
-    else
-        ret = FileHandle->SetPosition(FileHandle, 0);
-    if ( EFI_ERROR(ret) )
-        what = what ?: L"Seek";
-    else
-    {
-        file->addr = max_addr;
-        ret = efi_bs->AllocatePages(AllocateMaxAddress, EfiLoaderData,
-                                    PFN_UP(size), &file->addr);
-    }
-    if ( EFI_ERROR(ret) )
-    {
-        file->addr = 0;
-        what = what ?: L"Allocation";
-    }
-    else
-    {
-
-        file->size = size;
-        ret = FileHandle->Read(FileHandle, &file->size, file->ptr);
-        if ( !EFI_ERROR(ret) && file->size != size )
-            ret = EFI_ABORTED;
-        if ( EFI_ERROR(ret) )
-        {
-            what = what ?: L"Read";
-            efi_bs->FreePages(file->addr, PFN_UP(file->size));
-            file->addr = 0;
-        }
-    }
-
-    if ( FileHandle )
-        FileHandle->Close(FileHandle);
-
-    if ( what )
-    {
-        PrintErrMesg(what, ret);
-        PrintErr(L"Unable to load file");
-        return 0;
-    }
-    else
-    {
-        PrintStr(name);
-        PrintStr(L": ");
-        DisplayUint(file->addr, 2 * sizeof(file->addr));
-        PrintStr(L"-");
-        DisplayUint(file->addr + file->size, 2 * sizeof(file->addr));
-        PrintStr(newline);
-        return 1;
-    }
-
-}
-
-static void __init pre_parse(const struct file *cfg)
-{
-    char *ptr = cfg->ptr, *end = ptr + cfg->size;
-    bool_t start = 1, comment = 0;
-
-    for ( ; ptr < end; ++ptr )
-    {
-        if ( iscntrl(*ptr) )
-        {
-            comment = 0;
-            start = 1;
-            *ptr = 0;
-        }
-        else if ( comment || (start && isspace(*ptr)) )
-            *ptr = 0;
-        else if ( *ptr == '#' || (start && *ptr == ';') )
-        {
-            comment = 1;
-            *ptr = 0;
-        }
-        else
-            start = 0;
-    }
-    if ( cfg->size && end[-1] )
-         PrintStr(L"No newline at end of config file,"
-                   " last line will be ignored.\r\n");
-}
-
-static char *__init get_value(const struct file *cfg, const char *section,
-                              const char *item)
-{
-    char *ptr = cfg->ptr, *end = ptr + cfg->size;
-    size_t slen = section ? strlen(section) : 0, ilen = strlen(item);
-    bool_t match = !slen;
-
-    for ( ; ptr < end; ++ptr )
-    {
-        switch ( *ptr )
-        {
-        case 0:
-            continue;
-        case '[':
-            if ( !slen )
-                break;
-            if ( match )
-                return NULL;
-            match = strncmp(++ptr, section, slen) == 0 && ptr[slen] == ']';
-            break;
-        default:
-            if ( match && strncmp(ptr, item, ilen) == 0 && ptr[ilen] == '=' )
-            {
-                ptr += ilen + 1;
-                /* strip off any leading spaces */
-                while ( *ptr && isspace(*ptr) )
-                    ptr++;
-                return ptr;
-            }
-            break;
-        }
-        ptr += strlen(ptr);
-    }
-    return NULL;
-}
 /* Only call with non-config files. */
 bool_t __init load_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
                                struct file *file)
@@ -495,85 +140,6 @@ bool_t __init load_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
     return 0;
 }
 
-/* Truncate string at first space, and return pointer
- * to remainder of string.
- */
-char * __init truncate_string(char *s)
-{
-    while ( *s && !isspace(*s) )
-        ++s;
-    if (*s)
-    {
-        *s = 0;
-        return(s + 1);
-    }
-    return(NULL);
-}
-
-bool_t __init read_config_file(EFI_FILE_HANDLE *cfg_dir_handle,
-                             struct file *cfg, CHAR16 *cfg_file_name,
-                             union string *section,
-                             CHAR16 *xen_file_name)
-{
-    /*
-     * This allocation is internal to the EFI stub, so any address is
-     * fine.
-     */
-    EFI_PHYSICAL_ADDRESS max = ~0;
-
-    /* Read and parse the config file. */
-    if ( !cfg_file_name )
-    {
-        CHAR16 *tail;
-
-        while ( (tail = point_tail(xen_file_name)) != NULL )
-        {
-            wstrcpy(tail, L".cfg");
-            if ( read_file(*cfg_dir_handle, xen_file_name, cfg, max) )
-                break;
-            *tail = 0;
-        }
-        if ( !tail )
-            return 0;
-        PrintStr(L"Using configuration file '");
-        PrintStr(xen_file_name);
-        PrintStr(L"'\r\n");
-    }
-    else if ( !read_file(*cfg_dir_handle, cfg_file_name, cfg, max) )
-        return 0;
-    pre_parse(cfg);
-
-    if ( section->w )
-        w2s(section);
-    else
-        section->s = get_value(cfg, "global", "default");
-
-
-    for ( ; ; )
-    {
-        union string dom0_kernel_name;
-        dom0_kernel_name.s = get_value(cfg, section->s, "kernel");
-        if ( dom0_kernel_name.s )
-            break;
-        dom0_kernel_name.s = get_value(cfg, "global", "chain");
-        if ( !dom0_kernel_name.s )
-            break;
-        efi_bs->FreePages(cfg->addr, PFN_UP(cfg->size));
-        cfg->addr = 0;
-        if ( !read_file(*cfg_dir_handle, s2w(&dom0_kernel_name), cfg, max) )
-        {
-            PrintStr(L"Chained configuration file '");
-            PrintStr(dom0_kernel_name.w);
-            efi_bs->FreePool(dom0_kernel_name.w);
-            PrintStr(L"'not found.");
-            return 0;
-        }
-        pre_parse(cfg);
-        efi_bs->FreePool(dom0_kernel_name.w);
-    }
-    return 1;
-}
-
 static void __init edd_put_string(u8 *dst, size_t n, const char *src)
 {
     while ( n-- && *src )
@@ -745,73 +311,6 @@ static void __init relocate_image(unsigned long delta)
 }
 
 
-bool_t __init handle_cmdline(EFI_LOADED_IMAGE *loaded_image,
-                           CHAR16 **cfg_file_name, bool_t *base_video,
-                           CHAR16 **image_name, CHAR16 **section_name,
-                           CHAR16 **cmdline_remain)
-{
-
-    unsigned int i, argc;
-    CHAR16 **argv;
-
-
-    if ( !cfg_file_name || !base_video || !image_name )
-    {
-        PrintStr(L"Invalid args to handle_cmdline\r\n");
-        return 0;
-    }
-
-    argc = get_argv(0, NULL, loaded_image->LoadOptions,
-                    loaded_image->LoadOptionsSize, NULL);
-    if ( argc > 0 &&
-         efi_bs->AllocatePool(EfiLoaderData,
-                              (argc + 1) * sizeof(*argv) +
-                                  loaded_image->LoadOptionsSize,
-                              (void **)&argv) == EFI_SUCCESS )
-        get_argv(argc, argv, loaded_image->LoadOptions,
-                 loaded_image->LoadOptionsSize, cmdline_remain);
-    else
-        argc = 0;
-
-    for ( i = 1; i < argc; ++i )
-    {
-        CHAR16 *ptr = argv[i];
-
-        if ( !ptr )
-            break;
-        if ( *ptr == L'/' || *ptr == L'-' )
-        {
-            if ( wstrcmp(ptr + 1, L"basevideo") == 0 )
-                *base_video = 1;
-            else if ( wstrncmp(ptr + 1, L"cfg=", 4) == 0 )
-                *cfg_file_name = ptr + 5;
-            else if ( i + 1 < argc && wstrcmp(ptr + 1, L"cfg") == 0 )
-                *cfg_file_name = argv[++i];
-            else if ( wstrcmp(ptr + 1, L"help") == 0 ||
-                      (ptr[1] == L'?' && !ptr[2]) )
-            {
-                PrintStr(L"Xen EFI Loader options:\r\n");
-                PrintStr(L"-basevideo   retain current video mode\r\n");
-                PrintStr(L"-cfg=<file>  specify configuration file\r\n");
-                PrintStr(L"-help, -?    display this help\r\n");
-                return 0;
-            }
-            else
-            {
-                PrintStr(L"WARNING: Unknown command line option '");
-                PrintStr(ptr);
-                PrintStr(L"' ignored\r\n");
-            }
-        }
-        else
-            *section_name = ptr;
-    }
-
-    if ( argc )
-        *image_name = *argv;
-
-    return 1;
-}
 
 extern const s32 __trampoline_rel_start[], __trampoline_rel_stop[];
 extern const s32 __trampoline_seg_start[], __trampoline_seg_stop[];
diff --git a/xen/common/efi/efi-shared.c b/xen/common/efi/efi-shared.c
index b990292..835121d 100644
--- a/xen/common/efi/efi-shared.c
+++ b/xen/common/efi/efi-shared.c
@@ -19,6 +19,11 @@
 #include <xen/ctype.h>
 #include <xen/init.h>
 #include <asm/processor.h>
+#include <xen/keyhandler.h>
+#include <xen/pfn.h>
+#if EFI_PAGE_SIZE != PAGE_SIZE
+# error Cannot use xen/pfn.h here!
+#endif
 
 
 SIMPLE_TEXT_OUTPUT_INTERFACE *__initdata StdOut;
@@ -131,6 +136,507 @@ bool_t __init match_guid(const EFI_GUID *guid1, const EFI_GUID *guid2)
 }
 
 
+/* generic routine for printing error messages */
+void __init PrintErrMesg(const CHAR16 *mesg, EFI_STATUS ErrCode)
+{
+    StdOut = StdErr;
+    PrintErr((CHAR16 *)mesg);
+    PrintErr(L": ");
+
+    switch (ErrCode)
+    {
+    case EFI_NOT_FOUND:
+        mesg = L"Not found";
+        break;
+    case EFI_NO_MEDIA:
+        mesg = L"The device has no media";
+        break;
+    case EFI_MEDIA_CHANGED:
+        mesg = L"Media changed";
+        break;
+    case EFI_DEVICE_ERROR:
+        mesg = L"Device error";
+        break;
+    case EFI_VOLUME_CORRUPTED:
+        mesg = L"Volume corrupted";
+        break;
+    case EFI_ACCESS_DENIED:
+        mesg = L"Access denied";
+        break;
+    case EFI_OUT_OF_RESOURCES:
+        mesg = L"Out of resources";
+        break;
+    case EFI_VOLUME_FULL:
+        mesg = L"Volume is full";
+        break;
+    case EFI_SECURITY_VIOLATION:
+        mesg = L"Security violation";
+        break;
+    case EFI_CRC_ERROR:
+        mesg = L"CRC error";
+        break;
+    case EFI_COMPROMISED_DATA:
+        mesg = L"Compromised data";
+        break;
+    default:
+        PrintErr(L"ErrCode: ");
+        DisplayUint(ErrCode, 0);
+        mesg = NULL;
+        break;
+    }
+}
+
+
+EFI_FILE_HANDLE __init get_parent_handle(EFI_LOADED_IMAGE *loaded_image,
+                                         CHAR16 **leaf)
+{
+    static EFI_GUID __initdata fs_protocol = SIMPLE_FILE_SYSTEM_PROTOCOL;
+    EFI_FILE_HANDLE dir_handle;
+    EFI_DEVICE_PATH *dp;
+    CHAR16 *pathend, *ptr;
+    EFI_STATUS ret;
+
+    do {
+        EFI_FILE_IO_INTERFACE *fio;
+
+        /* Get the file system interface. */
+        ret = efi_bs->HandleProtocol(loaded_image->DeviceHandle,
+                                     &fs_protocol, (void **)&fio);
+        if ( EFI_ERROR(ret) )
+        {
+            PrintErrMesg(L"Couldn't obtain the File System Protocol Interface",
+                         ret);
+            return NULL;
+        }
+        ret = fio->OpenVolume(fio, &dir_handle);
+    } while ( ret == EFI_MEDIA_CHANGED );
+    if ( ret != EFI_SUCCESS )
+    {
+        PrintErrMesg(L"OpenVolume failure", ret);
+        return NULL;
+    }
+
+#define buffer ((CHAR16 *)keyhandler_scratch)
+#define BUFFERSIZE sizeof(keyhandler_scratch)
+    for ( dp = loaded_image->FilePath, *buffer = 0;
+          DevicePathType(dp) != END_DEVICE_PATH_TYPE;
+          dp = (void *)dp + DevicePathNodeLength(dp) )
+    {
+        FILEPATH_DEVICE_PATH *fp;
+
+        if ( DevicePathType(dp) != MEDIA_DEVICE_PATH ||
+             DevicePathSubType(dp) != MEDIA_FILEPATH_DP )
+        {
+            PrintErr(L"Unsupported device path component");
+            return NULL;
+        }
+
+        if ( *buffer )
+        {
+            EFI_FILE_HANDLE new_handle;
+
+            ret = dir_handle->Open(dir_handle, &new_handle, buffer,
+                                   EFI_FILE_MODE_READ, 0);
+            if ( ret != EFI_SUCCESS )
+            {
+                PrintErr(L"Open failed for ");
+                PrintErrMesg(buffer, ret);
+                return NULL;
+            }
+            dir_handle->Close(dir_handle);
+            dir_handle = new_handle;
+        }
+        fp = (void *)dp;
+        if ( BUFFERSIZE < DevicePathNodeLength(dp) -
+                          sizeof(*dp) + sizeof(*buffer) )
+        {
+            PrintErr(L"Increase BUFFERSIZE");
+            return NULL;
+        }
+        memcpy(buffer, fp->PathName, DevicePathNodeLength(dp) - sizeof(*dp));
+        buffer[(DevicePathNodeLength(dp) - sizeof(*dp)) / sizeof(*buffer)] = 0;
+    }
+    for ( ptr = buffer, pathend = NULL; *ptr; ++ptr )
+        if ( *ptr == L'\\' )
+            pathend = ptr;
+    if ( pathend )
+    {
+        *pathend = 0;
+        *leaf = pathend + 1;
+        if ( *buffer )
+        {
+            EFI_FILE_HANDLE new_handle;
+
+            ret = dir_handle->Open(dir_handle, &new_handle, buffer,
+                                   EFI_FILE_MODE_READ, 0);
+            if ( ret != EFI_SUCCESS ) {
+                PrintErr(L"Open failed for ");
+                PrintErrMesg(buffer, ret);
+                return NULL;
+            }
+            dir_handle->Close(dir_handle);
+            dir_handle = new_handle;
+        }
+    }
+    else
+        *leaf = buffer;
+#undef BUFFERSIZE
+#undef buffer
+
+    return dir_handle;
+}
+
+CHAR16 *__init point_tail(CHAR16 *fn)
+{
+    CHAR16 *tail = NULL;
+
+    for ( ; ; ++fn )
+        switch ( *fn )
+        {
+        case 0:
+            return tail;
+        case L'.':
+        case L'-':
+        case L'_':
+            tail = fn;
+            break;
+        }
+}
+
+bool_t __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
+                               struct file *file, EFI_PHYSICAL_ADDRESS max_addr)
+{
+    EFI_FILE_HANDLE FileHandle = NULL;
+    UINT64 size;
+    EFI_STATUS ret;
+    CHAR16 *what = NULL;
+
+    if ( !name )
+    {
+        PrintErrMesg(L"No Filename", EFI_OUT_OF_RESOURCES);
+        return 0;
+    }
+
+    ret = dir_handle->Open(dir_handle, &FileHandle, name,
+                           EFI_FILE_MODE_READ, 0);
+
+    if ( EFI_ERROR(ret) )
+        what = L"Open";
+    else
+        ret = FileHandle->SetPosition(FileHandle, -1);
+    if ( EFI_ERROR(ret) )
+        what = what ?: L"Seek";
+    else
+        ret = FileHandle->GetPosition(FileHandle, &size);
+    if ( EFI_ERROR(ret) )
+        what = what ?: L"Get size";
+    else
+        ret = FileHandle->SetPosition(FileHandle, 0);
+    if ( EFI_ERROR(ret) )
+        what = what ?: L"Seek";
+    else
+    {
+        file->addr = max_addr;
+        ret = efi_bs->AllocatePages(AllocateMaxAddress, EfiLoaderData,
+                                    PFN_UP(size), &file->addr);
+    }
+    if ( EFI_ERROR(ret) )
+    {
+        file->addr = 0;
+        what = what ?: L"Allocation";
+    }
+    else
+    {
+
+        file->size = size;
+        ret = FileHandle->Read(FileHandle, &file->size, file->ptr);
+        if ( !EFI_ERROR(ret) && file->size != size )
+            ret = EFI_ABORTED;
+        if ( EFI_ERROR(ret) )
+        {
+            what = what ?: L"Read";
+            efi_bs->FreePages(file->addr, PFN_UP(file->size));
+            file->addr = 0;
+        }
+    }
+
+    if ( FileHandle )
+        FileHandle->Close(FileHandle);
+
+    if ( what )
+    {
+        PrintErrMesg(what, ret);
+        PrintErr(L"Unable to load file");
+        return 0;
+    }
+    else
+    {
+        PrintStr(name);
+        PrintStr(L": ");
+        DisplayUint(file->addr, 2 * sizeof(file->addr));
+        PrintStr(L"-");
+        DisplayUint(file->addr + file->size, 2 * sizeof(file->addr));
+        PrintStr(newline);
+        return 1;
+    }
+
+}
+
+void __init pre_parse(const struct file *cfg)
+{
+    char *ptr = cfg->ptr, *end = ptr + cfg->size;
+    bool_t start = 1, comment = 0;
+
+    for ( ; ptr < end; ++ptr )
+    {
+        if ( iscntrl(*ptr) )
+        {
+            comment = 0;
+            start = 1;
+            *ptr = 0;
+        }
+        else if ( comment || (start && isspace(*ptr)) )
+            *ptr = 0;
+        else if ( *ptr == '#' || (start && *ptr == ';') )
+        {
+            comment = 1;
+            *ptr = 0;
+        }
+        else
+            start = 0;
+    }
+    if ( cfg->size && end[-1] )
+         PrintStr(L"No newline at end of config file,"
+                   " last line will be ignored.\r\n");
+}
+
+char *__init get_value(const struct file *cfg, const char *section,
+                       const char *item)
+{
+    char *ptr = cfg->ptr, *end = ptr + cfg->size;
+    size_t slen = section ? strlen(section) : 0, ilen = strlen(item);
+    bool_t match = !slen;
+
+    for ( ; ptr < end; ++ptr )
+    {
+        switch ( *ptr )
+        {
+        case 0:
+            continue;
+        case '[':
+            if ( !slen )
+                break;
+            if ( match )
+                return NULL;
+            match = strncmp(++ptr, section, slen) == 0 && ptr[slen] == ']';
+            break;
+        default:
+            if ( match && strncmp(ptr, item, ilen) == 0 && ptr[ilen] == '=' )
+            {
+                ptr += ilen + 1;
+                /* strip off any leading spaces */
+                while ( *ptr && isspace(*ptr) )
+                    ptr++;
+                return ptr;
+            }
+            break;
+        }
+        ptr += strlen(ptr);
+    }
+    return NULL;
+}
+
+/* Truncate string at first space, and return pointer
+ * to remainder of string.
+ */
+char * __init truncate_string(char *s)
+{
+    while ( *s && !isspace(*s) )
+        ++s;
+    if (*s)
+    {
+        *s = 0;
+        return(s + 1);
+    }
+    return(NULL);
+}
+
+unsigned int __init get_argv(unsigned int argc, CHAR16 **argv, CHAR16 *cmdline,
+                             UINTN cmdsize, CHAR16 **cmdline_remain)
+{
+    CHAR16 *ptr = (CHAR16 *)(argv + argc + 1), *prev = NULL;
+    bool_t prev_sep = TRUE;
+
+    for ( ; cmdsize > sizeof(*cmdline) && *cmdline;
+            cmdsize -= sizeof(*cmdline), ++cmdline )
+    {
+        bool_t cur_sep = *cmdline == L' ' || *cmdline == L'\t';
+
+        if ( !prev_sep )
+        {
+            if ( cur_sep )
+                ++ptr;
+            else if ( argv )
+            {
+                *ptr = *cmdline;
+                *++ptr = 0;
+            }
+        }
+        else if ( !cur_sep )
+        {
+            if ( !argv )
+                ++argc;
+            else if ( prev && wstrcmp(prev, L"--") == 0 )
+            {
+                --argv;
+                if (**cmdline_remain)
+                    *cmdline_remain = cmdline;
+                break;
+            }
+            else
+            {
+                *argv++ = prev = ptr;
+                *ptr = *cmdline;
+                *++ptr = 0;
+            }
+        }
+        prev_sep = cur_sep;
+    }
+    if ( argv )
+        *argv = NULL;
+    return argc;
+}
+
+bool_t __init read_config_file(EFI_FILE_HANDLE *cfg_dir_handle,
+                             struct file *cfg, CHAR16 *cfg_file_name,
+                             union string *section,
+                             CHAR16 *xen_file_name)
+{
+    /*
+     * This allocation is internal to the EFI stub, so any address is
+     * fine.
+     */
+    EFI_PHYSICAL_ADDRESS max = ~0;
+
+    /* Read and parse the config file. */
+    if ( !cfg_file_name )
+    {
+        CHAR16 *tail;
+
+        while ( (tail = point_tail(xen_file_name)) != NULL )
+        {
+            wstrcpy(tail, L".cfg");
+            if ( read_file(*cfg_dir_handle, xen_file_name, cfg, max) )
+                break;
+            *tail = 0;
+        }
+        if ( !tail )
+            return 0;
+        PrintStr(L"Using configuration file '");
+        PrintStr(xen_file_name);
+        PrintStr(L"'\r\n");
+    }
+    else if ( !read_file(*cfg_dir_handle, cfg_file_name, cfg, max) )
+        return 0;
+    pre_parse(cfg);
+
+    if ( section->w )
+        w2s(section);
+    else
+        section->s = get_value(cfg, "global", "default");
+
+
+    for ( ; ; )
+    {
+        union string dom0_kernel_name;
+        dom0_kernel_name.s = get_value(cfg, section->s, "kernel");
+        if ( dom0_kernel_name.s )
+            break;
+        dom0_kernel_name.s = get_value(cfg, "global", "chain");
+        if ( !dom0_kernel_name.s )
+            break;
+        efi_bs->FreePages(cfg->addr, PFN_UP(cfg->size));
+        cfg->addr = 0;
+        if ( !read_file(*cfg_dir_handle, s2w(&dom0_kernel_name), cfg, max) )
+        {
+            PrintStr(L"Chained configuration file '");
+            PrintStr(dom0_kernel_name.w);
+            efi_bs->FreePool(dom0_kernel_name.w);
+            PrintStr(L"'not found.");
+            return 0;
+        }
+        pre_parse(cfg);
+        efi_bs->FreePool(dom0_kernel_name.w);
+    }
+    return 1;
+}
+bool_t __init handle_cmdline(EFI_LOADED_IMAGE *loaded_image,
+                           CHAR16 **cfg_file_name, bool_t *base_video,
+                           CHAR16 **image_name, CHAR16 **section_name,
+                           CHAR16 **cmdline_remain)
+{
+
+    unsigned int i, argc;
+    CHAR16 **argv;
+
+
+    if ( !cfg_file_name || !base_video || !image_name )
+    {
+        PrintStr(L"Invalid args to handle_cmdline\r\n");
+        return 0;
+    }
+
+    argc = get_argv(0, NULL, loaded_image->LoadOptions,
+                    loaded_image->LoadOptionsSize, NULL);
+    if ( argc > 0 &&
+         efi_bs->AllocatePool(EfiLoaderData,
+                              (argc + 1) * sizeof(*argv) +
+                                  loaded_image->LoadOptionsSize,
+                              (void **)&argv) == EFI_SUCCESS )
+        get_argv(argc, argv, loaded_image->LoadOptions,
+                 loaded_image->LoadOptionsSize, cmdline_remain);
+    else
+        argc = 0;
+
+    for ( i = 1; i < argc; ++i )
+    {
+        CHAR16 *ptr = argv[i];
+
+        if ( !ptr )
+            break;
+        if ( *ptr == L'/' || *ptr == L'-' )
+        {
+            if ( wstrcmp(ptr + 1, L"basevideo") == 0 )
+                *base_video = 1;
+            else if ( wstrncmp(ptr + 1, L"cfg=", 4) == 0 )
+                *cfg_file_name = ptr + 5;
+            else if ( i + 1 < argc && wstrcmp(ptr + 1, L"cfg") == 0 )
+                *cfg_file_name = argv[++i];
+            else if ( wstrcmp(ptr + 1, L"help") == 0 ||
+                      (ptr[1] == L'?' && !ptr[2]) )
+            {
+                PrintStr(L"Xen EFI Loader options:\r\n");
+                PrintStr(L"-basevideo   retain current video mode\r\n");
+                PrintStr(L"-cfg=<file>  specify configuration file\r\n");
+                PrintStr(L"-help, -?    display this help\r\n");
+                return 0;
+            }
+            else
+            {
+                PrintStr(L"WARNING: Unknown command line option '");
+                PrintStr(ptr);
+                PrintStr(L"' ignored\r\n");
+            }
+        }
+        else
+            *section_name = ptr;
+    }
+
+    if ( argc )
+        *image_name = *argv;
+
+    return 1;
+}
 /*
  * Local variables:
  * mode: C
diff --git a/xen/include/efi/efi-shared.h b/xen/include/efi/efi-shared.h
index 38f8f39..e559bca 100644
--- a/xen/include/efi/efi-shared.h
+++ b/xen/include/efi/efi-shared.h
@@ -36,6 +36,28 @@ CHAR16 *__init s2w(union string *str);
 char *__init w2s(const union string *str);
 bool_t __init match_guid(const EFI_GUID *guid1, const EFI_GUID *guid2);
 
+void __init PrintErrMesg(const CHAR16 *mesg, EFI_STATUS ErrCode);
+EFI_FILE_HANDLE __init get_parent_handle(EFI_LOADED_IMAGE *loaded_image,
+                                         CHAR16 **leaf);
+CHAR16 *__init point_tail(CHAR16 *fn);
+bool_t __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
+                               struct file *file, EFI_PHYSICAL_ADDRESS max_addr);
+void __init pre_parse(const struct file *cfg);
+char *__init get_value(const struct file *cfg, const char *section,
+                       const char *item);
+
+char * __init truncate_string(char *s);
+
+bool_t __init read_config_file(EFI_FILE_HANDLE *cfg_dir_handle,
+                             struct file *cfg, CHAR16 *cfg_file_name,
+                             union string *section,
+                             CHAR16 *xen_file_name);
+unsigned int __init get_argv(unsigned int argc, CHAR16 **argv, CHAR16 *cmdline,
+                             UINTN cmdsize, CHAR16 **cmdline_remain);
+bool_t __init handle_cmdline(EFI_LOADED_IMAGE *loaded_image,
+                           CHAR16 **cfg_file_name, bool_t *base_video,
+                           CHAR16 **image_name, CHAR16 **section_name,
+                           CHAR16 **cmdline_remain);
 #endif
 
 
-- 
2.0.0

  parent reply	other threads:[~2014-07-22  0:43 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-22  0:43 [PATCH V2 00/12] arm64 EFI stub Roy Franz
2014-07-22  0:43 ` [PATCH V2 01/12] Create efi-shared.[ch], and move string functions Roy Franz
2014-07-23 16:31   ` Jan Beulich
2014-07-28 15:41     ` Ian Campbell
2014-07-28 15:52       ` Jan Beulich
2014-07-28 15:56         ` Ian Campbell
2014-07-28 16:00           ` Jan Beulich
2014-07-28 16:04             ` Ian Campbell
2014-07-28 16:10               ` Jan Beulich
2014-08-06 23:55                 ` Roy Franz
2014-08-07  6:17                   ` Jan Beulich
2014-08-09  0:27                     ` Roy Franz
2014-08-06 23:42     ` Roy Franz
2014-07-22  0:43 ` [PATCH V2 02/12] rename printErrMsg to PrintErrMesgExit Roy Franz
2014-07-23 16:33   ` Jan Beulich
2014-07-22  0:43 ` [PATCH V2 03/12] Refactor get_parent_handle for sharing Roy Franz
2014-07-23 16:37   ` Jan Beulich
2014-07-22  0:43 ` [PATCH V2 04/12] Refactor read_file() so it can be shared Roy Franz
2014-07-24  7:09   ` Jan Beulich
2014-08-06 18:38     ` Roy Franz
2014-08-07  6:20       ` Jan Beulich
2014-08-07 17:26         ` Roy Franz
2014-07-22  0:43 ` [PATCH V2 05/12] replace split_value() with truncate_string() Roy Franz
2014-07-24  7:19   ` Jan Beulich
2014-08-06 22:37     ` Roy Franz
2014-08-07  6:24       ` Jan Beulich
2014-08-18 23:38         ` Roy Franz
2014-08-19 12:56           ` Jan Beulich
2014-07-22  0:43 ` [PATCH V2 06/12] add read_config_file() function for XEN EFI config file Roy Franz
2014-07-24  7:32   ` Jan Beulich
2014-08-06 22:42     ` Roy Franz
2014-07-22  0:43 ` [PATCH V2 07/12] create handle_cmdline() function Roy Franz
2014-07-24  7:36   ` Jan Beulich
2014-07-28 15:44     ` Ian Campbell
2014-07-28 15:57       ` Jan Beulich
2014-07-22  0:43 ` [PATCH V2 08/12] Refactor get_argv() for sharing Roy Franz
2014-07-24  7:38   ` Jan Beulich
2014-07-22  0:43 ` Roy Franz [this message]
2014-07-22  0:43 ` [PATCH V2 10/12] add arm64 cache flushing code from linux Roy Franz
2014-07-28 15:53   ` Ian Campbell
2014-07-28 16:24     ` Ian Campbell
2014-07-22  0:43 ` [PATCH V2 11/12] Add fdt_create_empty_tree() function Roy Franz
2014-07-22 16:36   ` [Linaro-uefi] " Julien Grall
2014-07-22 17:12     ` Roy Franz
2014-07-22 17:15       ` Julien Grall
2014-07-23  9:58         ` Ian Campbell
2014-07-23 16:15           ` Roy Franz
2014-07-22  0:43 ` [PATCH V2 12/12] Add EFI stub for arm64 Roy Franz
2014-07-29  9:46   ` Ian Campbell
2014-07-28 15:30 ` [PATCH V2 00/12] arm64 EFI stub Ian Campbell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1405989815-25236-10-git-send-email-roy.franz@linaro.org \
    --to=roy.franz@linaro.org \
    --cc=fu.wei@linaro.org \
    --cc=ian.campbell@citrix.com \
    --cc=jbeulich@suse.com \
    --cc=keir@xen.org \
    --cc=linaro-uefi@lists.linaro.org \
    --cc=stefano.stabellini@citrix.com \
    --cc=tim@xen.org \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.