@@ -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[];
@@ -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
@@ -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
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(-)