]> glassweightruler.freedombox.rocks Git - Ventoy.git/commitdiff
1. Optimization for WIMBOOT mode.
authorlongpanda <admin@ventoy.net>
Thu, 13 May 2021 15:05:42 +0000 (23:05 +0800)
committerlongpanda <admin@ventoy.net>
Thu, 13 May 2021 15:05:42 +0000 (23:05 +0800)
2. Add WIMBOOT for UEFI mode.

120 files changed:
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/efi.c
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c
GRUB2/MOD_SRC/grub-2.04/include/grub/efi/efi.h
INSTALL/grub/arm64-efi/moddep.lst
INSTALL/grub/grub.cfg
INSTALL/grub/i386-efi/moddep.lst
INSTALL/grub/i386-pc/moddep.lst
INSTALL/grub/mips64el-efi/moddep.lst
INSTALL/grub/x86_64-efi/moddep.lst
INSTALL/ventoy/vtoyjump32.exe
INSTALL/ventoy/vtoyjump64.exe
INSTALL/ventoy/wimboot [deleted file]
INSTALL/ventoy/wimboot.i386.efi.xz [new file with mode: 0644]
INSTALL/ventoy/wimboot.x86_64.xz [new file with mode: 0644]
INSTALL/ventoy/winpeshl.ini [deleted file]
vtoyjump/vtoyjump/vtoyjump.c
wimboot/build.sh [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/.gitignore [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/Makefile [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/assert.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/bootapp.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/byteswap.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/cmdline.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/cmdline.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/compiler.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/cookie.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/coverity-model.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/cpio.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/cpio.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/ctype.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/die.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Base.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Guid/FileInfo.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Guid/HiiFormMapMethodGuid.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Guid/PcAnsi.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Guid/WinCertificate.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Ia32/ProcessorBind.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/IndustryStandard/PeImage.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/ProcessorBind.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Protocol/BlockIo.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Protocol/DevicePath.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Protocol/GraphicsOutput.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Protocol/LoadedImage.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Protocol/SimpleFileSystem.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Protocol/SimpleTextIn.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Protocol/SimpleTextInEx.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Protocol/SimpleTextOut.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Uefi.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Uefi/UefiBaseType.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Uefi/UefiGpt.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Uefi/UefiInternalFormRepresentation.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Uefi/UefiMultiPhase.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Uefi/UefiPxe.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/Uefi/UefiSpec.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/X64/ProcessorBind.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efi/import.pl [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efiblock.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efiblock.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efiboot.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efiboot.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efifile.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efifile.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efiguid.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efimain.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efipath.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efipath.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/efireloc.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/errno.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/huffman.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/huffman.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/i386.i [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/int13.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/int13.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/ipxe/vsprintf.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/ipxe/vsprintf.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/lznt1.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/lznt1.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/lzx.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/lzx.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/main.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/memmap.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/memmap.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/paging.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/paging.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/pause.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/pause.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/peloader.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/peloader.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/rotate.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/script.lds [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/sha1.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/sha1.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/stdarg.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/stddef.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/stdint.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/stdio.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/stdio.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/stdlib.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/string.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/string.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/strings.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/vdisk.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/vdisk.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/vsprintf.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/wchar.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/wctype.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/wim.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/wim.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/wimboot.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/wimfile.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/wimfile.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/wimpatch.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/wimpatch.h [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/x86_64.i [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/xca.c [new file with mode: 0644]
wimboot/wimboot-2.7.3/src/xca.h [new file with mode: 0644]

index dc81157701dbe8d1b8e5c6ed6067f5bf4fffa3e3..a93da19962dbf25ba2746c57a43d57abea6542b4 100644 (file)
@@ -964,3 +964,20 @@ void * grub_efi_allocate_iso_buf(grub_uint64_t size)
     
     return (void *)(unsigned long)address;
 }
     
     return (void *)(unsigned long)address;
 }
+
+void * grub_efi_allocate_chain_buf(grub_uint64_t size)
+{
+    grub_efi_boot_services_t *b;
+    grub_efi_status_t status;
+    grub_efi_physical_address_t address = 0;
+    grub_efi_uintn_t pages = GRUB_EFI_BYTES_TO_PAGES(size);
+
+    b = grub_efi_system_table->boot_services;
+    status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES, GRUB_EFI_LOADER_DATA, pages, &address);
+    if (status != GRUB_EFI_SUCCESS)
+    {
+        return NULL;
+    }
+    
+    return (void *)(unsigned long)address;
+}
index 3a9b7718023c297ccb4b7d38793a513def1c396d..e4dce2198de4c260cf4c3af0dd05469377f36da0 100644 (file)
@@ -127,6 +127,8 @@ static grub_uint64_t g_enumerate_start_time_ms;
 static grub_uint64_t g_enumerate_finish_time_ms;
 static int g_vtoy_file_flt[VTOY_FILE_FLT_BUTT] = {0};
 
 static grub_uint64_t g_enumerate_finish_time_ms;
 static int g_vtoy_file_flt[VTOY_FILE_FLT_BUTT] = {0};
 
+static const char *g_vtoy_winpeshl_ini = "[LaunchApps]\r\nvtoyjump.exe";
+
 static const char *g_menu_class[] = 
 {
     "vtoyiso", "vtoywim", "vtoyefi", "vtoyimg", "vtoyvhd", "vtoyvtoy"
 static const char *g_menu_class[] = 
 {
     "vtoyiso", "vtoywim", "vtoyefi", "vtoyimg", "vtoyvhd", "vtoyvtoy"
@@ -1020,7 +1022,7 @@ static grub_err_t ventoy_cmd_concat_efi_iso(grub_extcmd_context_t ctxt, int argc
     data = (char *)grub_efi_allocate_iso_buf(totlen);
 #else
     data = (char *)grub_malloc(totlen);
     data = (char *)grub_efi_allocate_iso_buf(totlen);
 #else
     data = (char *)grub_malloc(totlen);
-#endif   
+#endif  
 
     ventoy_fill_os_param(file, (ventoy_os_param *)data);
 
 
     ventoy_fill_os_param(file, (ventoy_os_param *)data);
 
@@ -1048,36 +1050,52 @@ static grub_err_t ventoy_cmd_load_file_to_mem(grub_extcmd_context_t ctxt, int ar
     char value[32];
     char *buf = NULL;
     grub_file_t file;
     char value[32];
     char *buf = NULL;
     grub_file_t file;
+    enum grub_file_type type;
     
     (void)ctxt;
     (void)argc;
     (void)args;
 
     
     (void)ctxt;
     (void)argc;
     (void)args;
 
-    if (argc != 2)
+    if (argc != 3)
     {
         return rc;
     }
 
     {
         return rc;
     }
 
-    file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
+    if (grub_strcmp(args[0], "nodecompress") == 0)
+    {
+        type = VENTOY_FILE_TYPE;
+    }
+    else
+    {
+        type = GRUB_FILE_TYPE_LINUX_INITRD;
+    }
+
+    file = ventoy_grub_file_open(type, "%s", args[1]);
     if (file == NULL)
     {
     if (file == NULL)
     {
-        debug("failed to open file <%s>\n", args[0]);
+        debug("failed to open file <%s>\n", args[1]);
         return 1;
     }
 
 #ifdef GRUB_MACHINE_EFI
         return 1;
     }
 
 #ifdef GRUB_MACHINE_EFI
-    buf = (char *)grub_efi_allocate_iso_buf(file->size);
+    buf = (char *)grub_efi_allocate_chain_buf(file->size);
 #else
     buf = (char *)grub_malloc(file->size);
 #endif   
 
 #else
     buf = (char *)grub_malloc(file->size);
 #endif   
 
+    if (!buf)
+    {
+        grub_file_close(file);
+        return 1;
+    }
+
     grub_file_read(file, buf, file->size);
 
     grub_file_read(file, buf, file->size);
 
-    grub_snprintf(name, sizeof(name), "%s_addr", args[1]);
+    grub_snprintf(name, sizeof(name), "%s_addr", args[2]);
     grub_snprintf(value, sizeof(value), "0x%llx", (unsigned long long)(unsigned long)buf);
     grub_env_set(name, value);
     
     grub_snprintf(value, sizeof(value), "0x%llx", (unsigned long long)(unsigned long)buf);
     grub_env_set(name, value);
     
-    grub_snprintf(name, sizeof(name), "%s_size", args[1]);
+    grub_snprintf(name, sizeof(name), "%s_size", args[2]);
     grub_snprintf(value, sizeof(value), "%llu", (unsigned long long)file->size);
     grub_env_set(name, value);
 
     grub_snprintf(value, sizeof(value), "%llu", (unsigned long long)file->size);
     grub_env_set(name, value);
 
@@ -4349,6 +4367,23 @@ int ventoy_env_init(void)
         grub_env_export("ventoy_env_param");
     }
 
         grub_env_export("ventoy_env_param");
     }
 
+    grub_snprintf(buf, sizeof(buf), "0x%lx", (ulong)g_vtoy_winpeshl_ini);
+    grub_env_set("vtoy_winpeshl_ini_addr", buf);
+
+    grub_snprintf(buf, sizeof(buf), "%d", (int)grub_strlen(g_vtoy_winpeshl_ini));
+    grub_env_set("vtoy_winpeshl_ini_size", buf);
+
+    grub_env_export("vtoy_winpeshl_ini_addr");
+    grub_env_export("vtoy_winpeshl_ini_size");
+
+    grub_snprintf(buf, sizeof(buf), "0x%lx", (ulong)ventoy_chain_file_size);
+    grub_env_set("vtoy_chain_file_size", buf);
+    grub_env_export("vtoy_chain_file_size");
+
+    grub_snprintf(buf, sizeof(buf), "0x%lx", (ulong)ventoy_chain_file_read);
+    grub_env_set("vtoy_chain_file_read", buf);
+    grub_env_export("vtoy_chain_file_read");
+
     return 0;
 }
 
     return 0;
 }
 
@@ -4470,6 +4505,8 @@ static cmd_para ventoy_cmds[] =
     { "vt_check_secureboot_var", ventoy_cmd_check_secureboot_var, 0, NULL, "", "", NULL },
     { "vt_clear_key", ventoy_cmd_clear_key, 0, NULL, "", "", NULL },
     { "vt_img_check_range", ventoy_cmd_img_check_range, 0, NULL, "", "", NULL },
     { "vt_check_secureboot_var", ventoy_cmd_check_secureboot_var, 0, NULL, "", "", NULL },
     { "vt_clear_key", ventoy_cmd_clear_key, 0, NULL, "", "", NULL },
     { "vt_img_check_range", ventoy_cmd_img_check_range, 0, NULL, "", "", NULL },
+    { "vt_is_pe64", ventoy_cmd_is_pe64, 0, NULL, "", "", NULL },
+    { "vt_sel_wimboot", ventoy_cmd_sel_wimboot, 0, NULL, "", "", NULL },
 
 };
 
 
 };
 
@@ -4484,6 +4521,7 @@ int ventoy_register_all_cmd(void)
         cur->cmd = grub_register_extcmd(cur->name, cur->func, cur->flags, 
                                         cur->summary, cur->description, cur->parser);
     }
         cur->cmd = grub_register_extcmd(cur->name, cur->func, cur->flags, 
                                         cur->summary, cur->description, cur->parser);
     }
+
     return 0;
 }
 
     return 0;
 }
 
index 3aff72b2fbb9bc22584121fde2688a7f514896c1..f7b4f9deabdb3265ff78620a2c20766c3a675101 100644 (file)
@@ -554,11 +554,13 @@ int ventoy_is_dir_exist(const char *fmt, ...);
 int ventoy_fill_data(grub_uint32_t buflen, char *buffer);
 grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **args);
 grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char **args);
 int ventoy_fill_data(grub_uint32_t buflen, char *buffer);
 grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **args);
 grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char **args);
+grub_err_t ventoy_cmd_is_pe64(grub_extcmd_context_t ctxt, int argc, char **args);
 grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
 grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc, char **args);
 grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
 grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args);
 grub_err_t ventoy_cmd_dump_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args);
 grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
 grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc, char **args);
 grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
 grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args);
 grub_err_t ventoy_cmd_dump_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args);
+grub_err_t ventoy_cmd_sel_wimboot(grub_extcmd_context_t ctxt, int argc, char **args);
 
 VTOY_JSON *vtoy_json_find_item
 (
 
 VTOY_JSON *vtoy_json_find_item
 (
@@ -1011,6 +1013,8 @@ int ventoy_load_part_table(const char *diskname);
 int ventoy_env_init(void);
 int ventoy_register_all_cmd(void);
 int ventoy_unregister_all_cmd(void);
 int ventoy_env_init(void);
 int ventoy_register_all_cmd(void);
 int ventoy_unregister_all_cmd(void);
+int ventoy_chain_file_size(const char *path);
+int ventoy_chain_file_read(const char *path, int offset, int len, void *buf);
 
 #define VTOY_CMD_CHECK(a) if (33554432 != g_ventoy_disk_part_size[a]) ventoy_syscall0(exit)
 
 
 #define VTOY_CMD_CHECK(a) if (33554432 != g_ventoy_disk_part_size[a]) ventoy_syscall0(exit)
 
index d21533a55bb67bf6a51c33a280f1045d7fd955fa..ba738693926091fed0b9c7140f803a3cb1aadedd 100644 (file)
@@ -314,6 +314,90 @@ static int ventoy_is_pe64(grub_uint8_t *buffer)
     return 0;
 }
 
     return 0;
 }
 
+grub_err_t ventoy_cmd_is_pe64(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+    int ret = 1;
+    grub_file_t file;
+    grub_uint8_t buf[512];
+    
+    (void)ctxt;
+    (void)argc;
+
+    file = grub_file_open(args[0], VENTOY_FILE_TYPE);
+    if (!file)
+    {
+        return 1;
+    }
+
+    grub_memset(buf, 0, 512);
+    grub_file_read(file, buf, 512);
+    if (ventoy_is_pe64(buf))
+    {
+        debug("%s is PE64\n", args[0]);
+        ret = 0;
+    }
+    else
+    {
+        debug("%s is PE32\n", args[0]);
+    }
+    grub_file_close(file);
+
+    return ret;
+}
+
+grub_err_t ventoy_cmd_sel_wimboot(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+    int size;
+    char *buf = NULL;
+    char configfile[128];
+    
+    (void)ctxt;
+    (void)argc;
+    (void)args;
+
+    debug("select wimboot argc:%d\n", argc);
+
+    buf = (char *)grub_malloc(8192);
+    if (!buf)
+    {
+        return 0;
+    }
+
+    size = (int)grub_snprintf(buf, 8192, 
+        "menuentry \"Windows Setup (32-bit)\" {\n"
+        "    set vtoy_wimboot_sel=32\n"
+        "}\n"
+        "menuentry \"Windows Setup (64-bit)\" {\n"
+        "    set vtoy_wimboot_sel=64\n"
+        "}\n"
+        );
+    buf[size] = 0;
+
+    g_ventoy_menu_esc = 1;
+    g_ventoy_suppress_esc = 1;
+
+    grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, size);
+    grub_script_execute_sourcecode(configfile);
+    
+    g_ventoy_menu_esc = 0;
+    g_ventoy_suppress_esc = 0;
+
+    grub_free(buf);
+
+    if (g_ventoy_last_entry == 0)
+    {
+        debug("last entry=%d %s=32\n", g_ventoy_last_entry, args[0]);
+        grub_env_set(args[0], "32");
+    }
+    else
+    {
+        debug("last entry=%d %s=64\n", g_ventoy_last_entry, args[0]);
+        grub_env_set(args[0], "64");
+    }
+
+    VENTOY_CMD_RETURN(GRUB_ERR_NONE);
+}
+
 grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char **args)
 {
     wim_patch *next = NULL;
 grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char **args)
 {
     wim_patch *next = NULL;
@@ -1810,3 +1894,29 @@ grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char
     VENTOY_CMD_RETURN(GRUB_ERR_NONE);
 }
 
     VENTOY_CMD_RETURN(GRUB_ERR_NONE);
 }
 
+int ventoy_chain_file_size(const char *path)
+{
+    int size;
+    grub_file_t file;
+
+    file = grub_file_open(path, VENTOY_FILE_TYPE);
+    size = (int)(file->size);
+
+    grub_file_close(file);
+    
+    return size;
+}
+
+int ventoy_chain_file_read(const char *path, int offset, int len, void *buf)
+{
+    int size;
+    grub_file_t file;
+
+    file = grub_file_open(path, VENTOY_FILE_TYPE);
+    grub_file_seek(file, offset);
+    size = grub_file_read(file, buf, len);
+    grub_file_close(file);
+    
+    return size;
+}
+
index 263359db333b0f3b8ac35b266134d53607c805dd..4abd5db693843b87fe2b43850e6520c0869be9c1 100644 (file)
@@ -87,6 +87,7 @@ EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1,
                                             const grub_efi_device_path_t *dp2);
 
 void * EXPORT_FUNC (grub_efi_allocate_iso_buf) (grub_uint64_t size);
                                             const grub_efi_device_path_t *dp2);
 
 void * EXPORT_FUNC (grub_efi_allocate_iso_buf) (grub_uint64_t size);
+void * EXPORT_FUNC (grub_efi_allocate_chain_buf) (grub_uint64_t size);
 
 
 extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, 
 
 
 extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, 
index 3342bd68175825fab7c5011256c393182adc69a0..2c8eba2463903651be3c1e763e69017641e3953f 100644 (file)
@@ -23,7 +23,7 @@ sfs: fshelp
 reiserfs: fshelp
 part_sunpc:
 zstd:
 reiserfs: fshelp
 part_sunpc:
 zstd:
-gfxmenu: video_colors trig bitmap_scale gfxterm font normal bitmap video
+gfxmenu: trig video_colors bitmap_scale gfxterm font normal bitmap video
 jfs:
 help: extcmd normal
 configfile: normal
 jfs:
 help: extcmd normal
 configfile: normal
index f57a20c979ba779d85123697a5b0266a27f7bd86..d62b71df239da21fd320518bbd90fa9009243fbe 100644 (file)
@@ -535,6 +535,10 @@ function uefi_windows_menu_func {
     vt_windows_chain_data "${1}${chosen_path}"
     ventoy_debug_pause
     
     vt_windows_chain_data "${1}${chosen_path}"
     ventoy_debug_pause
     
+    if vt_check_mode 4; then
+        vtoy_windows_wimboot_func
+    fi
+    
     if [ -n "$vtoy_chain_mem_addr" ]; then
         ventoy_acpi_param ${vtoy_chain_mem_addr} 2048
         ventoy_cli_console
     if [ -n "$vtoy_chain_mem_addr" ]; then
         ventoy_acpi_param ${vtoy_chain_mem_addr} 2048
         ventoy_cli_console
@@ -805,23 +809,81 @@ function uefi_iso_memdisk {
 }
 
 
 }
 
 
-function legacy_windows_wimboot_func {
-    set wimbootfile=(loop)/sources/boot.wim
-    set wimbit=64
+function vtoy_windows_wimboot_func {
+    if [ -f (loop)/x86/sources/boot.wim -a -f (loop)/x64/sources/boot.wim ]; then
+        vt_sel_wimboot vtoy_wimboot_bit
+        if [ "$vtoy_wimboot_bit" = "32" ]; then
+            set vtoy_wimboot_prefix=(loop)/x86
+        else
+            set vtoy_wimboot_prefix=(loop)/x64
+        fi
+    else
+        set vtoy_wimboot_prefix=(loop)
+        if vt_is_pe64 $vtoy_wimboot_prefix/setup.exe; then
+            set vtoy_wimboot_bit=64
+        else
+            set vtoy_wimboot_bit=32
+        fi
+    fi
+
+    if [ -n "${vtdebug_flag}" ]; then
+        echo vtoy_wimboot_prefix=$vtoy_wimboot_prefix vtoy_wimboot_bit=$vtoy_wimboot_bit
+    fi
 
 
-    vt_windows_wimboot_data
+    for wmfile in sources/boot.wim boot/bcd boot/boot.sdi; do
+        if [ ! -f $vtoy_wimboot_prefix/$wmfile ]; then
+            return
+        fi
+    done
 
 
-    linux16  $vtoy_efi_part/ventoy/wimboot quiet
-    ventoy_debug_pause
+    if [ -f $vtoy_wimboot_prefix/sources/install.wim -o -f $vtoy_wimboot_prefix/sources/install.esd ]; then
+        vt_windows_wimboot_data
+    else
+        return
+    fi
     
     
-    echo Loading files...... (This may take a few minutes, please wait.)
-    initrd16 newc:vtoyjump.exe:$vtoy_efi_part/ventoy/vtoyjump${wimbit}.exe \
-         newc:wimboot.data:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size} \
-         newc:winpeshl.ini:$vtoy_efi_part/ventoy/winpeshl.ini \
-         newc:bcd:(loop)/boot/bcd \
-         newc:boot.sdi:(loop)/boot/boot.sdi \
-         newc:boot.wim:$wimbootfile
-    boot
+    if [ "$grub_platform" = "pc" ]; then
+        set vt_wimkernel=wimboot.x86_64.xz
+        
+        linux16  "$vtoy_path/$vt_wimkernel"  quiet
+        ventoy_debug_pause
+
+        echo Loading files...... (This may take a few minutes, please wait)
+        initrd16 newc:vtoyjump.exe:$vtoy_path/vtoyjump${vtoy_wimboot_bit}.exe \
+             newc:wimboot.data:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size} \
+             newc:winpeshl.ini:mem:${vtoy_winpeshl_ini_addr}:size:${vtoy_winpeshl_ini_size} \
+             newc:bcd:$vtoy_wimboot_prefix/boot/bcd \
+             newc:boot.sdi:$vtoy_wimboot_prefix/boot/boot.sdi \
+             newc:boot.wim:$vtoy_wimboot_prefix/sources/boot.wim
+        boot
+    else
+        if [ "$grub_cpu" = "i386" ]; then
+            set vt_wimkernel=wimboot.i386.efi.xz
+        else
+            set vt_wimkernel=wimboot.x86_64.xz
+        fi
+
+        echo Loading files...... (This may take a few minutes, please wait)
+        vt_load_file_to_mem "nodecompress" $vtoy_wimboot_prefix/sources/boot.wim vtoy_wimfile_mem
+        if [ $? -eq 0 ]; then
+            set vtoy_wimfile_path=mem:${vtoy_wimfile_mem_addr}:size:${vtoy_wimfile_mem_size}
+        else
+            set vtoy_wimfile_path=$vtoy_wimboot_prefix/sources/boot.wim
+        fi
+
+        ventoy_cli_console
+        chainloader "$vtoy_path/$vt_wimkernel" quiet \
+            "vf=wimboot.data:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size}" \
+            "vf=winpeshl.ini:mem:${vtoy_winpeshl_ini_addr}:size:${vtoy_winpeshl_ini_size}" \
+            "vf=vtoyjump.exe:$vtoy_path/vtoyjump${vtoy_wimboot_bit}.exe" \
+            "vf=bcd:$vtoy_wimboot_prefix/boot/bcd" \
+            "vf=boot.sdi:$vtoy_wimboot_prefix/boot/boot.sdi" \
+            "vf=boot.wim:$vtoy_wimfile_path" \
+            pfsize=$vtoy_chain_file_size  \
+            pfread=$vtoy_chain_file_read
+        boot
+        ventoy_gui_console
+    fi
 }
 
 function legacy_windows_menu_func {
 }
 
 function legacy_windows_menu_func {
@@ -854,7 +916,7 @@ function legacy_windows_menu_func {
     ventoy_debug_pause    
 
     if vt_check_mode 4; then
     ventoy_debug_pause    
 
     if vt_check_mode 4; then
-        legacy_windows_wimboot_func
+        vtoy_windows_wimboot_func
     fi
 
     if [ -n "$vtoy_chain_mem_addr" ]; then
     fi
 
     if [ -n "$vtoy_chain_mem_addr" ]; then
index 3ab0a92b40e233d6b75c4a905d2c18c014da75ae..f101a8fef7122141de677bff66f1cadf9a724c45 100644 (file)
@@ -26,7 +26,7 @@ sfs: fshelp
 reiserfs: fshelp
 part_sunpc:
 zstd:
 reiserfs: fshelp
 part_sunpc:
 zstd:
-gfxmenu: video_colors trig bitmap_scale gfxterm font normal bitmap video
+gfxmenu: trig video_colors bitmap_scale gfxterm font normal bitmap video
 backtrace:
 jfs:
 help: extcmd normal
 backtrace:
 jfs:
 help: extcmd normal
index 4f8b330d719d8aa3327064e003578d27577f162b..08cc536ac514720a110448240e0509a5c9fbce08 100644 (file)
@@ -26,7 +26,7 @@ sfs: fshelp
 reiserfs: fshelp
 part_sunpc:
 zstd:
 reiserfs: fshelp
 part_sunpc:
 zstd:
-gfxmenu: video_colors trig bitmap_scale gfxterm font normal bitmap video
+gfxmenu: trig video_colors bitmap_scale gfxterm font normal bitmap video
 backtrace:
 jfs:
 help: extcmd normal
 backtrace:
 jfs:
 help: extcmd normal
index 5b71692e46bc525ff41a687e6f18454bd1a96b10..3164b81bdde85057f809838b048465bfee360238 100644 (file)
Binary files a/INSTALL/grub/mips64el-efi/moddep.lst and b/INSTALL/grub/mips64el-efi/moddep.lst differ
index f706b8282af88aaaab3d071f949b4cbfe952204b..602117232f40b8aebbb224be20ccd257c06c0dfc 100644 (file)
@@ -26,7 +26,7 @@ sfs: fshelp
 reiserfs: fshelp
 part_sunpc:
 zstd:
 reiserfs: fshelp
 part_sunpc:
 zstd:
-gfxmenu: video_colors trig bitmap_scale gfxterm font normal bitmap video
+gfxmenu: trig video_colors bitmap_scale gfxterm font normal bitmap video
 backtrace:
 jfs:
 help: extcmd normal
 backtrace:
 jfs:
 help: extcmd normal
index 6019aa44a256dcf5632f54001997dad3f7fe9242..1c7bea1f15a5527639bee37e42c16c3348bdd62f 100644 (file)
Binary files a/INSTALL/ventoy/vtoyjump32.exe and b/INSTALL/ventoy/vtoyjump32.exe differ
index c2e80a77a1b99578449749c2dbf972a2ef9e9f2c..a0d605629b30d3b2b6524fe45f4b54f12ac2af8e 100644 (file)
Binary files a/INSTALL/ventoy/vtoyjump64.exe and b/INSTALL/ventoy/vtoyjump64.exe differ
diff --git a/INSTALL/ventoy/wimboot b/INSTALL/ventoy/wimboot
deleted file mode 100644 (file)
index e02ed65..0000000
Binary files a/INSTALL/ventoy/wimboot and /dev/null differ
diff --git a/INSTALL/ventoy/wimboot.i386.efi.xz b/INSTALL/ventoy/wimboot.i386.efi.xz
new file mode 100644 (file)
index 0000000..42abe44
Binary files /dev/null and b/INSTALL/ventoy/wimboot.i386.efi.xz differ
diff --git a/INSTALL/ventoy/wimboot.x86_64.xz b/INSTALL/ventoy/wimboot.x86_64.xz
new file mode 100644 (file)
index 0000000..3f62867
Binary files /dev/null and b/INSTALL/ventoy/wimboot.x86_64.xz differ
diff --git a/INSTALL/ventoy/winpeshl.ini b/INSTALL/ventoy/winpeshl.ini
deleted file mode 100644 (file)
index 2302fea..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[LaunchApps]\r
-vtoyjump.exe
\ No newline at end of file
index e8f9f5a89aa9cdab9f7a602b35cd7253135684e1..9b10d1af5d55f7e036a4272d75fcccd7896f6576 100644 (file)
@@ -1118,7 +1118,7 @@ int VentoyJumpWimboot(INT argc, CHAR **argv, CHAR *LunchFile)
     g_64bit_system = TRUE;\r
 #endif\r
     \r
     g_64bit_system = TRUE;\r
 #endif\r
     \r
-    Log("VentoyJumpWimboot 64bit:%u", g_64bit_system);\r
+    Log("VentoyJumpWimboot %dbit", g_64bit_system ? 64 : 32);\r
 \r
     sprintf_s(LunchFile, MAX_PATH, "X:\\setup.exe");\r
 \r
 \r
     sprintf_s(LunchFile, MAX_PATH, "X:\\setup.exe");\r
 \r
@@ -1187,6 +1187,7 @@ int VentoyJump(INT argc, CHAR **argv, CHAR *LunchFile)
        }\r
        \r
        g_64bit_system = IsPe64(Buffer);\r
        }\r
        \r
        g_64bit_system = IsPe64(Buffer);\r
+    Log("VentoyJump %dbit", g_64bit_system ? 64 : 32);\r
 \r
        if (!IsPathExist(TRUE, "ventoy"))\r
        {\r
 \r
        if (!IsPathExist(TRUE, "ventoy"))\r
        {\r
diff --git a/wimboot/build.sh b/wimboot/build.sh
new file mode 100644 (file)
index 0000000..7253600
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+VTOY_PATH=$PWD/../
+
+cd wimboot-2.7.3/src
+
+make clean
+make -j 16
+
+rm -f *.xz
+xz wimboot.x86_64
+xz wimboot.i386.efi
+
+rm -f $VTOY_PATH/INSTALL/ventoy/wimboot.x86_64.xz
+rm -f $VTOY_PATH/INSTALL/ventoy/wimboot.i386.efi.xz
+cp -a wimboot.x86_64.xz $VTOY_PATH/INSTALL/ventoy/
+cp -a wimboot.i386.efi.xz $VTOY_PATH/INSTALL/ventoy/
+
+make clean
+cd ../../
diff --git a/wimboot/wimboot-2.7.3/src/.gitignore b/wimboot/wimboot-2.7.3/src/.gitignore
new file mode 100644 (file)
index 0000000..80c3366
--- /dev/null
@@ -0,0 +1,10 @@
+wimboot
+*.s
+*.o
+*.a
+*.elf
+*.map
+*.unsigned
+*.efi
+*.cab
+efireloc
diff --git a/wimboot/wimboot-2.7.3/src/Makefile b/wimboot/wimboot-2.7.3/src/Makefile
new file mode 100644 (file)
index 0000000..bb4716b
--- /dev/null
@@ -0,0 +1,187 @@
+VERSION := v2.7.3
+
+OBJECTS := prefix.o startup.o callback.o main.o vsprintf.o string.o peloader.o
+OBJECTS += int13.o vdisk.o cpio.o stdio.o lznt1.o xca.o die.o efi.o efimain.o
+OBJECTS += efiguid.o efifile.o efipath.o efiboot.o efiblock.o cmdline.o
+OBJECTS += wimpatch.o huffman.o lzx.o wim.o wimfile.o pause.o sha1.o cookie.o
+OBJECTS += paging.o memmap.o
+
+OBJECTS_i386 := $(patsubst %.o,%.i386.o,$(OBJECTS))
+OBJECTS_x86_64 := $(patsubst %.o,%.x86_64.o,$(OBJECTS))
+OBJECTS_i386_x86_64 := $(patsubst %.o,%.i386.x86_64.o,$(OBJECTS))
+
+HEADERS := $(wildcard *.h)
+
+HOST_CC                := $(CC)
+AS             := $(AS)
+ECHO           := echo
+OBJCOPY        := objcopy
+AR             := ar
+RANLIB         := ranlib
+CP             := cp
+RM             := rm
+GCAB           := gcab
+PESIGN         := pesign
+DIFF           := diff
+CUT            := cut
+BINUTILS_DIR   := /usr
+BFD_DIR                := $(BINUTILS_DIR)
+ZLIB_DIR       := /usr
+
+HOST_CFLAGS += -Wall -W -Werror
+
+CFLAGS += -Os -ffreestanding -Wall -W -Werror -nostdinc -I. -fshort-wchar
+CFLAGS += -DVERSION="\"$(VERSION)\""
+
+CFLAGS_i386 += -m32 -march=i386 -malign-double -fno-pic
+CFLAGS_x86_64 += -m64 -mno-red-zone -fpie
+
+# Enable stack protection if available
+#
+SPG_TEST = $(CC) -fstack-protector-strong -mstack-protector-guard=global \
+                -x c -c /dev/null -o /dev/null >/dev/null 2>&1
+SPG_FLAGS := $(shell $(SPG_TEST) && $(ECHO) '-fstack-protector-strong ' \
+                                           '-mstack-protector-guard=global')
+CFLAGS += $(SPG_FLAGS)
+
+# Inhibit unwanted debugging information
+CFI_TEST = $(CC) -fno-dwarf2-cfi-asm -fno-exceptions -fno-unwind-tables \
+                -fno-asynchronous-unwind-tables -x c -c /dev/null \
+                -o /dev/null >/dev/null 2>&1
+CFI_FLAGS := $(shell $(CFI_TEST) && \
+              $(ECHO) '-fno-dwarf2-cfi-asm -fno-exceptions ' \
+                   '-fno-unwind-tables -fno-asynchronous-unwind-tables')
+WORKAROUND_CFLAGS += $(CFI_FLAGS)
+
+# Add -maccumulate-outgoing-args if required by this version of gcc
+MS_ABI_TEST_CODE := extern void __attribute__ (( ms_abi )) ms_abi(); \
+                   void sysv_abi ( void ) { ms_abi(); }
+MS_ABI_TEST = $(ECHO) '$(MS_ABI_TEST_CODE)' | \
+             $(CC) -m64 -mno-accumulate-outgoing-args -x c -c - -o /dev/null \
+                   >/dev/null 2>&1
+MS_ABI_FLAGS := $(shell $(MS_ABI_TEST) || $(ECHO) '-maccumulate-outgoing-args')
+WORKAROUND_CFLAGS += $(MS_ABI_FLAGS)
+
+# Inhibit warnings from taking address of packed struct members
+WNAPM_TEST = $(CC) -Wno-address-of-packed-member -x c -c /dev/null \
+                  -o /dev/null >/dev/null 2>&1
+WNAPM_FLAGS := $(shell $(WNAPM_TEST) && \
+                $(ECHO) '-Wno-address-of-packed-member')
+WORKAROUND_CFLAGS += $(WNAPM_FLAGS)
+
+# Inhibit LTO
+LTO_TEST = $(CC) -fno-lto -x c -c /dev/null -o /dev/null >/dev/null 2>&1
+LTO_FLAGS := $(shell $(LTO_TEST) && $(ECHO) '-fno-lto')
+WORKAROUND_CFLAGS += $(LTO_FLAGS)
+
+CFLAGS += $(WORKAROUND_CFLAGS)
+CFLAGS += $(EXTRA_CFLAGS)
+
+ifneq ($(DEBUG),)
+CFLAGS += -DDEBUG=$(DEBUG)
+endif
+
+CFLAGS += -include compiler.h
+
+###############################################################################
+#
+# Final targets
+
+all : wimboot wimboot.i386 wimboot.x86_64 wimboot.cab
+
+wimboot : wimboot.x86_64 Makefile
+       $(CP) $< $@
+       $(CP) $@ ../$@
+
+wimboot.%.elf : prefix.%.o lib.%.a script.lds Makefile
+       $(LD) -m elf_$* -T script.lds -o $@ -q -Map wimboot.$*.map \
+               prefix.$*.o lib.$*.a
+
+wimboot.%.unsigned : wimboot.%.elf efireloc Makefile
+       $(OBJCOPY) -Obinary $< $@
+       ./efireloc $< $@
+
+wimboot.%.unsigned.hash : wimboot.%.unsigned Makefile
+       $(PESIGN) -h -i $< | $(CUT) -d" " -f2- > $@
+
+wimboot.%.efi : wimboot.%.unsigned Makefile
+       $(CP) $< $@
+
+wimboot.%.efi.hash : wimboot.%.efi Makefile
+       $(PESIGN) -h -i $< | $(CUT) -d" " -f2- > $@
+
+wimboot.% : wimboot.%.efi wimboot.%.efi.hash wimboot.%.unsigned.hash Makefile
+       $(DIFF) wimboot.$*.efi.hash wimboot.$*.unsigned.hash
+       $(CP) $< $@
+
+wimboot.cab : wimboot.i386.efi wimboot.x86_64.efi Makefile
+       $(GCAB) -n -c $@ wimboot.i386.efi wimboot.x86_64.efi
+
+###############################################################################
+#
+# i386 objects
+
+%.i386.s : %.S $(HEADERS) Makefile
+       $(CC) $(CFLAGS) $(CFLAGS_i386) -DASSEMBLY -Ui386 -E $< -o $@
+
+%.i386.s : %.c $(HEADERS) Makefile
+       $(CC) $(CFLAGS) $(CFLAGS_i386) -S $< -o $@
+
+%.i386.o : %.i386.s i386.i Makefile
+       $(AS) --32 i386.i $< -o $@
+
+lib.i386.a : $(OBJECTS_i386) Makefile
+       $(RM) -f $@
+       $(AR) r $@ $(OBJECTS_i386)
+       $(RANLIB) $@
+
+###############################################################################
+#
+# i386 objects to be linked into an x86_64 binary
+
+%.i386.x86_64.raw.o : %.i386.s i386.i Makefile
+       $(AS) --64 i386.i $< -o $@
+
+%.i386.x86_64.o : %.i386.x86_64.raw.o Makefile
+       $(OBJCOPY) --prefix-symbols=__i386_ $< $@
+
+###############################################################################
+#
+# x86_64 objects
+
+%.x86_64.s : %.S $(HEADERS) Makefile
+       $(CC) $(CFLAGS) $(CFLAGS_x86_64) -DASSEMBLY -Ui386 -E $< -o $@
+
+%.x86_64.s : %.c $(HEADERS) Makefile
+       $(CC) $(CFLAGS) $(CFLAGS_x86_64) -S $< -o $@
+
+%.x86_64.o : %.x86_64.s x86_64.i Makefile
+       $(AS) --64 x86_64.i $< -o $@
+
+lib.x86_64.a : $(OBJECTS_x86_64) $(OBJECTS_i386_x86_64) Makefile
+       $(RM) -f $@
+       $(AR) r $@ $(OBJECTS_x86_64) $(OBJECTS_i386_x86_64)
+       $(RANLIB) $@
+
+###############################################################################
+#
+# EFI relocator
+
+EFIRELOC_CFLAGS := -I$(BINUTILS_DIR)/include -I$(BFD_DIR)/include \
+                  -I$(ZLIB_DIR)/include -idirafter .
+EFIRELOC_LDFLAGS := -L$(BINUTILS_DIR)/lib -L$(BFD_DIR)/lib -L$(ZLIB_DIR)/lib \
+                   -lbfd -ldl -liberty -lz -Wl,--no-warn-search-mismatch
+
+efireloc : efireloc.c Makefile
+       $(CC) $(HOST_CFLAGS) $(EFIRELOC_CFLAGS) $< $(EFIRELOC_LDFLAGS) -o $@
+
+###############################################################################
+#
+# Cleanup
+
+clean :
+       $(RM) -f *.s *.o *.a *.elf *.map
+       $(RM) -f efireloc
+       $(RM) -f wimboot wimboot.i386 wimboot.x86_64 ../wimboot
+       $(RM) -f wimboot.i386.unsigned wimboot.x86_64.unsigned
+       $(RM) -f wimboot.i386.efi wimboot.x86_64.efi wimboot.cab
diff --git a/wimboot/wimboot-2.7.3/src/assert.h b/wimboot/wimboot-2.7.3/src/assert.h
new file mode 100644 (file)
index 0000000..bbfcde9
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _ASSERT_H
+#define _ASSERT_H
+
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Assertions
+ *
+ */
+
+#include "wimboot.h"
+
+#define assert(x) do {                                         \
+       if ( DEBUG && ! (x) ) {                                 \
+               die ( "Assertion failed at %s line %d: %s\n",   \
+                     __FILE__, __LINE__, #x );                 \
+       }                                                       \
+       } while ( 0 )
+
+#endif /* _ASSERT_H */
diff --git a/wimboot/wimboot-2.7.3/src/bootapp.h b/wimboot/wimboot-2.7.3/src/bootapp.h
new file mode 100644 (file)
index 0000000..16b3c1f
--- /dev/null
@@ -0,0 +1,318 @@
+#ifndef _BOOTAPP_H
+#define _BOOTAPP_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Boot application data structures
+ *
+ */
+
+#include <stdint.h>
+
+/** A segment:offset address */
+struct segoff {
+       /** Offset */
+       uint16_t offset;
+       /** Segment */
+       uint16_t segment;
+} __attribute__ (( packed ));
+
+/** A GUID */
+struct guid {
+       /** 8 hex digits, big-endian */
+       uint32_t a;
+       /** 2 hex digits, big-endian */
+       uint16_t b;
+       /** 2 hex digits, big-endian */
+       uint16_t c;
+       /** 2 hex digits, big-endian */
+       uint16_t d;
+       /** 12 hex digits, big-endian */
+       uint8_t e[6];
+} __attribute__ (( packed ));
+
+/** Real-mode callback parameters */
+struct bootapp_callback_params {
+       /** Vector */
+       union {
+               /** Interrupt number */
+               uint32_t interrupt;
+               /** Segment:offset address of real-mode function */
+               struct segoff function;
+       } vector;
+       /** %eax value */
+       union {
+               struct {
+                       uint8_t al;
+                       uint8_t ah;
+               } __attribute__ (( packed ));
+               uint16_t ax;
+               uint32_t eax;
+       };
+       /** %ebx value */
+       union {
+               struct {
+                       uint8_t bl;
+                       uint8_t bh;
+               } __attribute__ (( packed ));
+               uint16_t bx;
+               uint32_t ebx;
+       };
+       /** %ecx value */
+       union {
+               struct {
+                       uint8_t cl;
+                       uint8_t ch;
+               } __attribute__ (( packed ));
+               uint16_t cx;
+               uint32_t ecx;
+       };
+       /** %edx value */
+       union {
+               struct {
+                       uint8_t dl;
+                       uint8_t dh;
+               } __attribute__ (( packed ));
+               uint16_t dx;
+               uint32_t edx;
+       };
+       /** Placeholder (for %esp?) */
+       uint32_t unused_esp;
+       /** Placeholder (for %ebp?) */
+       uint32_t unused_ebp;
+       /** %esi value */
+       union {
+               uint16_t si;
+               uint32_t esi;
+       };
+       /** %edi value */
+       union {
+               uint16_t di;
+               uint32_t edi;
+       };
+       /** Placeholder (for %cs?) */
+       uint32_t unused_cs;
+       /** %ds value */
+       uint32_t ds;
+       /** Placeholder (for %ss?) */
+       uint32_t unused_ss;
+       /** %es value */
+       uint32_t es;
+       /** %fs value */
+       uint32_t fs;
+       /** %gs value */
+       uint32_t gs;
+       /** eflags value */
+       uint32_t eflags;
+} __attribute__ (( packed ));
+
+/** eflags bits */
+enum eflags {
+       CF = ( 1 << 0 ),
+       PF = ( 1 << 2 ),
+       AF = ( 1 << 4 ),
+       ZF = ( 1 << 6 ),
+       SF = ( 1 << 7 ),
+       OF = ( 1 << 11 ),
+};
+
+/** Real-mode callback function table */
+struct bootapp_callback_functions {
+       /**
+        * Call an arbitrary real-mode interrupt
+        *
+        * @v params            Parameters
+        */
+       void ( * call_interrupt ) ( struct bootapp_callback_params *params );
+       /**
+        * Call an arbitrary real-mode function
+        *
+        * @v params            Parameters
+        */
+       void ( * call_real ) ( struct bootapp_callback_params *params );
+} __attribute__ (( packed ));
+
+/** Real-mode callbacks */
+struct bootapp_callback {
+       /** Real-mode callback function table */
+       struct bootapp_callback_functions *fns;
+       /** Drive number for INT13 calls */
+       uint32_t drive;
+} __attribute__ (( packed ));
+
+/** Boot application descriptor */
+struct bootapp_descriptor {
+       /** Signature */
+       char signature[8];
+       /** Version */
+       uint32_t version;
+       /** Total length */
+       uint32_t len;
+       /** COFF machine type */
+       uint32_t arch;
+       /** Reserved */
+       uint32_t reserved_0x14;
+       /** Loaded PE image base address */
+       void *pe_base;
+       /** Reserved */
+       uint32_t reserved_0x1c;
+       /** Length of loaded PE image */
+       uint32_t pe_len;
+       /** Offset to memory descriptor */
+       uint32_t memory;
+       /** Offset to boot application entry descriptor */
+       uint32_t entry;
+       /** Offset to ??? */
+       uint32_t xxx;
+       /** Offset to callback descriptor */
+       uint32_t callback;
+       /** Offset to pointless descriptor */
+       uint32_t pointless;
+       /** Reserved */
+       uint32_t reserved_0x38;
+} __attribute__ (( packed ));
+
+/** "BOOT APP" magic signature */
+#define BOOTAPP_SIGNATURE "BOOT APP"
+
+/** Boot application descriptor version */
+#define BOOTAPP_VERSION 2
+
+/** i386 architecture */
+#define BOOTAPP_ARCH_I386 0x014c
+
+/** Memory region descriptor */
+struct bootapp_memory_region {
+       /** Reserved (for struct list_head?) */
+       uint8_t reserved[8];
+       /** Start page address */
+       uint64_t start_page;
+       /** Reserved */
+       uint8_t reserved_0x10[8];
+       /** Number of pages */
+       uint64_t num_pages;
+       /** Reserved */
+       uint8_t reserved_0x20[4];
+       /** Flags */
+       uint32_t flags;
+} __attribute__ (( packed ));
+
+/** Memory descriptor */
+struct bootapp_memory_descriptor {
+       /** Version */
+       uint32_t version;
+       /** Length of descriptor (excluding region descriptors) */
+       uint32_t len;
+       /** Number of regions */
+       uint32_t num_regions;
+       /** Length of each region descriptor */
+       uint32_t region_len;
+       /** Length of reserved area at start of each region descriptor */
+       uint32_t reserved_len;
+} __attribute__ (( packed ));
+
+/** Boot application memory descriptor version */
+#define BOOTAPP_MEMORY_VERSION 1
+
+/** Boot application entry descriptor */
+struct bootapp_entry_descriptor {
+       /** Signature */
+       char signature[8];
+       /** Flags */
+       uint32_t flags;
+       /** GUID */
+       struct guid guid;
+       /** Reserved */
+       uint8_t reserved[16];
+} __attribute__ (( packed ));
+
+/** ??? */
+struct bootapp_entry_wtf1_descriptor {
+       /** Flags */
+       uint32_t flags;
+       /** Length of descriptor */
+       uint32_t len;
+       /** Total length of following descriptors within BTAPENT */
+       uint32_t extra_len;
+       /** Reserved */
+       uint8_t reserved[12];
+} __attribute__ (( packed ));
+
+/** ??? */
+struct bootapp_entry_wtf2_descriptor {
+       /** GUID */
+       struct guid guid;
+} __attribute__ (( packed ));
+
+/** ??? */
+struct bootapp_entry_wtf3_descriptor {
+       /** Flags */
+       uint32_t flags;
+       /** Reserved */
+       uint32_t reserved_0x04;
+       /** Length of descriptor */
+       uint32_t len;
+       /** Reserved */
+       uint32_t reserved_0x0c;
+       /** Boot partition offset (in bytes) */
+       uint32_t boot_partition_offset;
+       /** Reserved */
+       uint8_t reserved_0x14[16];
+       /** MBR signature present? */
+       uint32_t xxx;
+       /** MBR signature */
+       uint32_t mbr_signature;
+       /** Reserved */
+       uint8_t reserved_0x2c[26];
+} __attribute__ (( packed ));
+
+/** "BTAPENT" magic signature */
+#define BOOTAPP_ENTRY_SIGNATURE "BTAPENT\0"
+
+/** Boot application entry flags
+ *
+ * pxeboot, etftboot, and fatboot all use a value of 0x21; I have no
+ * idea what it means.
+ */
+#define BOOTAPP_ENTRY_FLAGS 0x21
+
+/** Boot application callback descriptor */
+struct bootapp_callback_descriptor {
+       /** Real-mode callbacks */
+       struct bootapp_callback *callback;
+       /** Reserved */
+       uint32_t reserved;
+} __attribute__ (( packed ));
+
+/** Boot application pointless descriptor */
+struct bootapp_pointless_descriptor {
+       /** Version */
+       uint32_t version;
+       /** Reserved */
+       uint8_t reserved[24];
+} __attribute__ (( packed ));
+
+/** Boot application pointless descriptor version */
+#define BOOTAPP_POINTLESS_VERSION 1
+
+#endif /* _BOOTAPP_H */
diff --git a/wimboot/wimboot-2.7.3/src/byteswap.h b/wimboot/wimboot-2.7.3/src/byteswap.h
new file mode 100644 (file)
index 0000000..34a6066
--- /dev/null
@@ -0,0 +1,183 @@
+#ifndef _BITS_BYTESWAP_H
+#define _BITS_BYTESWAP_H
+
+/** @file
+ *
+ * Byte-order swapping functions
+ *
+ */
+
+#include <stdint.h>
+
+static inline __attribute__ (( always_inline, const )) uint16_t
+__bswap_variable_16 ( uint16_t x ) {
+       __asm__ ( "xchgb %b0,%h0" : "=Q" ( x ) : "0" ( x ) );
+       return x;
+}
+
+static inline __attribute__ (( always_inline )) void
+__bswap_16s ( uint16_t *x ) {
+       __asm__ ( "rorw $8, %0" : "+m" ( *x ) );
+}
+
+static inline __attribute__ (( always_inline, const )) uint32_t
+__bswap_variable_32 ( uint32_t x ) {
+       __asm__ ( "bswapl %k0" : "=r" ( x ) : "0" ( x ) );
+       return x;
+}
+
+static inline __attribute__ (( always_inline )) void
+__bswap_32s ( uint32_t *x ) {
+       __asm__ ( "bswapl %k0" : "=r" ( *x ) : "0" ( *x ) );
+}
+
+#ifdef __x86_64__
+
+static inline __attribute__ (( always_inline, const )) uint64_t
+__bswap_variable_64 ( uint64_t x ) {
+       __asm__ ( "bswapq %q0" : "=r" ( x ) : "0" ( x ) );
+       return x;
+}
+
+#else /* __x86_64__ */
+
+static inline __attribute__ (( always_inline, const )) uint64_t
+__bswap_variable_64 ( uint64_t x ) {
+       uint32_t in_high = ( x >> 32 );
+       uint32_t in_low = ( x & 0xffffffffUL );
+       uint32_t out_high;
+       uint32_t out_low;
+
+       __asm__ ( "bswapl %0\n\t"
+                 "bswapl %1\n\t"
+                 "xchgl %0,%1\n\t"
+                 : "=r" ( out_high ), "=r" ( out_low )
+                 : "0" ( in_high ), "1" ( in_low ) );
+
+       return ( ( ( ( uint64_t ) out_high ) << 32 ) |
+                ( ( uint64_t ) out_low ) );
+}
+
+#endif /* __x86_64__ */
+
+static inline __attribute__ (( always_inline )) void
+__bswap_64s ( uint64_t *x ) {
+       *x = __bswap_variable_64 ( *x );
+}
+
+/**
+ * Byte-swap a 16-bit constant
+ *
+ * @v value            Constant value
+ * @ret swapped                Byte-swapped value
+ */
+#define __bswap_constant_16( value )                                   \
+       ( ( ( (value) & 0x00ff ) << 8 ) |                               \
+         ( ( (value) & 0xff00 ) >> 8 ) )
+
+/**
+ * Byte-swap a 32-bit constant
+ *
+ * @v value            Constant value
+ * @ret swapped                Byte-swapped value
+ */
+#define __bswap_constant_32( value ) \
+       ( ( ( (value) & 0x000000ffUL ) << 24 ) |                        \
+         ( ( (value) & 0x0000ff00UL ) <<  8 ) |                        \
+         ( ( (value) & 0x00ff0000UL ) >>  8 ) |                        \
+         ( ( (value) & 0xff000000UL ) >> 24 ) )
+
+/**
+ * Byte-swap a 64-bit constant
+ *
+ * @v value            Constant value
+ * @ret swapped                Byte-swapped value
+ */
+#define __bswap_constant_64( value )                                   \
+       ( ( ( (value) & 0x00000000000000ffULL ) << 56 ) |               \
+         ( ( (value) & 0x000000000000ff00ULL ) << 40 ) |               \
+         ( ( (value) & 0x0000000000ff0000ULL ) << 24 ) |               \
+         ( ( (value) & 0x00000000ff000000ULL ) <<  8 ) |               \
+         ( ( (value) & 0x000000ff00000000ULL ) >>  8 ) |               \
+         ( ( (value) & 0x0000ff0000000000ULL ) >> 24 ) |               \
+         ( ( (value) & 0x00ff000000000000ULL ) >> 40 ) |               \
+         ( ( (value) & 0xff00000000000000ULL ) >> 56 ) )
+
+/**
+ * Byte-swap a 16-bit value
+ *
+ * @v value            Value
+ * @ret swapped                Byte-swapped value
+ */
+#define __bswap_16( value )                                            \
+       ( __builtin_constant_p (value) ?                                \
+         ( ( uint16_t ) __bswap_constant_16 ( ( uint16_t ) (value) ) ) \
+         : __bswap_variable_16 (value) )
+#define bswap_16( value ) __bswap_16 (value)
+
+/**
+ * Byte-swap a 32-bit value
+ *
+ * @v value            Value
+ * @ret swapped                Byte-swapped value
+ */
+#define __bswap_32( value )                                            \
+       ( __builtin_constant_p (value) ?                                \
+         ( ( uint32_t ) __bswap_constant_32 ( ( uint32_t ) (value) ) ) \
+         : __bswap_variable_32 (value) )
+#define bswap_32( value ) __bswap_32 (value)
+
+/**
+ * Byte-swap a 64-bit value
+ *
+ * @v value            Value
+ * @ret swapped                Byte-swapped value
+ */
+#define __bswap_64( value )                                            \
+       ( __builtin_constant_p (value) ?                                \
+         ( ( uint64_t ) __bswap_constant_64 ( ( uint64_t ) (value) ) ) \
+          : __bswap_variable_64 (value) )
+#define bswap_64( value ) __bswap_64 (value)
+
+#define __cpu_to_leNN( bits, value ) (value)
+#define __cpu_to_beNN( bits, value ) __bswap_ ## bits (value)
+#define __leNN_to_cpu( bits, value ) (value)
+#define __beNN_to_cpu( bits, value ) __bswap_ ## bits (value)
+#define __cpu_to_leNNs( bits, ptr ) do { } while ( 0 )
+#define __cpu_to_beNNs( bits, ptr ) __bswap_ ## bits ## s (ptr)
+#define __leNN_to_cpus( bits, ptr ) do { } while ( 0 )
+#define __beNN_to_cpus( bits, ptr ) __bswap_ ## bits ## s (ptr)
+
+#define cpu_to_le16( value ) __cpu_to_leNN ( 16, value )
+#define cpu_to_le32( value ) __cpu_to_leNN ( 32, value )
+#define cpu_to_le64( value ) __cpu_to_leNN ( 64, value )
+#define cpu_to_be16( value ) __cpu_to_beNN ( 16, value )
+#define cpu_to_be32( value ) __cpu_to_beNN ( 32, value )
+#define cpu_to_be64( value ) __cpu_to_beNN ( 64, value )
+#define le16_to_cpu( value ) __leNN_to_cpu ( 16, value )
+#define le32_to_cpu( value ) __leNN_to_cpu ( 32, value )
+#define le64_to_cpu( value ) __leNN_to_cpu ( 64, value )
+#define be16_to_cpu( value ) __beNN_to_cpu ( 16, value )
+#define be32_to_cpu( value ) __beNN_to_cpu ( 32, value )
+#define be64_to_cpu( value ) __beNN_to_cpu ( 64, value )
+#define cpu_to_le16s( ptr ) __cpu_to_leNNs ( 16, ptr )
+#define cpu_to_le32s( ptr ) __cpu_to_leNNs ( 32, ptr )
+#define cpu_to_le64s( ptr ) __cpu_to_leNNs ( 64, ptr )
+#define cpu_to_be16s( ptr ) __cpu_to_beNNs ( 16, ptr )
+#define cpu_to_be32s( ptr ) __cpu_to_beNNs ( 32, ptr )
+#define cpu_to_be64s( ptr ) __cpu_to_beNNs ( 64, ptr )
+#define le16_to_cpus( ptr ) __leNN_to_cpus ( 16, ptr )
+#define le32_to_cpus( ptr ) __leNN_to_cpus ( 32, ptr )
+#define le64_to_cpus( ptr ) __leNN_to_cpus ( 64, ptr )
+#define be16_to_cpus( ptr ) __beNN_to_cpus ( 16, ptr )
+#define be32_to_cpus( ptr ) __beNN_to_cpus ( 32, ptr )
+#define be64_to_cpus( ptr ) __beNN_to_cpus ( 64, ptr )
+
+#define htonll( value ) cpu_to_be64 (value)
+#define ntohll( value ) be64_to_cpu (value)
+#define htonl( value ) cpu_to_be32 (value)
+#define ntohl( value ) be32_to_cpu (value)
+#define htons( value ) cpu_to_be16 (value)
+#define ntohs( value ) be16_to_cpu (value)
+
+#endif /* _BITS_BYTESWAP_H */
diff --git a/wimboot/wimboot-2.7.3/src/cmdline.c b/wimboot/wimboot-2.7.3/src/cmdline.c
new file mode 100644 (file)
index 0000000..e070ccb
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Command line
+ *
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "wimboot.h"
+#include "cmdline.h"
+
+/** Use raw (unpatched) BCD files */
+int cmdline_rawbcd;
+
+/** Use raw (unpatched) WIM files */
+int cmdline_rawwim;
+
+/** Inhibit debugging output */
+int cmdline_quiet;
+
+/** Allow graphical output from bootmgr/bootmgfw */
+int cmdline_gui;
+
+/** Pause before booting OS */
+int cmdline_pause;
+
+/** Pause without displaying any prompt */
+int cmdline_pause_quiet;
+
+/** Use linear (unpaged) memory model */
+int cmdline_linear;
+
+/** WIM boot index */
+unsigned int cmdline_index;
+
+int cmdline_vf_num;
+char cmdline_vf_path[MAX_VF][64];
+
+file_size_pf pfventoy_file_size;
+file_read_pf pfventoy_file_read;
+
+/**
+ * Process command line
+ *
+ * @v cmdline          Command line
+ */
+void process_cmdline ( char *cmdline ) {
+       char *tmp = cmdline;
+       char *key;
+       char *value;
+       char *endp;
+
+       /* Do nothing if we have no command line */
+       if ( ( cmdline == NULL ) || ( cmdline[0] == '\0' ) )
+               return;
+
+       /* Parse command line */
+       while ( *tmp ) {
+
+               /* Skip whitespace */
+               while ( isspace ( *tmp ) )
+                       tmp++;
+
+               /* Find value (if any) and end of this argument */
+               key = tmp;
+               value = NULL;
+               while ( *tmp ) {
+                       if ( isspace ( *tmp ) ) {
+                               *(tmp++) = '\0';
+                               break;
+                       } else if ( *tmp == '=' ) {
+                               *(tmp++) = '\0';
+                               value = tmp;
+                       } else {
+                               tmp++;
+                       }
+               }
+
+               /* Process this argument */
+               if ( strcmp ( key, "rawbcd" ) == 0 ) {
+                       cmdline_rawbcd = 1;
+               } else if ( strcmp ( key, "rawwim" ) == 0 ) {
+                       cmdline_rawwim = 1;
+               } else if ( strcmp ( key, "gui" ) == 0 ) {
+                       cmdline_gui = 1;
+               }
+
+        else if ((key[0] == 'v') && (key[1] == 'f') ) {
+            if (cmdline_vf_num >= MAX_VF)
+                die("Too many vf\n");
+            snprintf(cmdline_vf_path[cmdline_vf_num], 64, "%s", value);
+            cmdline_vf_num++;
+               }else if ( strcmp ( key, "pfsize" ) == 0 ) {    
+            pfventoy_file_size = (file_size_pf)strtoul(value, &endp, 0);
+               } else if ( strcmp ( key, "pfread" ) == 0 ) {
+            pfventoy_file_read = (file_read_pf)strtoul(value, &endp, 0 );
+               }
+
+        else if ( strcmp ( key, "linear" ) == 0 ) {
+                       cmdline_linear = 1;
+               } else if ( strcmp ( key, "quiet" ) == 0 ) {
+                       cmdline_quiet = 1;
+               } else if ( strcmp ( key, "pause" ) == 0 ) {
+                       cmdline_pause = 1;
+                       if ( value && ( strcmp ( value, "quiet" ) == 0 ) )
+                               cmdline_pause_quiet = 1;
+               } else if ( strcmp ( key, "index" ) == 0 ) {
+                       if ( ( ! value ) || ( ! value[0] ) )
+                               die ( "Argument \"index\" needs a value\n" );
+                       cmdline_index = strtoul ( value, &endp, 0 );
+                       if ( *endp )
+                               die ( "Invalid index \"%s\"\n", value );
+               } else if ( strcmp ( key, "initrdfile" ) == 0 ) {
+                       /* Ignore this keyword to allow for use with syslinux */
+               } else if ( key == cmdline ) {
+                       /* Ignore unknown initial arguments, which may
+                        * be the program name.
+                        */
+               } else {
+                       die ( "Unrecognised argument \"%s%s%s\"\n", key,
+                             ( value ? "=" : "" ), ( value ? value : "" ) );
+               }
+       }
+
+       /* Show command line (after parsing "quiet" option) */
+       DBG ( "Command line: \"%s\" vf=%d pfsize=%p pfread=%p\n", 
+           cmdline, cmdline_vf_num, pfventoy_file_size, pfventoy_file_read);
+}
diff --git a/wimboot/wimboot-2.7.3/src/cmdline.h b/wimboot/wimboot-2.7.3/src/cmdline.h
new file mode 100644 (file)
index 0000000..73520c1
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef _CMDLINE_H
+#define _CMDLINE_H
+
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Command line
+ *
+ */
+
+extern int cmdline_rawbcd;
+extern int cmdline_rawwim;
+extern int cmdline_quiet;
+extern int cmdline_gui;
+extern int cmdline_pause;
+extern int cmdline_pause_quiet;
+extern int cmdline_linear;
+extern unsigned int cmdline_index;
+extern void process_cmdline ( char *cmdline );
+
+typedef int (*file_size_pf)(const char *path);
+typedef int (*file_read_pf)(const char *path, int offset, int len, void *buf);
+extern file_size_pf pfventoy_file_size;
+extern file_read_pf pfventoy_file_read;
+#define MAX_VF 16
+extern char cmdline_vf_path[MAX_VF][64];
+extern int cmdline_vf_num;
+
+#endif /* _CMDLINE_H */
diff --git a/wimboot/wimboot-2.7.3/src/compiler.h b/wimboot/wimboot-2.7.3/src/compiler.h
new file mode 100644 (file)
index 0000000..d5eb034
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef _COMPILER_H
+#define _COMPILER_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Global compiler definitions
+ *
+ */
+
+/* Force visibility of all symbols to "hidden", i.e. inform gcc that
+ * all symbol references resolve strictly within our final binary.
+ * This avoids unnecessary PLT/GOT entries on x86_64.
+ *
+ * This is a stronger claim than specifying "-fvisibility=hidden",
+ * since it also affects symbols marked with "extern".
+ */
+#ifndef ASSEMBLY
+#if __GNUC__ >= 4
+#pragma GCC visibility push(hidden)
+#endif
+#endif /* ASSEMBLY */
+
+#endif /* _COMPILER_H */
diff --git a/wimboot/wimboot-2.7.3/src/cookie.c b/wimboot/wimboot-2.7.3/src/cookie.c
new file mode 100644 (file)
index 0000000..c1cfa65
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Stack cookie
+ *
+ */
+
+#include "wimboot.h"
+
+/** Stack cookie */
+unsigned long __stack_chk_guard;
+
+/**
+ * Construct stack cookie value
+ *
+ */
+static __attribute__ (( noinline )) unsigned long make_cookie ( void ) {
+       union {
+               struct {
+                       uint32_t eax;
+                       uint32_t edx;
+               } __attribute__ (( packed ));
+               unsigned long tsc;
+       } u;
+       unsigned long cookie;
+
+       /* We have no viable source of entropy.  Use the CPU timestamp
+        * counter, which will have at least some minimal randomness
+        * in the low bits by the time we are invoked.
+        */
+       __asm__ ( "rdtsc" : "=a" ( u.eax ), "=d" ( u.edx ) );
+       cookie = u.tsc;
+
+       /* Ensure that the value contains a NUL byte, to act as a
+        * runaway string terminator.  Construct the NUL using a shift
+        * rather than a mask, to avoid losing valuable entropy in the
+        * lower-order bits.
+        */
+       cookie <<= 8;
+
+       return cookie;
+}
+
+/**
+ * Initialise stack cookie
+ *
+ * This function must not itself use stack guard
+ */
+void init_cookie ( void ) {
+
+       /* Set stack cookie value
+        *
+        * This function must not itself use stack protection, since
+        * the change in the stack guard value would trigger a false
+        * positive.
+        *
+        * There is unfortunately no way to annotate a function to
+        * exclude the use of stack protection.  We must therefore
+        * rely on correctly anticipating the compiler's decision on
+        * the use of stack protection.
+        */
+       __stack_chk_guard = make_cookie();
+}
+
+/**
+ * Abort on stack check failure
+ *
+ */
+void __stack_chk_fail ( void ) {
+
+       /* Abort program */
+       die ( "Stack check failed\n" );
+}
diff --git a/wimboot/wimboot-2.7.3/src/coverity-model.c b/wimboot/wimboot-2.7.3/src/coverity-model.c
new file mode 100644 (file)
index 0000000..e85c85a
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Coverity modelling file
+ *
+ */
+
+typedef unsigned short wchar_t;
+typedef void mbstate_t;
+
+/* Inhibit use of built-in models for functions where Coverity's
+ * assumptions about the modelled function are incorrect for wimboot.
+ */
+int getchar ( void ) {
+}
+size_t wcrtomb ( char *buf, wchar_t wc, mbstate_t *ps ) {
+}
diff --git a/wimboot/wimboot-2.7.3/src/cpio.c b/wimboot/wimboot-2.7.3/src/cpio.c
new file mode 100644 (file)
index 0000000..affb1d8
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * CPIO archives
+ *
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "wimboot.h"
+#include "cpio.h"
+
+/**
+ * Align CPIO length to nearest dword
+ *
+ * @v len              Length
+ * @ret len            Aligned length
+ */
+static size_t cpio_align ( size_t len ) {
+       return ( ( len + 0x03 ) & ~0x03 );
+}
+
+/**
+ * Parse CPIO field value
+ *
+ * @v field            ASCII field
+ * @ret value          Field value
+ */
+static unsigned long cpio_value ( const char *field ) {
+       char buf[9];
+
+       memcpy ( buf, field, ( sizeof ( buf ) - 1 ) );
+       buf[ sizeof ( buf ) - 1 ] = '\0';
+       return strtoul ( buf, NULL, 16 );
+}
+
+/**
+ * Extract files from CPIO archive
+ *
+ * @v data             CPIO archive
+ * @v len              Maximum length of CPIO archive
+ * @v file             File handler
+ * @ret rc             Return status code
+ */
+int cpio_extract ( void *data, size_t len,
+                  int ( * file ) ( const char *name, void *data,
+                                   size_t len ) ) {
+       const struct cpio_header *cpio;
+       const uint32_t *pad;
+       const char *file_name;
+       void *file_data;
+       size_t file_name_len;
+       size_t file_len;
+       size_t cpio_len;
+       int rc;
+
+       while ( 1 ) {
+
+               /* Skip over any padding */
+               while ( len >= sizeof ( *pad ) ) {
+                       pad = data;
+                       if ( *pad )
+                               break;
+                       data += sizeof ( *pad );
+                       len -= sizeof ( *pad );
+               }
+
+               /* Stop if we have reached the end of the archive */
+               if ( ! len )
+                       return 0;
+
+               /* Sanity check */
+               if ( len < sizeof ( *cpio ) ) {
+                       DBG ( "Truncated CPIO header\n" );
+                       return -1;
+               }
+               cpio = data;
+
+               /* Check magic */
+               if ( memcmp ( cpio->c_magic, CPIO_MAGIC,
+                             sizeof ( cpio->c_magic ) ) != 0 ) {
+                       DBG ( "Bad CPIO magic\n" );
+                       return -1;
+               }
+
+               /* Extract file parameters */
+               file_name = ( ( void * ) ( cpio + 1 ) );
+               file_name_len = cpio_value ( cpio->c_namesize );
+               file_data = ( data + cpio_align ( sizeof ( *cpio ) +
+                                                 file_name_len ) );
+               file_len = cpio_value ( cpio->c_filesize );
+               cpio_len = ( file_data + file_len - data );
+               if ( cpio_len < len )
+                       cpio_len = cpio_align ( cpio_len );
+               if ( cpio_len > len ) {
+                       DBG ( "Truncated CPIO file\n" );
+                       return -1;
+               }
+
+               /* If we reach the trailer, we're done */
+               if ( strcmp ( file_name, CPIO_TRAILER ) == 0 )
+                       return 0;
+
+               /* Process file */
+               if ( ( rc = file ( file_name, file_data, file_len ) ) != 0 )
+                       return rc;
+
+               /* Move to next file */
+               data += cpio_len;
+               len -= cpio_len;
+       }
+}
diff --git a/wimboot/wimboot-2.7.3/src/cpio.h b/wimboot/wimboot-2.7.3/src/cpio.h
new file mode 100644 (file)
index 0000000..b689b06
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef _CPIO_H
+#define _CPIO_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * CPIO archives
+ *
+ */
+
+#include <stdint.h>
+
+/** A CPIO archive header
+ *
+ * All field are hexadecimal ASCII numbers padded with '0' on the
+ * left to the full width of the field.
+ */
+struct cpio_header {
+       /** The string "070701" or "070702" */
+       char c_magic[6];
+       /** File inode number */
+       char c_ino[8];
+       /** File mode and permissions */
+       char c_mode[8];
+       /** File uid */
+       char c_uid[8];
+       /** File gid */
+       char c_gid[8];
+       /** Number of links */
+       char c_nlink[8];
+       /** Modification time */
+       char c_mtime[8];
+       /** Size of data field */
+       char c_filesize[8];
+       /** Major part of file device number */
+       char c_maj[8];
+       /** Minor part of file device number */
+       char c_min[8];
+       /** Major part of device node reference */
+       char c_rmaj[8];
+       /** Minor part of device node reference */
+       char c_rmin[8];
+       /** Length of filename, including final NUL */
+       char c_namesize[8];
+       /** Checksum of data field if c_magic is 070702, othersize zero */
+       char c_chksum[8];
+} __attribute__ (( packed ));
+
+/** CPIO magic */
+#define CPIO_MAGIC "070701"
+
+/** CPIO trailer */
+#define CPIO_TRAILER "TRAILER!!!"
+
+extern int cpio_extract ( void *data, size_t len,
+                         int ( * file ) ( const char *name, void *data,
+                                          size_t len ) );
+
+#endif /* _CPIO_H */
diff --git a/wimboot/wimboot-2.7.3/src/ctype.h b/wimboot/wimboot-2.7.3/src/ctype.h
new file mode 100644 (file)
index 0000000..6138158
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _CTYPE_H
+#define _CTYPE_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Character types
+ *
+ */
+
+static inline int islower ( int c ) {
+       return ( ( c >= 'a' ) && ( c <= 'z' ) );
+}
+
+static inline int isupper ( int c ) {
+       return ( ( c >= 'A' ) && ( c <= 'Z' ) );
+}
+
+static inline int toupper ( int c ) {
+
+       if ( islower ( c ) )
+               c -= ( 'a' - 'A' );
+       return c;
+}
+
+extern int isspace ( int c );
+
+#endif /* _CTYPE_H */
diff --git a/wimboot/wimboot-2.7.3/src/die.c b/wimboot/wimboot-2.7.3/src/die.c
new file mode 100644 (file)
index 0000000..54e287e
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Fatal errors
+ *
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "wimboot.h"
+#include "efi.h"
+
+/**
+ * Handle fatal errors
+ *
+ * @v fmt      Error message format string
+ * @v ...      Arguments
+ */
+void die ( const char *fmt, ... ) {
+       EFI_BOOT_SERVICES *bs;
+       EFI_RUNTIME_SERVICES *rs;
+       va_list args;
+
+       /* Print message */
+       va_start ( args, fmt );
+       vprintf ( fmt, args );
+       va_end ( args );
+
+       /* Reboot or exit as applicable */
+       if ( efi_systab ) {
+
+               /* Exit */
+               bs = efi_systab->BootServices;
+               bs->Exit ( efi_image_handle, EFI_LOAD_ERROR, 0, NULL );
+               printf ( "Failed to exit\n" );
+               rs = efi_systab->RuntimeServices;
+               rs->ResetSystem ( EfiResetWarm, 0, 0, NULL );
+               printf ( "Failed to reboot\n" );
+
+       } else {
+
+               /* Wait for keypress */
+               printf ( "Press a key to reboot..." );
+               getchar();
+               printf ( "\n" );
+
+               /* Reboot system */
+               reboot();
+       }
+
+       /* Should be impossible to reach this */
+       __builtin_unreachable();
+}
diff --git a/wimboot/wimboot-2.7.3/src/efi.c b/wimboot/wimboot-2.7.3/src/efi.c
new file mode 100644 (file)
index 0000000..1be33e9
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * EFI interface
+ *
+ */
+
+#include "wimboot.h"
+#include "efi.h"
+
+/** EFI system table */
+EFI_SYSTEM_TABLE *efi_systab;
+
+/** EFI image handle */
+EFI_HANDLE efi_image_handle;
diff --git a/wimboot/wimboot-2.7.3/src/efi.h b/wimboot/wimboot-2.7.3/src/efi.h
new file mode 100644 (file)
index 0000000..afc7c42
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef _EFI_H
+#define _EFI_H
+
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * EFI definitions
+ *
+ */
+
+/* EFIAPI definition */
+#if __x86_64__
+#define EFIAPI __attribute__ (( ms_abi ))
+#else
+#define EFIAPI
+#endif
+
+/* EFI headers rudely redefine NULL */
+#undef NULL
+
+#include "efi/Uefi.h"
+#include "efi/Protocol/LoadedImage.h"
+
+extern EFI_SYSTEM_TABLE *efi_systab;
+extern EFI_HANDLE efi_image_handle;
+
+extern EFI_GUID efi_block_io_protocol_guid;
+extern EFI_GUID efi_device_path_protocol_guid;
+extern EFI_GUID efi_graphics_output_protocol_guid;
+extern EFI_GUID efi_loaded_image_protocol_guid;
+extern EFI_GUID efi_simple_file_system_protocol_guid;
+
+#endif /* _EFI_H */
diff --git a/wimboot/wimboot-2.7.3/src/efi/Base.h b/wimboot/wimboot-2.7.3/src/efi/Base.h
new file mode 100644 (file)
index 0000000..488f0ef
--- /dev/null
@@ -0,0 +1,1021 @@
+/** @file
+  Root include file for Mde Package Base type modules
+
+  This is the include file for any module of type base. Base modules only use
+  types defined via this include file and can be ported easily to any
+  environment. There are a set of base libraries in the Mde Package that can
+  be used to implement base modules.
+
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#ifndef __BASE_H__
+#define __BASE_H__
+
+//
+// Include processor specific binding
+//
+#include "efi/ProcessorBind.h"
+
+
+/**
+  Verifies the storage size of a given data type.
+
+  This macro generates a divide by zero error or a zero size array declaration in
+  the preprocessor if the size is incorrect.  These are declared as "extern" so
+  the space for these arrays will not be in the modules.
+
+  @param  TYPE  The date type to determine the size of.
+  @param  Size  The expected size for the TYPE.
+
+**/
+#define VERIFY_SIZE_OF(TYPE, Size) extern UINT8 _VerifySizeof##TYPE[(sizeof(TYPE) == (Size)) / (sizeof(TYPE) == (Size))]
+
+//
+// Verify that ProcessorBind.h produced UEFI Data Types that are compliant with
+// Section 2.3.1 of the UEFI 2.3 Specification.
+//
+VERIFY_SIZE_OF (BOOLEAN, 1);
+VERIFY_SIZE_OF (INT8, 1);
+VERIFY_SIZE_OF (UINT8, 1);
+VERIFY_SIZE_OF (INT16, 2);
+VERIFY_SIZE_OF (UINT16, 2);
+VERIFY_SIZE_OF (INT32, 4);
+VERIFY_SIZE_OF (UINT32, 4);
+VERIFY_SIZE_OF (INT64, 8);
+VERIFY_SIZE_OF (UINT64, 8);
+VERIFY_SIZE_OF (CHAR8, 1);
+VERIFY_SIZE_OF (CHAR16, 2);
+
+//
+// The Microsoft* C compiler can removed references to unreferenced data items
+//  if the /OPT:REF linker option is used. We defined a macro as this is a
+//  a non standard extension
+//
+#if defined(_MSC_EXTENSIONS) && !defined (MDE_CPU_EBC)
+  ///
+  /// Remove global variable from the linked image if there are no references to
+  /// it after all compiler and linker optimizations have been performed.
+  ///
+  ///
+  #define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany)
+#else
+  ///
+  /// Remove the global variable from the linked image if there are no references
+  ///  to it after all compiler and linker optimizations have been performed.
+  ///
+  ///
+  #define GLOBAL_REMOVE_IF_UNREFERENCED
+#endif
+
+//
+// For symbol name in GNU assembly code, an extra "_" is necessary
+//
+#if defined(__GNUC__)
+  ///
+  /// Private worker functions for ASM_PFX()
+  ///
+  #define _CONCATENATE(a, b)  __CONCATENATE(a, b)
+  #define __CONCATENATE(a, b) a ## b
+
+  ///
+  /// The __USER_LABEL_PREFIX__ macro predefined by GNUC represents the prefix
+  /// on symbols in assembly language.
+  ///
+  #define ASM_PFX(name) _CONCATENATE (__USER_LABEL_PREFIX__, name)
+#endif
+
+#if __APPLE__
+  //
+  // Apple extension that is used by the linker to optimize code size
+  // with assembly functions. Put at the end of your .S files
+  //
+  #define ASM_FUNCTION_REMOVE_IF_UNREFERENCED  .subsections_via_symbols
+#else
+  #define ASM_FUNCTION_REMOVE_IF_UNREFERENCED
+#endif
+
+#ifdef __CC_ARM
+  //
+  // Older RVCT ARM compilers don't fully support #pragma pack and require __packed
+  // as a prefix for the structure.
+  //
+  #define PACKED  __packed
+#else
+  #define PACKED
+#endif
+
+///
+/// 128 bit buffer containing a unique identifier value.
+/// Unless otherwise specified, aligned on a 64 bit boundary.
+///
+typedef struct {
+  UINT32  Data1;
+  UINT16  Data2;
+  UINT16  Data3;
+  UINT8   Data4[8];
+} GUID;
+
+//
+// 8-bytes unsigned value that represents a physical system address.
+//
+typedef UINT64 PHYSICAL_ADDRESS;
+
+///
+/// LIST_ENTRY structure definition.
+///
+typedef struct _LIST_ENTRY LIST_ENTRY;
+
+///
+/// _LIST_ENTRY structure definition.
+///
+struct _LIST_ENTRY {
+  LIST_ENTRY  *ForwardLink;
+  LIST_ENTRY  *BackLink;
+};
+
+//
+// Modifiers to abstract standard types to aid in debug of problems
+//
+
+///
+/// Datum is read-only.
+///
+#define CONST     const
+
+///
+/// Datum is scoped to the current file or function.
+///
+#define STATIC    static
+
+///
+/// Undeclared type.
+///
+#define VOID      void
+
+//
+// Modifiers for Data Types used to self document code.
+// This concept is borrowed for UEFI specification.
+//
+
+///
+/// Datum is passed to the function.
+///
+#define IN
+
+///
+/// Datum is returned from the function.
+///
+#define OUT
+
+///
+/// Passing the datum to the function is optional, and a NULL
+/// is passed if the value is not supplied.
+///
+#define OPTIONAL
+
+//
+//  UEFI specification claims 1 and 0. We are concerned about the
+//  complier portability so we did it this way.
+//
+
+///
+/// Boolean true value.  UEFI Specification defines this value to be 1,
+/// but this form is more portable.
+///
+#define TRUE  ((BOOLEAN)(1==1))
+
+///
+/// Boolean false value.  UEFI Specification defines this value to be 0,
+/// but this form is more portable.
+///
+#define FALSE ((BOOLEAN)(0==1))
+
+///
+/// NULL pointer (VOID *)
+///
+#define NULL  ((VOID *) 0)
+
+///
+/// Maximum values for common UEFI Data Types
+///
+#define MAX_INT8    ((INT8)0x7F)
+#define MAX_UINT8   ((UINT8)0xFF)
+#define MAX_INT16   ((INT16)0x7FFF)
+#define MAX_UINT16  ((UINT16)0xFFFF)
+#define MAX_INT32   ((INT32)0x7FFFFFFF)
+#define MAX_UINT32  ((UINT32)0xFFFFFFFF)
+#define MAX_INT64   ((INT64)0x7FFFFFFFFFFFFFFFULL)
+#define MAX_UINT64  ((UINT64)0xFFFFFFFFFFFFFFFFULL)
+
+#define  BIT0     0x00000001
+#define  BIT1     0x00000002
+#define  BIT2     0x00000004
+#define  BIT3     0x00000008
+#define  BIT4     0x00000010
+#define  BIT5     0x00000020
+#define  BIT6     0x00000040
+#define  BIT7     0x00000080
+#define  BIT8     0x00000100
+#define  BIT9     0x00000200
+#define  BIT10    0x00000400
+#define  BIT11    0x00000800
+#define  BIT12    0x00001000
+#define  BIT13    0x00002000
+#define  BIT14    0x00004000
+#define  BIT15    0x00008000
+#define  BIT16    0x00010000
+#define  BIT17    0x00020000
+#define  BIT18    0x00040000
+#define  BIT19    0x00080000
+#define  BIT20    0x00100000
+#define  BIT21    0x00200000
+#define  BIT22    0x00400000
+#define  BIT23    0x00800000
+#define  BIT24    0x01000000
+#define  BIT25    0x02000000
+#define  BIT26    0x04000000
+#define  BIT27    0x08000000
+#define  BIT28    0x10000000
+#define  BIT29    0x20000000
+#define  BIT30    0x40000000
+#define  BIT31    0x80000000
+#define  BIT32    0x0000000100000000ULL
+#define  BIT33    0x0000000200000000ULL
+#define  BIT34    0x0000000400000000ULL
+#define  BIT35    0x0000000800000000ULL
+#define  BIT36    0x0000001000000000ULL
+#define  BIT37    0x0000002000000000ULL
+#define  BIT38    0x0000004000000000ULL
+#define  BIT39    0x0000008000000000ULL
+#define  BIT40    0x0000010000000000ULL
+#define  BIT41    0x0000020000000000ULL
+#define  BIT42    0x0000040000000000ULL
+#define  BIT43    0x0000080000000000ULL
+#define  BIT44    0x0000100000000000ULL
+#define  BIT45    0x0000200000000000ULL
+#define  BIT46    0x0000400000000000ULL
+#define  BIT47    0x0000800000000000ULL
+#define  BIT48    0x0001000000000000ULL
+#define  BIT49    0x0002000000000000ULL
+#define  BIT50    0x0004000000000000ULL
+#define  BIT51    0x0008000000000000ULL
+#define  BIT52    0x0010000000000000ULL
+#define  BIT53    0x0020000000000000ULL
+#define  BIT54    0x0040000000000000ULL
+#define  BIT55    0x0080000000000000ULL
+#define  BIT56    0x0100000000000000ULL
+#define  BIT57    0x0200000000000000ULL
+#define  BIT58    0x0400000000000000ULL
+#define  BIT59    0x0800000000000000ULL
+#define  BIT60    0x1000000000000000ULL
+#define  BIT61    0x2000000000000000ULL
+#define  BIT62    0x4000000000000000ULL
+#define  BIT63    0x8000000000000000ULL
+
+#define  SIZE_1KB    0x00000400
+#define  SIZE_2KB    0x00000800
+#define  SIZE_4KB    0x00001000
+#define  SIZE_8KB    0x00002000
+#define  SIZE_16KB   0x00004000
+#define  SIZE_32KB   0x00008000
+#define  SIZE_64KB   0x00010000
+#define  SIZE_128KB  0x00020000
+#define  SIZE_256KB  0x00040000
+#define  SIZE_512KB  0x00080000
+#define  SIZE_1MB    0x00100000
+#define  SIZE_2MB    0x00200000
+#define  SIZE_4MB    0x00400000
+#define  SIZE_8MB    0x00800000
+#define  SIZE_16MB   0x01000000
+#define  SIZE_32MB   0x02000000
+#define  SIZE_64MB   0x04000000
+#define  SIZE_128MB  0x08000000
+#define  SIZE_256MB  0x10000000
+#define  SIZE_512MB  0x20000000
+#define  SIZE_1GB    0x40000000
+#define  SIZE_2GB    0x80000000
+#define  SIZE_4GB    0x0000000100000000ULL
+#define  SIZE_8GB    0x0000000200000000ULL
+#define  SIZE_16GB   0x0000000400000000ULL
+#define  SIZE_32GB   0x0000000800000000ULL
+#define  SIZE_64GB   0x0000001000000000ULL
+#define  SIZE_128GB  0x0000002000000000ULL
+#define  SIZE_256GB  0x0000004000000000ULL
+#define  SIZE_512GB  0x0000008000000000ULL
+#define  SIZE_1TB    0x0000010000000000ULL
+#define  SIZE_2TB    0x0000020000000000ULL
+#define  SIZE_4TB    0x0000040000000000ULL
+#define  SIZE_8TB    0x0000080000000000ULL
+#define  SIZE_16TB   0x0000100000000000ULL
+#define  SIZE_32TB   0x0000200000000000ULL
+#define  SIZE_64TB   0x0000400000000000ULL
+#define  SIZE_128TB  0x0000800000000000ULL
+#define  SIZE_256TB  0x0001000000000000ULL
+#define  SIZE_512TB  0x0002000000000000ULL
+#define  SIZE_1PB    0x0004000000000000ULL
+#define  SIZE_2PB    0x0008000000000000ULL
+#define  SIZE_4PB    0x0010000000000000ULL
+#define  SIZE_8PB    0x0020000000000000ULL
+#define  SIZE_16PB   0x0040000000000000ULL
+#define  SIZE_32PB   0x0080000000000000ULL
+#define  SIZE_64PB   0x0100000000000000ULL
+#define  SIZE_128PB  0x0200000000000000ULL
+#define  SIZE_256PB  0x0400000000000000ULL
+#define  SIZE_512PB  0x0800000000000000ULL
+#define  SIZE_1EB    0x1000000000000000ULL
+#define  SIZE_2EB    0x2000000000000000ULL
+#define  SIZE_4EB    0x4000000000000000ULL
+#define  SIZE_8EB    0x8000000000000000ULL
+
+#define  BASE_1KB    0x00000400
+#define  BASE_2KB    0x00000800
+#define  BASE_4KB    0x00001000
+#define  BASE_8KB    0x00002000
+#define  BASE_16KB   0x00004000
+#define  BASE_32KB   0x00008000
+#define  BASE_64KB   0x00010000
+#define  BASE_128KB  0x00020000
+#define  BASE_256KB  0x00040000
+#define  BASE_512KB  0x00080000
+#define  BASE_1MB    0x00100000
+#define  BASE_2MB    0x00200000
+#define  BASE_4MB    0x00400000
+#define  BASE_8MB    0x00800000
+#define  BASE_16MB   0x01000000
+#define  BASE_32MB   0x02000000
+#define  BASE_64MB   0x04000000
+#define  BASE_128MB  0x08000000
+#define  BASE_256MB  0x10000000
+#define  BASE_512MB  0x20000000
+#define  BASE_1GB    0x40000000
+#define  BASE_2GB    0x80000000
+#define  BASE_4GB    0x0000000100000000ULL
+#define  BASE_8GB    0x0000000200000000ULL
+#define  BASE_16GB   0x0000000400000000ULL
+#define  BASE_32GB   0x0000000800000000ULL
+#define  BASE_64GB   0x0000001000000000ULL
+#define  BASE_128GB  0x0000002000000000ULL
+#define  BASE_256GB  0x0000004000000000ULL
+#define  BASE_512GB  0x0000008000000000ULL
+#define  BASE_1TB    0x0000010000000000ULL
+#define  BASE_2TB    0x0000020000000000ULL
+#define  BASE_4TB    0x0000040000000000ULL
+#define  BASE_8TB    0x0000080000000000ULL
+#define  BASE_16TB   0x0000100000000000ULL
+#define  BASE_32TB   0x0000200000000000ULL
+#define  BASE_64TB   0x0000400000000000ULL
+#define  BASE_128TB  0x0000800000000000ULL
+#define  BASE_256TB  0x0001000000000000ULL
+#define  BASE_512TB  0x0002000000000000ULL
+#define  BASE_1PB    0x0004000000000000ULL
+#define  BASE_2PB    0x0008000000000000ULL
+#define  BASE_4PB    0x0010000000000000ULL
+#define  BASE_8PB    0x0020000000000000ULL
+#define  BASE_16PB   0x0040000000000000ULL
+#define  BASE_32PB   0x0080000000000000ULL
+#define  BASE_64PB   0x0100000000000000ULL
+#define  BASE_128PB  0x0200000000000000ULL
+#define  BASE_256PB  0x0400000000000000ULL
+#define  BASE_512PB  0x0800000000000000ULL
+#define  BASE_1EB    0x1000000000000000ULL
+#define  BASE_2EB    0x2000000000000000ULL
+#define  BASE_4EB    0x4000000000000000ULL
+#define  BASE_8EB    0x8000000000000000ULL
+
+//
+//  Support for variable length argument lists using the ANSI standard.
+//
+//  Since we are using the ANSI standard we used the standard naming and
+//  did not follow the coding convention
+//
+//  VA_LIST  - typedef for argument list.
+//  VA_START (VA_LIST Marker, argument before the ...) - Init Marker for use.
+//  VA_END (VA_LIST Marker) - Clear Marker
+//  VA_ARG (VA_LIST Marker, var arg size) - Use Marker to get an argument from
+//    the ... list. You must know the size and pass it in this macro.
+//  VA_COPY (VA_LIST Dest, VA_LIST Start) - Initialize Dest as a copy of Start.
+//
+//  example:
+//
+//  UINTN
+//  ExampleVarArg (
+//    IN UINTN  NumberOfArgs,
+//    ...
+//    )
+//  {
+//    VA_LIST Marker;
+//    UINTN   Index;
+//    UINTN   Result;
+//
+//    //
+//    // Initialize the Marker
+//    //
+//    VA_START (Marker, NumberOfArgs);
+//    for (Index = 0, Result = 0; Index < NumberOfArgs; Index++) {
+//      //
+//      // The ... list is a series of UINTN values, so average them up.
+//      //
+//      Result += VA_ARG (Marker, UINTN);
+//    }
+//
+//    VA_END (Marker);
+//    return Result
+//  }
+//
+
+/**
+  Return the size of argument that has been aligned to sizeof (UINTN).
+
+  @param  n    The parameter size to be aligned.
+
+  @return The aligned size.
+**/
+#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1))
+
+#if defined(__CC_ARM)
+//
+// RVCT ARM variable argument list support.
+//
+
+///
+/// Variable used to traverse the list of arguments. This type can vary by
+/// implementation and could be an array or structure.
+///
+#ifdef __APCS_ADSABI
+  typedef int         *va_list[1];
+  #define VA_LIST     va_list
+#else
+  typedef struct __va_list { void *__ap; } va_list;
+  #define VA_LIST                          va_list
+#endif
+
+#define VA_START(Marker, Parameter)   __va_start(Marker, Parameter)
+
+#define VA_ARG(Marker, TYPE)          __va_arg(Marker, TYPE)
+
+#define VA_END(Marker)                ((void)0)
+
+// For some ARM RVCT compilers, __va_copy is not defined
+#ifndef __va_copy
+  #define __va_copy(dest, src) ((void)((dest) = (src)))
+#endif
+
+#define VA_COPY(Dest, Start)          __va_copy (Dest, Start)
+
+#elif defined(__GNUC__) && !defined(NO_BUILTIN_VA_FUNCS)
+//
+// Use GCC built-in macros for variable argument lists.
+//
+
+///
+/// Variable used to traverse the list of arguments. This type can vary by
+/// implementation and could be an array or structure.
+///
+typedef __builtin_va_list VA_LIST;
+
+#define VA_START(Marker, Parameter)  __builtin_va_start (Marker, Parameter)
+
+#define VA_ARG(Marker, TYPE)         ((sizeof (TYPE) < sizeof (UINTN)) ? (TYPE)(__builtin_va_arg (Marker, UINTN)) : (TYPE)(__builtin_va_arg (Marker, TYPE)))
+
+#define VA_END(Marker)               __builtin_va_end (Marker)
+
+#define VA_COPY(Dest, Start)         __builtin_va_copy (Dest, Start)
+
+#else
+///
+/// Variable used to traverse the list of arguments. This type can vary by
+/// implementation and could be an array or structure.
+///
+typedef CHAR8 *VA_LIST;
+
+/**
+  Retrieves a pointer to the beginning of a variable argument list, based on
+  the name of the parameter that immediately precedes the variable argument list.
+
+  This function initializes Marker to point to the beginning of the variable
+  argument list that immediately follows Parameter.  The method for computing the
+  pointer to the next argument in the argument list is CPU-specific following the
+  EFIAPI ABI.
+
+  @param   Marker       The VA_LIST used to traverse the list of arguments.
+  @param   Parameter    The name of the parameter that immediately precedes
+                        the variable argument list.
+
+  @return  A pointer to the beginning of a variable argument list.
+
+**/
+#define VA_START(Marker, Parameter) (Marker = (VA_LIST) ((UINTN) & (Parameter) + _INT_SIZE_OF (Parameter)))
+
+/**
+  Returns an argument of a specified type from a variable argument list and updates
+  the pointer to the variable argument list to point to the next argument.
+
+  This function returns an argument of the type specified by TYPE from the beginning
+  of the variable argument list specified by Marker.  Marker is then updated to point
+  to the next argument in the variable argument list.  The method for computing the
+  pointer to the next argument in the argument list is CPU-specific following the EFIAPI ABI.
+
+  @param   Marker   VA_LIST used to traverse the list of arguments.
+  @param   TYPE     The type of argument to retrieve from the beginning
+                    of the variable argument list.
+
+  @return  An argument of the type specified by TYPE.
+
+**/
+#define VA_ARG(Marker, TYPE)   (*(TYPE *) ((Marker += _INT_SIZE_OF (TYPE)) - _INT_SIZE_OF (TYPE)))
+
+/**
+  Terminates the use of a variable argument list.
+
+  This function initializes Marker so it can no longer be used with VA_ARG().
+  After this macro is used, the only way to access the variable argument list is
+  by using VA_START() again.
+
+  @param   Marker   VA_LIST used to traverse the list of arguments.
+
+**/
+#define VA_END(Marker)      (Marker = (VA_LIST) 0)
+
+/**
+  Initializes a VA_LIST as a copy of an existing VA_LIST.
+
+  This macro initializes Dest as a copy of Start, as if the VA_START macro had been applied to Dest
+  followed by the same sequence of uses of the VA_ARG macro as had previously been used to reach
+  the present state of Start.
+
+  @param   Dest   VA_LIST used to traverse the list of arguments.
+  @param   Start  VA_LIST used to traverse the list of arguments.
+
+**/
+#define VA_COPY(Dest, Start)  ((void)((Dest) = (Start)))
+
+#endif
+
+///
+/// Pointer to the start of a variable argument list stored in a memory buffer. Same as UINT8 *.
+///
+typedef UINTN  *BASE_LIST;
+
+/**
+  Returns the size of a data type in sizeof(UINTN) units rounded up to the nearest UINTN boundary.
+
+  @param  TYPE  The date type to determine the size of.
+
+  @return The size of TYPE in sizeof (UINTN) units rounded up to the nearest UINTN boundary.
+**/
+#define _BASE_INT_SIZE_OF(TYPE) ((sizeof (TYPE) + sizeof (UINTN) - 1) / sizeof (UINTN))
+
+/**
+  Returns an argument of a specified type from a variable argument list and updates
+  the pointer to the variable argument list to point to the next argument.
+
+  This function returns an argument of the type specified by TYPE from the beginning
+  of the variable argument list specified by Marker.  Marker is then updated to point
+  to the next argument in the variable argument list.  The method for computing the
+  pointer to the next argument in the argument list is CPU specific following the EFIAPI ABI.
+
+  @param   Marker   The pointer to the beginning of a variable argument list.
+  @param   TYPE     The type of argument to retrieve from the beginning
+                    of the variable argument list.
+
+  @return  An argument of the type specified by TYPE.
+
+**/
+#define BASE_ARG(Marker, TYPE)   (*(TYPE *) ((Marker += _BASE_INT_SIZE_OF (TYPE)) - _BASE_INT_SIZE_OF (TYPE)))
+
+/**
+  The macro that returns the byte offset of a field in a data structure.
+
+  This function returns the offset, in bytes, of field specified by Field from the
+  beginning of the  data structure specified by TYPE. If TYPE does not contain Field,
+  the module will not compile.
+
+  @param   TYPE     The name of the data structure that contains the field specified by Field.
+  @param   Field    The name of the field in the data structure.
+
+  @return  Offset, in bytes, of field.
+
+**/
+#ifdef __GNUC__
+#if __GNUC__ >= 4
+#define OFFSET_OF(TYPE, Field) ((UINTN) __builtin_offsetof(TYPE, Field))
+#endif
+#endif
+
+#ifndef OFFSET_OF
+#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
+#endif
+
+/**
+  Macro that returns a pointer to the data structure that contains a specified field of
+  that data structure.  This is a lightweight method to hide information by placing a
+  public data structure inside a larger private data structure and using a pointer to
+  the public data structure to retrieve a pointer to the private data structure.
+
+  This function computes the offset, in bytes, of field specified by Field from the beginning
+  of the  data structure specified by TYPE.  This offset is subtracted from Record, and is
+  used to return a pointer to a data structure of the type specified by TYPE. If the data type
+  specified by TYPE does not contain the field specified by Field, then the module will not compile.
+
+  @param   Record   Pointer to the field specified by Field within a data structure of type TYPE.
+  @param   TYPE     The name of the data structure type to return.  This data structure must
+                    contain the field specified by Field.
+  @param   Field    The name of the field in the data structure specified by TYPE to which Record points.
+
+  @return  A pointer to the structure from one of it's elements.
+
+**/
+#define BASE_CR(Record, TYPE, Field)  ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
+
+/**
+  Rounds a value up to the next boundary using a specified alignment.
+
+  This function rounds Value up to the next boundary using the specified Alignment.
+  This aligned value is returned.
+
+  @param   Value      The value to round up.
+  @param   Alignment  The alignment boundary used to return the aligned value.
+
+  @return  A value up to the next boundary.
+
+**/
+#define ALIGN_VALUE(Value, Alignment) ((Value) + (((Alignment) - (Value)) & ((Alignment) - 1)))
+
+/**
+  Adjust a pointer by adding the minimum offset required for it to be aligned on
+  a specified alignment boundary.
+
+  This function rounds the pointer specified by Pointer to the next alignment boundary
+  specified by Alignment. The pointer to the aligned address is returned.
+
+  @param   Pointer    The pointer to round up.
+  @param   Alignment  The alignment boundary to use to return an aligned pointer.
+
+  @return  Pointer to the aligned address.
+
+**/
+#define ALIGN_POINTER(Pointer, Alignment) ((VOID *) (ALIGN_VALUE ((UINTN)(Pointer), (Alignment))))
+
+/**
+  Rounds a value up to the next natural boundary for the current CPU.
+  This is 4-bytes for 32-bit CPUs and 8-bytes for 64-bit CPUs.
+
+  This function rounds the value specified by Value up to the next natural boundary for the
+  current CPU. This rounded value is returned.
+
+  @param   Value      The value to round up.
+
+  @return  Rounded value specified by Value.
+
+**/
+#define ALIGN_VARIABLE(Value)  ALIGN_VALUE ((Value), sizeof (UINTN))
+
+
+/**
+  Return the maximum of two operands.
+
+  This macro returns the maximum of two operand specified by a and b.
+  Both a and b must be the same numerical types, signed or unsigned.
+
+  @param   a        The first operand with any numerical type.
+  @param   b        The second operand. Can be any numerical type as long as is
+                    the same type as a.
+
+  @return  Maximum of two operands.
+
+**/
+#define MAX(a, b)                       \
+  (((a) > (b)) ? (a) : (b))
+
+/**
+  Return the minimum of two operands.
+
+  This macro returns the minimal of two operand specified by a and b.
+  Both a and b must be the same numerical types, signed or unsigned.
+
+  @param   a        The first operand with any numerical type.
+  @param   b        The second operand. It should be the same any numerical type with a.
+
+  @return  Minimum of two operands.
+
+**/
+#define MIN(a, b)                       \
+  (((a) < (b)) ? (a) : (b))
+
+/**
+  Return the absolute value of a signed operand.
+
+  This macro returns the absolute value of the signed operand specified by a.
+
+  @param   a        The signed operand.
+
+  @return  The absolute value of the signed operand.
+
+**/
+#define ABS(a)                          \
+  (((a) < 0) ? (-(a)) : (a))
+
+//
+// Status codes common to all execution phases
+//
+typedef UINTN RETURN_STATUS;
+
+/**
+  Produces a RETURN_STATUS code with the highest bit set.
+
+  @param  StatusCode    The status code value to convert into a warning code.
+                        StatusCode must be in the range 0x00000000..0x7FFFFFFF.
+
+  @return The value specified by StatusCode with the highest bit set.
+
+**/
+#define ENCODE_ERROR(StatusCode)     ((RETURN_STATUS)(MAX_BIT | (StatusCode)))
+
+/**
+  Produces a RETURN_STATUS code with the highest bit clear.
+
+  @param  StatusCode    The status code value to convert into a warning code.
+                        StatusCode must be in the range 0x00000000..0x7FFFFFFF.
+
+  @return The value specified by StatusCode with the highest bit clear.
+
+**/
+#define ENCODE_WARNING(StatusCode)   ((RETURN_STATUS)(StatusCode))
+
+/**
+  Returns TRUE if a specified RETURN_STATUS code is an error code.
+
+  This function returns TRUE if StatusCode has the high bit set.  Otherwise, FALSE is returned.
+
+  @param  StatusCode    The status code value to evaluate.
+
+  @retval TRUE          The high bit of StatusCode is set.
+  @retval FALSE         The high bit of StatusCode is clear.
+
+**/
+#define RETURN_ERROR(StatusCode)     (((INTN)(RETURN_STATUS)(StatusCode)) < 0)
+
+///
+/// The operation completed successfully.
+///
+#define RETURN_SUCCESS               0
+
+///
+/// The image failed to load.
+///
+#define RETURN_LOAD_ERROR            ENCODE_ERROR (1)
+
+///
+/// The parameter was incorrect.
+///
+#define RETURN_INVALID_PARAMETER     ENCODE_ERROR (2)
+
+///
+/// The operation is not supported.
+///
+#define RETURN_UNSUPPORTED           ENCODE_ERROR (3)
+
+///
+/// The buffer was not the proper size for the request.
+///
+#define RETURN_BAD_BUFFER_SIZE       ENCODE_ERROR (4)
+
+///
+/// The buffer was not large enough to hold the requested data.
+/// The required buffer size is returned in the appropriate
+/// parameter when this error occurs.
+///
+#define RETURN_BUFFER_TOO_SMALL      ENCODE_ERROR (5)
+
+///
+/// There is no data pending upon return.
+///
+#define RETURN_NOT_READY             ENCODE_ERROR (6)
+
+///
+/// The physical device reported an error while attempting the
+/// operation.
+///
+#define RETURN_DEVICE_ERROR          ENCODE_ERROR (7)
+
+///
+/// The device can not be written to.
+///
+#define RETURN_WRITE_PROTECTED       ENCODE_ERROR (8)
+
+///
+/// The resource has run out.
+///
+#define RETURN_OUT_OF_RESOURCES      ENCODE_ERROR (9)
+
+///
+/// An inconsistency was detected on the file system causing the
+/// operation to fail.
+///
+#define RETURN_VOLUME_CORRUPTED      ENCODE_ERROR (10)
+
+///
+/// There is no more space on the file system.
+///
+#define RETURN_VOLUME_FULL           ENCODE_ERROR (11)
+
+///
+/// The device does not contain any medium to perform the
+/// operation.
+///
+#define RETURN_NO_MEDIA              ENCODE_ERROR (12)
+
+///
+/// The medium in the device has changed since the last
+/// access.
+///
+#define RETURN_MEDIA_CHANGED         ENCODE_ERROR (13)
+
+///
+/// The item was not found.
+///
+#define RETURN_NOT_FOUND             ENCODE_ERROR (14)
+
+///
+/// Access was denied.
+///
+#define RETURN_ACCESS_DENIED         ENCODE_ERROR (15)
+
+///
+/// The server was not found or did not respond to the request.
+///
+#define RETURN_NO_RESPONSE           ENCODE_ERROR (16)
+
+///
+/// A mapping to the device does not exist.
+///
+#define RETURN_NO_MAPPING            ENCODE_ERROR (17)
+
+///
+/// A timeout time expired.
+///
+#define RETURN_TIMEOUT               ENCODE_ERROR (18)
+
+///
+/// The protocol has not been started.
+///
+#define RETURN_NOT_STARTED           ENCODE_ERROR (19)
+
+///
+/// The protocol has already been started.
+///
+#define RETURN_ALREADY_STARTED       ENCODE_ERROR (20)
+
+///
+/// The operation was aborted.
+///
+#define RETURN_ABORTED               ENCODE_ERROR (21)
+
+///
+/// An ICMP error occurred during the network operation.
+///
+#define RETURN_ICMP_ERROR            ENCODE_ERROR (22)
+
+///
+/// A TFTP error occurred during the network operation.
+///
+#define RETURN_TFTP_ERROR            ENCODE_ERROR (23)
+
+///
+/// A protocol error occurred during the network operation.
+///
+#define RETURN_PROTOCOL_ERROR        ENCODE_ERROR (24)
+
+///
+/// A function encountered an internal version that was
+/// incompatible with a version requested by the caller.
+///
+#define RETURN_INCOMPATIBLE_VERSION  ENCODE_ERROR (25)
+
+///
+/// The function was not performed due to a security violation.
+///
+#define RETURN_SECURITY_VIOLATION    ENCODE_ERROR (26)
+
+///
+/// A CRC error was detected.
+///
+#define RETURN_CRC_ERROR             ENCODE_ERROR (27)
+
+///
+/// The beginning or end of media was reached.
+///
+#define RETURN_END_OF_MEDIA          ENCODE_ERROR (28)
+
+///
+/// The end of the file was reached.
+///
+#define RETURN_END_OF_FILE           ENCODE_ERROR (31)
+
+///
+/// The language specified was invalid.
+///
+#define RETURN_INVALID_LANGUAGE      ENCODE_ERROR (32)
+
+///
+/// The security status of the data is unknown or compromised
+/// and the data must be updated or replaced to restore a valid
+/// security status.
+///
+#define RETURN_COMPROMISED_DATA      ENCODE_ERROR (33)
+
+///
+/// The string contained one or more characters that
+/// the device could not render and were skipped.
+///
+#define RETURN_WARN_UNKNOWN_GLYPH    ENCODE_WARNING (1)
+
+///
+/// The handle was closed, but the file was not deleted.
+///
+#define RETURN_WARN_DELETE_FAILURE   ENCODE_WARNING (2)
+
+///
+/// The handle was closed, but the data to the file was not
+/// flushed properly.
+///
+#define RETURN_WARN_WRITE_FAILURE    ENCODE_WARNING (3)
+
+///
+/// The resulting buffer was too small, and the data was
+/// truncated to the buffer size.
+///
+#define RETURN_WARN_BUFFER_TOO_SMALL ENCODE_WARNING (4)
+
+///
+/// The data has not been updated within the timeframe set by
+/// local policy for this type of data.
+///
+#define RETURN_WARN_STALE_DATA       ENCODE_WARNING (5)
+
+/**
+  Returns a 16-bit signature built from 2 ASCII characters.
+
+  This macro returns a 16-bit value built from the two ASCII characters specified
+  by A and B.
+
+  @param  A    The first ASCII character.
+  @param  B    The second ASCII character.
+
+  @return A 16-bit value built from the two ASCII characters specified by A and B.
+
+**/
+#define SIGNATURE_16(A, B)        ((A) | (B << 8))
+
+/**
+  Returns a 32-bit signature built from 4 ASCII characters.
+
+  This macro returns a 32-bit value built from the four ASCII characters specified
+  by A, B, C, and D.
+
+  @param  A    The first ASCII character.
+  @param  B    The second ASCII character.
+  @param  C    The third ASCII character.
+  @param  D    The fourth ASCII character.
+
+  @return A 32-bit value built from the two ASCII characters specified by A, B,
+          C and D.
+
+**/
+#define SIGNATURE_32(A, B, C, D)  (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16))
+
+/**
+  Returns a 64-bit signature built from 8 ASCII characters.
+
+  This macro returns a 64-bit value built from the eight ASCII characters specified
+  by A, B, C, D, E, F, G,and H.
+
+  @param  A    The first ASCII character.
+  @param  B    The second ASCII character.
+  @param  C    The third ASCII character.
+  @param  D    The fourth ASCII character.
+  @param  E    The fifth ASCII character.
+  @param  F    The sixth ASCII character.
+  @param  G    The seventh ASCII character.
+  @param  H    The eighth ASCII character.
+
+  @return A 64-bit value built from the two ASCII characters specified by A, B,
+          C, D, E, F, G and H.
+
+**/
+#define SIGNATURE_64(A, B, C, D, E, F, G, H) \
+    (SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32))
+
+#endif
+
diff --git a/wimboot/wimboot-2.7.3/src/efi/Guid/FileInfo.h b/wimboot/wimboot-2.7.3/src/efi/Guid/FileInfo.h
new file mode 100644 (file)
index 0000000..1457275
--- /dev/null
@@ -0,0 +1,71 @@
+/** @file
+  Provides a GUID and a data structure that can be used with EFI_FILE_PROTOCOL.SetInfo()
+  and EFI_FILE_PROTOCOL.GetInfo() to set or get generic file information.
+  This GUID is defined in UEFI specification.
+
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __FILE_INFO_H__
+#define __FILE_INFO_H__
+
+#define EFI_FILE_INFO_ID \
+  { \
+    0x9576e92, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+typedef struct {
+  ///
+  /// The size of the EFI_FILE_INFO structure, including the Null-terminated FileName string.
+  ///
+  UINT64    Size;
+  ///
+  /// The size of the file in bytes.
+  ///
+  UINT64    FileSize;
+  ///
+  /// PhysicalSize The amount of physical space the file consumes on the file system volume.
+  ///
+  UINT64    PhysicalSize;
+  ///
+  /// The time the file was created.
+  ///
+  EFI_TIME  CreateTime;
+  ///
+  /// The time when the file was last accessed.
+  ///
+  EFI_TIME  LastAccessTime;
+  ///
+  /// The time when the file's contents were last modified.
+  ///
+  EFI_TIME  ModificationTime;
+  ///
+  /// The attribute bits for the file.
+  ///
+  UINT64    Attribute;
+  ///
+  /// The Null-terminated name of the file.
+  ///
+  CHAR16    FileName[1];
+} EFI_FILE_INFO;
+
+///
+/// The FileName field of the EFI_FILE_INFO data structure is variable length.
+/// Whenever code needs to know the size of the EFI_FILE_INFO data structure, it needs to
+/// be the size of the data structure without the FileName field.  The following macro
+/// computes this size correctly no matter how big the FileName array is declared.
+/// This is required to make the EFI_FILE_INFO data structure ANSI compilant.
+///
+#define SIZE_OF_EFI_FILE_INFO OFFSET_OF (EFI_FILE_INFO, FileName)
+
+extern EFI_GUID gEfiFileInfoGuid;
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/Guid/HiiFormMapMethodGuid.h b/wimboot/wimboot-2.7.3/src/efi/Guid/HiiFormMapMethodGuid.h
new file mode 100644 (file)
index 0000000..ab508fd
--- /dev/null
@@ -0,0 +1,25 @@
+/** @file
+  Guid used to identify HII FormMap configuration method.
+
+  Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+  @par Revision Reference:
+  GUID defined in UEFI 2.2 spec.
+**/
+
+#ifndef __EFI_HII_FORMMAP_GUID_H__
+#define __EFI_HII_FORMMAP_GUID_H__
+
+#define EFI_HII_STANDARD_FORM_GUID \
+  { 0x3bd2f4ec, 0xe524, 0x46e4, { 0xa9, 0xd8, 0x51, 0x1, 0x17, 0x42, 0x55, 0x62 } }
+
+extern EFI_GUID gEfiHiiStandardFormGuid;
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/Guid/PcAnsi.h b/wimboot/wimboot-2.7.3/src/efi/Guid/PcAnsi.h
new file mode 100644 (file)
index 0000000..8f31254
--- /dev/null
@@ -0,0 +1,58 @@
+/** @file
+  Terminal Device Path Vendor Guid.
+
+  Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+  @par Revision Reference:
+  GUIDs defined in UEFI 2.0 spec.
+
+**/
+
+#ifndef __PC_ANSI_H__
+#define __PC_ANSI_H__
+
+#define EFI_PC_ANSI_GUID \
+  { \
+    0xe0c14753, 0xf9be, 0x11d2, {0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+  }
+
+#define EFI_VT_100_GUID \
+  { \
+    0xdfa66065, 0xb419, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+  }
+
+#define EFI_VT_100_PLUS_GUID \
+  { \
+    0x7baec70b, 0x57e0, 0x4c76, {0x8e, 0x87, 0x2f, 0x9e, 0x28, 0x08, 0x83, 0x43 } \
+  }
+
+#define EFI_VT_UTF8_GUID \
+  { \
+    0xad15a0d6, 0x8bec, 0x4acf, {0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88 } \
+  }
+
+#define DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL \
+  { \
+    0x37499a9d, 0x542f, 0x4c89, {0xa0, 0x26, 0x35, 0xda, 0x14, 0x20, 0x94, 0xe4 } \
+  }
+
+#define EFI_SAS_DEVICE_PATH_GUID \
+  { \
+    0xd487ddb4, 0x008b, 0x11d9, {0xaf, 0xdc, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d } \
+  }
+
+extern EFI_GUID gEfiPcAnsiGuid;
+extern EFI_GUID gEfiVT100Guid;
+extern EFI_GUID gEfiVT100PlusGuid;
+extern EFI_GUID gEfiVTUTF8Guid;
+extern EFI_GUID gEfiUartDevicePathGuid;
+extern EFI_GUID gEfiSasDevicePathGuid;
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/Guid/WinCertificate.h b/wimboot/wimboot-2.7.3/src/efi/Guid/WinCertificate.h
new file mode 100644 (file)
index 0000000..6dea446
--- /dev/null
@@ -0,0 +1,128 @@
+/** @file
+  GUID for UEFI WIN_CERTIFICATE structure.
+
+  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+  @par Revision Reference:
+  GUID defined in UEFI 2.0 spec.
+**/
+
+#ifndef __EFI_WIN_CERTIFICATE_H__
+#define __EFI_WIN_CERTIFICATE_H__
+
+//
+// _WIN_CERTIFICATE.wCertificateType
+//
+#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
+#define WIN_CERT_TYPE_EFI_PKCS115      0x0EF0
+#define WIN_CERT_TYPE_EFI_GUID         0x0EF1
+
+///
+/// The WIN_CERTIFICATE structure is part of the PE/COFF specification.
+///
+typedef struct {
+  ///
+  /// The length of the entire certificate,
+  /// including the length of the header, in bytes.
+  ///
+  UINT32  dwLength;
+  ///
+  /// The revision level of the WIN_CERTIFICATE
+  /// structure. The current revision level is 0x0200.
+  ///
+  UINT16  wRevision;
+  ///
+  /// The certificate type. See WIN_CERT_TYPE_xxx for the UEFI
+  /// certificate types. The UEFI specification reserves the range of
+  /// certificate type values from 0x0EF0 to 0x0EFF.
+  ///
+  UINT16  wCertificateType;
+  ///
+  /// The following is the actual certificate. The format of
+  /// the certificate depends on wCertificateType.
+  ///
+  /// UINT8 bCertificate[ANYSIZE_ARRAY];
+  ///
+} WIN_CERTIFICATE;
+
+///
+/// WIN_CERTIFICATE_UEFI_GUID.CertType
+///
+#define EFI_CERT_TYPE_RSA2048_SHA256_GUID \
+  {0xa7717414, 0xc616, 0x4977, {0x94, 0x20, 0x84, 0x47, 0x12, 0xa7, 0x35, 0xbf } }
+
+///
+/// WIN_CERTIFICATE_UEFI_GUID.CertData
+///
+typedef struct {
+  EFI_GUID  HashType;
+  UINT8     PublicKey[256];
+  UINT8     Signature[256];
+} EFI_CERT_BLOCK_RSA_2048_SHA256;
+
+
+///
+/// Certificate which encapsulates a GUID-specific digital signature
+///
+typedef struct {
+  ///
+  /// This is the standard WIN_CERTIFICATE header, where
+  /// wCertificateType is set to WIN_CERT_TYPE_EFI_GUID.
+  ///
+  WIN_CERTIFICATE   Hdr;
+  ///
+  /// This is the unique id which determines the
+  /// format of the CertData. .
+  ///
+  EFI_GUID          CertType;
+  ///
+  /// The following is the certificate data. The format of
+  /// the data is determined by the CertType.
+  /// If CertType is EFI_CERT_TYPE_RSA2048_SHA256_GUID,
+  /// the CertData will be EFI_CERT_BLOCK_RSA_2048_SHA256 structure.
+  ///
+  UINT8            CertData[1];
+} WIN_CERTIFICATE_UEFI_GUID;
+
+
+///
+/// Certificate which encapsulates the RSASSA_PKCS1-v1_5 digital signature.
+///
+/// The WIN_CERTIFICATE_UEFI_PKCS1_15 structure is derived from
+/// WIN_CERTIFICATE and encapsulate the information needed to
+/// implement the RSASSA-PKCS1-v1_5 digital signature algorithm as
+/// specified in RFC2437.
+///
+typedef struct {
+  ///
+  /// This is the standard WIN_CERTIFICATE header, where
+  /// wCertificateType is set to WIN_CERT_TYPE_UEFI_PKCS1_15.
+  ///
+  WIN_CERTIFICATE Hdr;
+  ///
+  /// This is the hashing algorithm which was performed on the
+  /// UEFI executable when creating the digital signature.
+  ///
+  EFI_GUID        HashAlgorithm;
+  ///
+  /// The following is the actual digital signature. The
+  /// size of the signature is the same size as the key
+  /// (1024-bit key is 128 bytes) and can be determined by
+  /// subtracting the length of the other parts of this header
+  /// from the total length of the certificate as found in
+  /// Hdr.dwLength.
+  ///
+  /// UINT8 Signature[];
+  ///
+} WIN_CERTIFICATE_EFI_PKCS1_15;
+
+extern EFI_GUID gEfiCertTypeRsa2048Sha256Guid;
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/Ia32/ProcessorBind.h b/wimboot/wimboot-2.7.3/src/efi/Ia32/ProcessorBind.h
new file mode 100644 (file)
index 0000000..bdcd7d4
--- /dev/null
@@ -0,0 +1,288 @@
+/** @file
+  Processor or Compiler specific defines and types for IA-32 architecture.
+
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __PROCESSOR_BIND_H__
+#define __PROCESSOR_BIND_H__
+
+///
+/// Define the processor type so other code can make processor based choices.
+///
+#define MDE_CPU_IA32
+
+//
+// Make sure we are using the correct packing rules per EFI specification
+//
+#if !defined(__GNUC__)
+#pragma pack()
+#endif
+
+#if defined(__INTEL_COMPILER)
+//
+// Disable ICC's remark #869: "Parameter" was never referenced warning.
+// This is legal ANSI C code so we disable the remark that is turned on with -Wall
+//
+#pragma warning ( disable : 869 )
+
+//
+// Disable ICC's remark #1418: external function definition with no prior declaration.
+// This is legal ANSI C code so we disable the remark that is turned on with /W4
+//
+#pragma warning ( disable : 1418 )
+
+//
+// Disable ICC's remark #1419: external declaration in primary source file
+// This is legal ANSI C code so we disable the remark that is turned on with /W4
+//
+#pragma warning ( disable : 1419 )
+
+//
+// Disable ICC's remark #593: "Variable" was set but never used.
+// This is legal ANSI C code so we disable the remark that is turned on with /W4
+//
+#pragma warning ( disable : 593 )
+
+#endif
+
+
+#if defined(_MSC_EXTENSIONS)
+
+//
+// Disable warning that make it impossible to compile at /W4
+// This only works for Microsoft* tools
+//
+
+//
+// Disabling bitfield type checking warnings.
+//
+#pragma warning ( disable : 4214 )
+
+//
+// Disabling the unreferenced formal parameter warnings.
+//
+#pragma warning ( disable : 4100 )
+
+//
+// Disable slightly different base types warning as CHAR8 * can not be set
+// to a constant string.
+//
+#pragma warning ( disable : 4057 )
+
+//
+// ASSERT(FALSE) or while (TRUE) are legal constructes so supress this warning
+//
+#pragma warning ( disable : 4127 )
+
+//
+// This warning is caused by functions defined but not used. For precompiled header only.
+//
+#pragma warning ( disable : 4505 )
+
+//
+// This warning is caused by empty (after preprocessing) source file. For precompiled header only.
+//
+#pragma warning ( disable : 4206 )
+
+#endif
+
+
+#if defined(_MSC_EXTENSIONS)
+
+  //
+  // use Microsoft C complier dependent integer width types
+  //
+
+  ///
+  /// 8-byte unsigned value.
+  ///
+  typedef unsigned __int64    UINT64;
+  ///
+  /// 8-byte signed value.
+  ///
+  typedef __int64             INT64;
+  ///
+  /// 4-byte unsigned value.
+  ///
+  typedef unsigned __int32    UINT32;
+  ///
+  /// 4-byte signed value.
+  ///
+  typedef __int32             INT32;
+  ///
+  /// 2-byte unsigned value.
+  ///
+  typedef unsigned short      UINT16;
+  ///
+  /// 2-byte Character.  Unless otherwise specified all strings are stored in the
+  /// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards.
+  ///
+  typedef unsigned short      CHAR16;
+  ///
+  /// 2-byte signed value.
+  ///
+  typedef short               INT16;
+  ///
+  /// Logical Boolean.  1-byte value containing 0 for FALSE or a 1 for TRUE.  Other
+  /// values are undefined.
+  ///
+  typedef unsigned char       BOOLEAN;
+  ///
+  /// 1-byte unsigned value.
+  ///
+  typedef unsigned char       UINT8;
+  ///
+  /// 1-byte Character.
+  ///
+  typedef char                CHAR8;
+  ///
+  /// 1-byte signed value.
+  ///
+  typedef signed char         INT8;
+#else
+  ///
+  /// 8-byte unsigned value.
+  ///
+  typedef unsigned long long  UINT64;
+  ///
+  /// 8-byte signed value.
+  ///
+  typedef long long           INT64;
+  ///
+  /// 4-byte unsigned value.
+  ///
+  typedef unsigned int        UINT32;
+  ///
+  /// 4-byte signed value.
+  ///
+  typedef int                 INT32;
+  ///
+  /// 2-byte unsigned value.
+  ///
+  typedef unsigned short      UINT16;
+  ///
+  /// 2-byte Character.  Unless otherwise specified all strings are stored in the
+  /// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards.
+  ///
+  typedef unsigned short      CHAR16;
+  ///
+  /// 2-byte signed value.
+  ///
+  typedef short               INT16;
+  ///
+  /// Logical Boolean.  1-byte value containing 0 for FALSE or a 1 for TRUE.  Other
+  /// values are undefined.
+  ///
+  typedef unsigned char       BOOLEAN;
+  ///
+  /// 1-byte unsigned value.
+  ///
+  typedef unsigned char       UINT8;
+  ///
+  /// 1-byte Character
+  ///
+  typedef char                CHAR8;
+  ///
+  /// 1-byte signed value
+  ///
+  typedef signed char         INT8;
+#endif
+
+///
+/// Unsigned value of native width.  (4 bytes on supported 32-bit processor instructions;
+/// 8 bytes on supported 64-bit processor instructions.)
+///
+typedef UINT32  UINTN;
+///
+/// Signed value of native width.  (4 bytes on supported 32-bit processor instructions;
+/// 8 bytes on supported 64-bit processor instructions.)
+///
+typedef INT32   INTN;
+
+//
+// Processor specific defines
+//
+
+///
+/// A value of native width with the highest bit set.
+///
+#define MAX_BIT     0x80000000
+///
+/// A value of native width with the two highest bits set.
+///
+#define MAX_2_BITS  0xC0000000
+
+///
+/// Maximum legal IA-32 address.
+///
+#define MAX_ADDRESS   0xFFFFFFFF
+
+///
+/// Maximum legal IA-32 INTN and UINTN values.
+///
+#define MAX_INTN   ((INTN)0x7FFFFFFF)
+#define MAX_UINTN  ((UINTN)0xFFFFFFFF)
+
+///
+/// The stack alignment required for IA-32.
+///
+#define CPU_STACK_ALIGNMENT   sizeof(UINTN)
+
+//
+// Modifier to ensure that all protocol member functions and EFI intrinsics
+// use the correct C calling convention. All protocol member functions and
+// EFI intrinsics are required to modify their member functions with EFIAPI.
+//
+#ifdef EFIAPI
+  ///
+  /// If EFIAPI is already defined, then we use that definition.
+  ///
+#elif defined(_MSC_EXTENSIONS)
+  ///
+  /// Microsoft* compiler specific method for EFIAPI calling convention.
+  ///
+  #define EFIAPI __cdecl
+#elif defined(__GNUC__)
+  ///
+  /// GCC specific method for EFIAPI calling convention.
+  ///
+  #define EFIAPI __attribute__((cdecl))
+#else
+  ///
+  /// The default for a non Microsoft* or GCC compiler is to assume the EFI ABI
+  /// is the standard.
+  ///
+  #define EFIAPI
+#endif
+
+#if defined(__GNUC__)
+  ///
+  /// For GNU assembly code, .global or .globl can declare global symbols.
+  /// Define this macro to unify the usage.
+  ///
+  #define ASM_GLOBAL .globl
+#endif
+
+/**
+  Return the pointer to the first instruction of a function given a function pointer.
+  On IA-32 CPU architectures, these two pointer values are the same,
+  so the implementation of this macro is very simple.
+
+  @param  FunctionPointer   A pointer to a function.
+
+  @return The pointer to the first instruction of a function given a function pointer.
+
+**/
+#define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer)
+
+#endif
+
diff --git a/wimboot/wimboot-2.7.3/src/efi/IndustryStandard/PeImage.h b/wimboot/wimboot-2.7.3/src/efi/IndustryStandard/PeImage.h
new file mode 100644 (file)
index 0000000..254e5d2
--- /dev/null
@@ -0,0 +1,756 @@
+/** @file
+  EFI image format for PE32, PE32+ and TE. Please note some data structures are
+  different for PE32 and PE32+. EFI_IMAGE_NT_HEADERS32 is for PE32 and
+  EFI_IMAGE_NT_HEADERS64 is for PE32+.
+
+  This file is coded to the Visual Studio, Microsoft Portable Executable and
+  Common Object File Format Specification, Revision 8.3 - February 6, 2013.
+  This file also includes some definitions in PI Specification, Revision 1.0.
+
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __PE_IMAGE_H__
+#define __PE_IMAGE_H__
+
+//
+// PE32+ Subsystem type for EFI images
+//
+#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION         10
+#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
+#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER      12
+#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER      13 ///< defined PI Specification, 1.0
+
+
+//
+// PE32+ Machine type for EFI images
+//
+#define IMAGE_FILE_MACHINE_I386            0x014c
+#define IMAGE_FILE_MACHINE_IA64            0x0200
+#define IMAGE_FILE_MACHINE_EBC             0x0EBC
+#define IMAGE_FILE_MACHINE_X64             0x8664
+#define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED  0x01c2
+#define IMAGE_FILE_MACHINE_ARM64           0xAA64
+
+//
+// EXE file formats
+//
+#define EFI_IMAGE_DOS_SIGNATURE     SIGNATURE_16('M', 'Z')
+#define EFI_IMAGE_OS2_SIGNATURE     SIGNATURE_16('N', 'E')
+#define EFI_IMAGE_OS2_SIGNATURE_LE  SIGNATURE_16('L', 'E')
+#define EFI_IMAGE_NT_SIGNATURE      SIGNATURE_32('P', 'E', '\0', '\0')
+
+///
+/// PE images can start with an optional DOS header, so if an image is run
+/// under DOS it can print an error message.
+///
+typedef struct {
+  UINT16  e_magic;    ///< Magic number.
+  UINT16  e_cblp;     ///< Bytes on last page of file.
+  UINT16  e_cp;       ///< Pages in file.
+  UINT16  e_crlc;     ///< Relocations.
+  UINT16  e_cparhdr;  ///< Size of header in paragraphs.
+  UINT16  e_minalloc; ///< Minimum extra paragraphs needed.
+  UINT16  e_maxalloc; ///< Maximum extra paragraphs needed.
+  UINT16  e_ss;       ///< Initial (relative) SS value.
+  UINT16  e_sp;       ///< Initial SP value.
+  UINT16  e_csum;     ///< Checksum.
+  UINT16  e_ip;       ///< Initial IP value.
+  UINT16  e_cs;       ///< Initial (relative) CS value.
+  UINT16  e_lfarlc;   ///< File address of relocation table.
+  UINT16  e_ovno;     ///< Overlay number.
+  UINT16  e_res[4];   ///< Reserved words.
+  UINT16  e_oemid;    ///< OEM identifier (for e_oeminfo).
+  UINT16  e_oeminfo;  ///< OEM information; e_oemid specific.
+  UINT16  e_res2[10]; ///< Reserved words.
+  UINT32  e_lfanew;   ///< File address of new exe header.
+} EFI_IMAGE_DOS_HEADER;
+
+///
+/// COFF File Header (Object and Image).
+///
+typedef struct {
+  UINT16  Machine;
+  UINT16  NumberOfSections;
+  UINT32  TimeDateStamp;
+  UINT32  PointerToSymbolTable;
+  UINT32  NumberOfSymbols;
+  UINT16  SizeOfOptionalHeader;
+  UINT16  Characteristics;
+} EFI_IMAGE_FILE_HEADER;
+
+///
+/// Size of EFI_IMAGE_FILE_HEADER.
+///
+#define EFI_IMAGE_SIZEOF_FILE_HEADER        20
+
+//
+// Characteristics
+//
+#define EFI_IMAGE_FILE_RELOCS_STRIPPED      BIT0     ///< 0x0001  Relocation info stripped from file.
+#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE     BIT1     ///< 0x0002  File is executable  (i.e. no unresolved externel references).
+#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED   BIT2     ///< 0x0004  Line nunbers stripped from file.
+#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED  BIT3     ///< 0x0008  Local symbols stripped from file.
+#define EFI_IMAGE_FILE_BYTES_REVERSED_LO    BIT7     ///< 0x0080  Bytes of machine word are reversed.
+#define EFI_IMAGE_FILE_32BIT_MACHINE        BIT8     ///< 0x0100  32 bit word machine.
+#define EFI_IMAGE_FILE_DEBUG_STRIPPED       BIT9     ///< 0x0200  Debugging info stripped from file in .DBG file.
+#define EFI_IMAGE_FILE_SYSTEM               BIT12    ///< 0x1000  System File.
+#define EFI_IMAGE_FILE_DLL                  BIT13    ///< 0x2000  File is a DLL.
+#define EFI_IMAGE_FILE_BYTES_REVERSED_HI    BIT15    ///< 0x8000  Bytes of machine word are reversed.
+
+///
+/// Header Data Directories.
+///
+typedef struct {
+  UINT32  VirtualAddress;
+  UINT32  Size;
+} EFI_IMAGE_DATA_DIRECTORY;
+
+//
+// Directory Entries
+//
+#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT      0
+#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT      1
+#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE    2
+#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION   3
+#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY    4
+#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC   5
+#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG       6
+#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT   7
+#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR   8
+#define EFI_IMAGE_DIRECTORY_ENTRY_TLS         9
+#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
+
+#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16
+
+///
+/// @attention
+/// EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC means PE32 and
+/// EFI_IMAGE_OPTIONAL_HEADER32 must be used. The data structures only vary
+/// after NT additional fields.
+///
+#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
+
+///
+/// Optional Header Standard Fields for PE32.
+///
+typedef struct {
+  ///
+  /// Standard fields.
+  ///
+  UINT16                    Magic;
+  UINT8                     MajorLinkerVersion;
+  UINT8                     MinorLinkerVersion;
+  UINT32                    SizeOfCode;
+  UINT32                    SizeOfInitializedData;
+  UINT32                    SizeOfUninitializedData;
+  UINT32                    AddressOfEntryPoint;
+  UINT32                    BaseOfCode;
+  UINT32                    BaseOfData;  ///< PE32 contains this additional field, which is absent in PE32+.
+  ///
+  /// Optional Header Windows-Specific Fields.
+  ///
+  UINT32                    ImageBase;
+  UINT32                    SectionAlignment;
+  UINT32                    FileAlignment;
+  UINT16                    MajorOperatingSystemVersion;
+  UINT16                    MinorOperatingSystemVersion;
+  UINT16                    MajorImageVersion;
+  UINT16                    MinorImageVersion;
+  UINT16                    MajorSubsystemVersion;
+  UINT16                    MinorSubsystemVersion;
+  UINT32                    Win32VersionValue;
+  UINT32                    SizeOfImage;
+  UINT32                    SizeOfHeaders;
+  UINT32                    CheckSum;
+  UINT16                    Subsystem;
+  UINT16                    DllCharacteristics;
+  UINT32                    SizeOfStackReserve;
+  UINT32                    SizeOfStackCommit;
+  UINT32                    SizeOfHeapReserve;
+  UINT32                    SizeOfHeapCommit;
+  UINT32                    LoaderFlags;
+  UINT32                    NumberOfRvaAndSizes;
+  EFI_IMAGE_DATA_DIRECTORY  DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
+} EFI_IMAGE_OPTIONAL_HEADER32;
+
+///
+/// @attention
+/// EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC means PE32+ and
+/// EFI_IMAGE_OPTIONAL_HEADER64 must be used. The data structures only vary
+/// after NT additional fields.
+///
+#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
+
+///
+/// Optional Header Standard Fields for PE32+.
+///
+typedef struct {
+  ///
+  /// Standard fields.
+  ///
+  UINT16                    Magic;
+  UINT8                     MajorLinkerVersion;
+  UINT8                     MinorLinkerVersion;
+  UINT32                    SizeOfCode;
+  UINT32                    SizeOfInitializedData;
+  UINT32                    SizeOfUninitializedData;
+  UINT32                    AddressOfEntryPoint;
+  UINT32                    BaseOfCode;
+  ///
+  /// Optional Header Windows-Specific Fields.
+  ///
+  UINT64                    ImageBase;
+  UINT32                    SectionAlignment;
+  UINT32                    FileAlignment;
+  UINT16                    MajorOperatingSystemVersion;
+  UINT16                    MinorOperatingSystemVersion;
+  UINT16                    MajorImageVersion;
+  UINT16                    MinorImageVersion;
+  UINT16                    MajorSubsystemVersion;
+  UINT16                    MinorSubsystemVersion;
+  UINT32                    Win32VersionValue;
+  UINT32                    SizeOfImage;
+  UINT32                    SizeOfHeaders;
+  UINT32                    CheckSum;
+  UINT16                    Subsystem;
+  UINT16                    DllCharacteristics;
+  UINT64                    SizeOfStackReserve;
+  UINT64                    SizeOfStackCommit;
+  UINT64                    SizeOfHeapReserve;
+  UINT64                    SizeOfHeapCommit;
+  UINT32                    LoaderFlags;
+  UINT32                    NumberOfRvaAndSizes;
+  EFI_IMAGE_DATA_DIRECTORY  DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
+} EFI_IMAGE_OPTIONAL_HEADER64;
+
+
+///
+/// @attention
+/// EFI_IMAGE_NT_HEADERS32 is for use ONLY by tools.
+///
+typedef struct {
+  UINT32                      Signature;
+  EFI_IMAGE_FILE_HEADER       FileHeader;
+  EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader;
+} EFI_IMAGE_NT_HEADERS32;
+
+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32)
+
+///
+/// @attention
+/// EFI_IMAGE_HEADERS64 is for use ONLY by tools.
+///
+typedef struct {
+  UINT32                      Signature;
+  EFI_IMAGE_FILE_HEADER       FileHeader;
+  EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader;
+} EFI_IMAGE_NT_HEADERS64;
+
+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64)
+
+//
+// Other Windows Subsystem Values
+//
+#define EFI_IMAGE_SUBSYSTEM_UNKNOWN     0
+#define EFI_IMAGE_SUBSYSTEM_NATIVE      1
+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2
+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3
+#define EFI_IMAGE_SUBSYSTEM_OS2_CUI     5
+#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI   7
+
+///
+/// Length of ShortName.
+///
+#define EFI_IMAGE_SIZEOF_SHORT_NAME 8
+
+///
+/// Section Table. This table immediately follows the optional header.
+///
+typedef struct {
+  UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME];
+  union {
+    UINT32  PhysicalAddress;
+    UINT32  VirtualSize;
+  } Misc;
+  UINT32  VirtualAddress;
+  UINT32  SizeOfRawData;
+  UINT32  PointerToRawData;
+  UINT32  PointerToRelocations;
+  UINT32  PointerToLinenumbers;
+  UINT16  NumberOfRelocations;
+  UINT16  NumberOfLinenumbers;
+  UINT32  Characteristics;
+} EFI_IMAGE_SECTION_HEADER;
+
+///
+/// Size of EFI_IMAGE_SECTION_HEADER.
+///
+#define EFI_IMAGE_SIZEOF_SECTION_HEADER       40
+
+//
+// Section Flags Values
+//
+#define EFI_IMAGE_SCN_TYPE_NO_PAD                  BIT3   ///< 0x00000008  ///< Reserved.
+#define EFI_IMAGE_SCN_CNT_CODE                     BIT5   ///< 0x00000020
+#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA         BIT6   ///< 0x00000040
+#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA       BIT7   ///< 0x00000080
+
+#define EFI_IMAGE_SCN_LNK_OTHER                    BIT8   ///< 0x00000100  ///< Reserved.
+#define EFI_IMAGE_SCN_LNK_INFO                     BIT9   ///< 0x00000200  ///< Section contains comments or some other type of information.
+#define EFI_IMAGE_SCN_LNK_REMOVE                   BIT11  ///< 0x00000800  ///< Section contents will not become part of image.
+#define EFI_IMAGE_SCN_LNK_COMDAT                   BIT12  ///< 0x00001000
+
+#define EFI_IMAGE_SCN_ALIGN_1BYTES                 BIT20  ///< 0x00100000
+#define EFI_IMAGE_SCN_ALIGN_2BYTES                 BIT21  ///< 0x00200000
+#define EFI_IMAGE_SCN_ALIGN_4BYTES          (BIT20|BIT21) ///< 0x00300000
+#define EFI_IMAGE_SCN_ALIGN_8BYTES                 BIT22  ///< 0x00400000
+#define EFI_IMAGE_SCN_ALIGN_16BYTES         (BIT20|BIT22) ///< 0x00500000
+#define EFI_IMAGE_SCN_ALIGN_32BYTES         (BIT21|BIT22) ///< 0x00600000
+#define EFI_IMAGE_SCN_ALIGN_64BYTES   (BIT20|BIT21|BIT22) ///< 0x00700000
+
+#define EFI_IMAGE_SCN_MEM_DISCARDABLE              BIT25  ///< 0x02000000
+#define EFI_IMAGE_SCN_MEM_NOT_CACHED               BIT26  ///< 0x04000000
+#define EFI_IMAGE_SCN_MEM_NOT_PAGED                BIT27  ///< 0x08000000
+#define EFI_IMAGE_SCN_MEM_SHARED                   BIT28  ///< 0x10000000
+#define EFI_IMAGE_SCN_MEM_EXECUTE                  BIT29  ///< 0x20000000
+#define EFI_IMAGE_SCN_MEM_READ                     BIT30  ///< 0x40000000
+#define EFI_IMAGE_SCN_MEM_WRITE                    BIT31  ///< 0x80000000
+
+///
+/// Size of a Symbol Table Record.
+///
+#define EFI_IMAGE_SIZEOF_SYMBOL 18
+
+//
+// Symbols have a section number of the section in which they are
+// defined. Otherwise, section numbers have the following meanings:
+//
+#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0  ///< Symbol is undefined or is common.
+#define EFI_IMAGE_SYM_ABSOLUTE  (UINT16) -1 ///< Symbol is an absolute value.
+#define EFI_IMAGE_SYM_DEBUG     (UINT16) -2 ///< Symbol is a special debug item.
+
+//
+// Symbol Type (fundamental) values.
+//
+#define EFI_IMAGE_SYM_TYPE_NULL   0   ///< no type.
+#define EFI_IMAGE_SYM_TYPE_VOID   1   ///< no valid type.
+#define EFI_IMAGE_SYM_TYPE_CHAR   2   ///< type character.
+#define EFI_IMAGE_SYM_TYPE_SHORT  3   ///< type short integer.
+#define EFI_IMAGE_SYM_TYPE_INT    4
+#define EFI_IMAGE_SYM_TYPE_LONG   5
+#define EFI_IMAGE_SYM_TYPE_FLOAT  6
+#define EFI_IMAGE_SYM_TYPE_DOUBLE 7
+#define EFI_IMAGE_SYM_TYPE_STRUCT 8
+#define EFI_IMAGE_SYM_TYPE_UNION  9
+#define EFI_IMAGE_SYM_TYPE_ENUM   10  ///< enumeration.
+#define EFI_IMAGE_SYM_TYPE_MOE    11  ///< member of enumeration.
+#define EFI_IMAGE_SYM_TYPE_BYTE   12
+#define EFI_IMAGE_SYM_TYPE_WORD   13
+#define EFI_IMAGE_SYM_TYPE_UINT   14
+#define EFI_IMAGE_SYM_TYPE_DWORD  15
+
+//
+// Symbol Type (derived) values.
+//
+#define EFI_IMAGE_SYM_DTYPE_NULL      0 ///< no derived type.
+#define EFI_IMAGE_SYM_DTYPE_POINTER   1
+#define EFI_IMAGE_SYM_DTYPE_FUNCTION  2
+#define EFI_IMAGE_SYM_DTYPE_ARRAY     3
+
+//
+// Storage classes.
+//
+#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION   ((UINT8) -1)
+#define EFI_IMAGE_SYM_CLASS_NULL              0
+#define EFI_IMAGE_SYM_CLASS_AUTOMATIC         1
+#define EFI_IMAGE_SYM_CLASS_EXTERNAL          2
+#define EFI_IMAGE_SYM_CLASS_STATIC            3
+#define EFI_IMAGE_SYM_CLASS_REGISTER          4
+#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF      5
+#define EFI_IMAGE_SYM_CLASS_LABEL             6
+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL   7
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT  8
+#define EFI_IMAGE_SYM_CLASS_ARGUMENT          9
+#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG        10
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION   11
+#define EFI_IMAGE_SYM_CLASS_UNION_TAG         12
+#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION   13
+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC  14
+#define EFI_IMAGE_SYM_CLASS_ENUM_TAG          15
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM    16
+#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM    17
+#define EFI_IMAGE_SYM_CLASS_BIT_FIELD         18
+#define EFI_IMAGE_SYM_CLASS_BLOCK             100
+#define EFI_IMAGE_SYM_CLASS_FUNCTION          101
+#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT     102
+#define EFI_IMAGE_SYM_CLASS_FILE              103
+#define EFI_IMAGE_SYM_CLASS_SECTION           104
+#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL     105
+
+//
+// type packing constants
+//
+#define EFI_IMAGE_N_BTMASK  017
+#define EFI_IMAGE_N_TMASK   060
+#define EFI_IMAGE_N_TMASK1  0300
+#define EFI_IMAGE_N_TMASK2  0360
+#define EFI_IMAGE_N_BTSHFT  4
+#define EFI_IMAGE_N_TSHIFT  2
+
+//
+// Communal selection types.
+//
+#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES    1
+#define EFI_IMAGE_COMDAT_SELECT_ANY             2
+#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE       3
+#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH     4
+#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE     5
+
+//
+// the following values only be referred in PeCoff, not defined in PECOFF.
+//
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY  1
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY    2
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS      3
+
+///
+/// Relocation format.
+///
+typedef struct {
+  UINT32  VirtualAddress;
+  UINT32  SymbolTableIndex;
+  UINT16  Type;
+} EFI_IMAGE_RELOCATION;
+
+///
+/// Size of EFI_IMAGE_RELOCATION
+///
+#define EFI_IMAGE_SIZEOF_RELOCATION 10
+
+//
+// I386 relocation types.
+//
+#define EFI_IMAGE_REL_I386_ABSOLUTE 0x0000  ///< Reference is absolute, no relocation is necessary.
+#define EFI_IMAGE_REL_I386_DIR16    0x0001  ///< Direct 16-bit reference to the symbols virtual address.
+#define EFI_IMAGE_REL_I386_REL16    0x0002  ///< PC-relative 16-bit reference to the symbols virtual address.
+#define EFI_IMAGE_REL_I386_DIR32    0x0006  ///< Direct 32-bit reference to the symbols virtual address.
+#define EFI_IMAGE_REL_I386_DIR32NB  0x0007  ///< Direct 32-bit reference to the symbols virtual address, base not included.
+#define EFI_IMAGE_REL_I386_SEG12    0x0009  ///< Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address.
+#define EFI_IMAGE_REL_I386_SECTION  0x000A
+#define EFI_IMAGE_REL_I386_SECREL   0x000B
+#define EFI_IMAGE_REL_I386_REL32    0x0014  ///< PC-relative 32-bit reference to the symbols virtual address.
+
+//
+// x64 processor relocation types.
+//
+#define IMAGE_REL_AMD64_ABSOLUTE  0x0000
+#define IMAGE_REL_AMD64_ADDR64    0x0001
+#define IMAGE_REL_AMD64_ADDR32    0x0002
+#define IMAGE_REL_AMD64_ADDR32NB  0x0003
+#define IMAGE_REL_AMD64_REL32     0x0004
+#define IMAGE_REL_AMD64_REL32_1   0x0005
+#define IMAGE_REL_AMD64_REL32_2   0x0006
+#define IMAGE_REL_AMD64_REL32_3   0x0007
+#define IMAGE_REL_AMD64_REL32_4   0x0008
+#define IMAGE_REL_AMD64_REL32_5   0x0009
+#define IMAGE_REL_AMD64_SECTION   0x000A
+#define IMAGE_REL_AMD64_SECREL    0x000B
+#define IMAGE_REL_AMD64_SECREL7   0x000C
+#define IMAGE_REL_AMD64_TOKEN     0x000D
+#define IMAGE_REL_AMD64_SREL32    0x000E
+#define IMAGE_REL_AMD64_PAIR      0x000F
+#define IMAGE_REL_AMD64_SSPAN32   0x0010
+
+///
+/// Based relocation format.
+///
+typedef struct {
+  UINT32  VirtualAddress;
+  UINT32  SizeOfBlock;
+} EFI_IMAGE_BASE_RELOCATION;
+
+///
+/// Size of EFI_IMAGE_BASE_RELOCATION.
+///
+#define EFI_IMAGE_SIZEOF_BASE_RELOCATION  8
+
+//
+// Based relocation types.
+//
+#define EFI_IMAGE_REL_BASED_ABSOLUTE        0
+#define EFI_IMAGE_REL_BASED_HIGH            1
+#define EFI_IMAGE_REL_BASED_LOW             2
+#define EFI_IMAGE_REL_BASED_HIGHLOW         3
+#define EFI_IMAGE_REL_BASED_HIGHADJ         4
+#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR    5
+#define EFI_IMAGE_REL_BASED_ARM_MOV32A      5
+#define EFI_IMAGE_REL_BASED_ARM_MOV32T      7
+#define EFI_IMAGE_REL_BASED_IA64_IMM64      9
+#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR16  9
+#define EFI_IMAGE_REL_BASED_DIR64           10
+
+///
+/// Line number format.
+///
+typedef struct {
+  union {
+    UINT32  SymbolTableIndex; ///< Symbol table index of function name if Linenumber is 0.
+    UINT32  VirtualAddress;   ///< Virtual address of line number.
+  } Type;
+  UINT16  Linenumber;         ///< Line number.
+} EFI_IMAGE_LINENUMBER;
+
+///
+/// Size of EFI_IMAGE_LINENUMBER.
+///
+#define EFI_IMAGE_SIZEOF_LINENUMBER 6
+
+//
+// Archive format.
+//
+#define EFI_IMAGE_ARCHIVE_START_SIZE        8
+#define EFI_IMAGE_ARCHIVE_START             "!<arch>\n"
+#define EFI_IMAGE_ARCHIVE_END               "`\n"
+#define EFI_IMAGE_ARCHIVE_PAD               "\n"
+#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER     "/               "
+#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER  "//              "
+
+///
+/// Archive Member Headers
+///
+typedef struct {
+  UINT8 Name[16];     ///< File member name - `/' terminated.
+  UINT8 Date[12];     ///< File member date - decimal.
+  UINT8 UserID[6];    ///< File member user id - decimal.
+  UINT8 GroupID[6];   ///< File member group id - decimal.
+  UINT8 Mode[8];      ///< File member mode - octal.
+  UINT8 Size[10];     ///< File member size - decimal.
+  UINT8 EndHeader[2]; ///< String to end header. (0x60 0x0A).
+} EFI_IMAGE_ARCHIVE_MEMBER_HEADER;
+
+///
+/// Size of EFI_IMAGE_ARCHIVE_MEMBER_HEADER.
+///
+#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
+
+
+//
+// DLL Support
+//
+
+///
+/// Export Directory Table.
+///
+typedef struct {
+  UINT32  Characteristics;
+  UINT32  TimeDateStamp;
+  UINT16  MajorVersion;
+  UINT16  MinorVersion;
+  UINT32  Name;
+  UINT32  Base;
+  UINT32  NumberOfFunctions;
+  UINT32  NumberOfNames;
+  UINT32  AddressOfFunctions;
+  UINT32  AddressOfNames;
+  UINT32  AddressOfNameOrdinals;
+} EFI_IMAGE_EXPORT_DIRECTORY;
+
+///
+/// Hint/Name Table.
+///
+typedef struct {
+  UINT16  Hint;
+  UINT8   Name[1];
+} EFI_IMAGE_IMPORT_BY_NAME;
+
+///
+/// Import Address Table RVA (Thunk Table).
+///
+typedef struct {
+  union {
+    UINT32                    Function;
+    UINT32                    Ordinal;
+    EFI_IMAGE_IMPORT_BY_NAME  *AddressOfData;
+  } u1;
+} EFI_IMAGE_THUNK_DATA;
+
+#define EFI_IMAGE_ORDINAL_FLAG              BIT31    ///< Flag for PE32.
+#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal)  ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0)
+#define EFI_IMAGE_ORDINAL(Ordinal)          (Ordinal & 0xffff)
+
+///
+/// Import Directory Table
+///
+typedef struct {
+  UINT32                Characteristics;
+  UINT32                TimeDateStamp;
+  UINT32                ForwarderChain;
+  UINT32                Name;
+  EFI_IMAGE_THUNK_DATA  *FirstThunk;
+} EFI_IMAGE_IMPORT_DESCRIPTOR;
+
+
+///
+/// Debug Directory Format.
+///
+typedef struct {
+  UINT32  Characteristics;
+  UINT32  TimeDateStamp;
+  UINT16  MajorVersion;
+  UINT16  MinorVersion;
+  UINT32  Type;
+  UINT32  SizeOfData;
+  UINT32  RVA;           ///< The address of the debug data when loaded, relative to the image base.
+  UINT32  FileOffset;    ///< The file pointer to the debug data.
+} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY;
+
+#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2     ///< The Visual C++ debug information.
+
+///
+/// Debug Data Structure defined in Microsoft C++.
+///
+#define CODEVIEW_SIGNATURE_NB10  SIGNATURE_32('N', 'B', '1', '0')
+typedef struct {
+  UINT32  Signature;                        ///< "NB10"
+  UINT32  Unknown;
+  UINT32  Unknown2;
+  UINT32  Unknown3;
+  //
+  // Filename of .PDB goes here
+  //
+} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY;
+
+///
+/// Debug Data Structure defined in Microsoft C++.
+///
+#define CODEVIEW_SIGNATURE_RSDS  SIGNATURE_32('R', 'S', 'D', 'S')
+typedef struct {
+  UINT32  Signature;                        ///< "RSDS".
+  UINT32  Unknown;
+  UINT32  Unknown2;
+  UINT32  Unknown3;
+  UINT32  Unknown4;
+  UINT32  Unknown5;
+  //
+  // Filename of .PDB goes here
+  //
+} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY;
+
+
+///
+/// Debug Data Structure defined by Apple Mach-O to Coff utility.
+///
+#define CODEVIEW_SIGNATURE_MTOC  SIGNATURE_32('M', 'T', 'O', 'C')
+typedef struct {
+  UINT32    Signature;                       ///< "MTOC".
+  GUID      MachOUuid;
+  //
+  //  Filename of .DLL (Mach-O with debug info) goes here
+  //
+} EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY;
+
+///
+/// Resource format.
+///
+typedef struct {
+  UINT32  Characteristics;
+  UINT32  TimeDateStamp;
+  UINT16  MajorVersion;
+  UINT16  MinorVersion;
+  UINT16  NumberOfNamedEntries;
+  UINT16  NumberOfIdEntries;
+  //
+  // Array of EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY entries goes here.
+  //
+} EFI_IMAGE_RESOURCE_DIRECTORY;
+
+///
+/// Resource directory entry format.
+///
+typedef struct {
+  union {
+    struct {
+      UINT32  NameOffset:31;
+      UINT32  NameIsString:1;
+    } s;
+    UINT32  Id;
+  } u1;
+  union {
+    UINT32  OffsetToData;
+    struct {
+      UINT32  OffsetToDirectory:31;
+      UINT32  DataIsDirectory:1;
+    } s;
+  } u2;
+} EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY;
+
+///
+/// Resource directory entry for string.
+///
+typedef struct {
+  UINT16  Length;
+  CHAR16  String[1];
+} EFI_IMAGE_RESOURCE_DIRECTORY_STRING;
+
+///
+/// Resource directory entry for data array.
+///
+typedef struct {
+  UINT32  OffsetToData;
+  UINT32  Size;
+  UINT32  CodePage;
+  UINT32  Reserved;
+} EFI_IMAGE_RESOURCE_DATA_ENTRY;
+
+///
+/// Header format for TE images, defined in the PI Specification, 1.0.
+///
+typedef struct {
+  UINT16                    Signature;            ///< The signature for TE format = "VZ".
+  UINT16                    Machine;              ///< From the original file header.
+  UINT8                     NumberOfSections;     ///< From the original file header.
+  UINT8                     Subsystem;            ///< From original optional header.
+  UINT16                    StrippedSize;         ///< Number of bytes we removed from the header.
+  UINT32                    AddressOfEntryPoint;  ///< Offset to entry point -- from original optional header.
+  UINT32                    BaseOfCode;           ///< From original image -- required for ITP debug.
+  UINT64                    ImageBase;            ///< From original file header.
+  EFI_IMAGE_DATA_DIRECTORY  DataDirectory[2];     ///< Only base relocation and debug directory.
+} EFI_TE_IMAGE_HEADER;
+
+
+#define EFI_TE_IMAGE_HEADER_SIGNATURE  SIGNATURE_16('V', 'Z')
+
+//
+// Data directory indexes in our TE image header
+//
+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC  0
+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG      1
+
+
+///
+/// Union of PE32, PE32+, and TE headers.
+///
+typedef union {
+  EFI_IMAGE_NT_HEADERS32   Pe32;
+  EFI_IMAGE_NT_HEADERS64   Pe32Plus;
+  EFI_TE_IMAGE_HEADER      Te;
+} EFI_IMAGE_OPTIONAL_HEADER_UNION;
+
+typedef union {
+  EFI_IMAGE_NT_HEADERS32            *Pe32;
+  EFI_IMAGE_NT_HEADERS64            *Pe32Plus;
+  EFI_TE_IMAGE_HEADER               *Te;
+  EFI_IMAGE_OPTIONAL_HEADER_UNION   *Union;
+} EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION;
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/ProcessorBind.h b/wimboot/wimboot-2.7.3/src/efi/ProcessorBind.h
new file mode 100644 (file)
index 0000000..0f31cc3
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _WIMBOOT_EFI_PROCESSOR_BIND_H
+#define _WIMBOOT_EFI_PROCESSOR_BIND_H
+
+/*
+ * EFI header files rely on having the CPU architecture directory
+ * present in the search path in order to pick up ProcessorBind.h.  We
+ * use this header file as a quick indirection layer.
+ *
+ */
+
+#if __i386__
+#include <efi/Ia32/ProcessorBind.h>
+#endif
+
+#if __x86_64__
+#include <efi/X64/ProcessorBind.h>
+#endif
+
+#endif /* _WIMBOOT_EFI_PROCESSOR_BIND_H */
diff --git a/wimboot/wimboot-2.7.3/src/efi/Protocol/BlockIo.h b/wimboot/wimboot-2.7.3/src/efi/Protocol/BlockIo.h
new file mode 100644 (file)
index 0000000..33c6991
--- /dev/null
@@ -0,0 +1,241 @@
+/** @file
+  Block IO protocol as defined in the UEFI 2.0 specification.
+
+  The Block IO protocol is used to abstract block devices like hard drives,
+  DVD-ROMs and floppy drives.
+
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __BLOCK_IO_H__
+#define __BLOCK_IO_H__
+
+#define EFI_BLOCK_IO_PROTOCOL_GUID \
+  { \
+    0x964e5b21, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+typedef struct _EFI_BLOCK_IO_PROTOCOL  EFI_BLOCK_IO_PROTOCOL;
+
+///
+/// Protocol GUID name defined in EFI1.1.
+///
+#define BLOCK_IO_PROTOCOL       EFI_BLOCK_IO_PROTOCOL_GUID
+
+///
+/// Protocol defined in EFI1.1.
+///
+typedef EFI_BLOCK_IO_PROTOCOL   EFI_BLOCK_IO;
+
+/**
+  Reset the Block Device.
+
+  @param  This                 Indicates a pointer to the calling context.
+  @param  ExtendedVerification Driver may perform diagnostics on reset.
+
+  @retval EFI_SUCCESS          The device was reset.
+  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could
+                               not be reset.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_BLOCK_RESET)(
+  IN EFI_BLOCK_IO_PROTOCOL          *This,
+  IN BOOLEAN                        ExtendedVerification
+  );
+
+/**
+  Read BufferSize bytes from Lba into Buffer.
+
+  @param  This       Indicates a pointer to the calling context.
+  @param  MediaId    Id of the media, changes every time the media is replaced.
+  @param  Lba        The starting Logical Block Address to read from
+  @param  BufferSize Size of Buffer, must be a multiple of device block size.
+  @param  Buffer     A pointer to the destination buffer for the data. The caller is
+                     responsible for either having implicit or explicit ownership of the buffer.
+
+  @retval EFI_SUCCESS           The data was read correctly from the device.
+  @retval EFI_DEVICE_ERROR      The device reported an error while performing the read.
+  @retval EFI_NO_MEDIA          There is no media in the device.
+  @retval EFI_MEDIA_CHANGED     The MediaId does not matched the current device.
+  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
+  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
+                                or the buffer is not on proper alignment.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_BLOCK_READ)(
+  IN EFI_BLOCK_IO_PROTOCOL          *This,
+  IN UINT32                         MediaId,
+  IN EFI_LBA                        Lba,
+  IN UINTN                          BufferSize,
+  OUT VOID                          *Buffer
+  );
+
+/**
+  Write BufferSize bytes from Lba into Buffer.
+
+  @param  This       Indicates a pointer to the calling context.
+  @param  MediaId    The media ID that the write request is for.
+  @param  Lba        The starting logical block address to be written. The caller is
+                     responsible for writing to only legitimate locations.
+  @param  BufferSize Size of Buffer, must be a multiple of device block size.
+  @param  Buffer     A pointer to the source buffer for the data.
+
+  @retval EFI_SUCCESS           The data was written correctly to the device.
+  @retval EFI_WRITE_PROTECTED   The device can not be written to.
+  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.
+  @retval EFI_NO_MEDIA          There is no media in the device.
+  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.
+  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
+  @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
+                                or the buffer is not on proper alignment.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_BLOCK_WRITE)(
+  IN EFI_BLOCK_IO_PROTOCOL          *This,
+  IN UINT32                         MediaId,
+  IN EFI_LBA                        Lba,
+  IN UINTN                          BufferSize,
+  IN VOID                           *Buffer
+  );
+
+/**
+  Flush the Block Device.
+
+  @param  This              Indicates a pointer to the calling context.
+
+  @retval EFI_SUCCESS       All outstanding data was written to the device
+  @retval EFI_DEVICE_ERROR  The device reported an error while writting back the data
+  @retval EFI_NO_MEDIA      There is no media in the device.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_BLOCK_FLUSH)(
+  IN EFI_BLOCK_IO_PROTOCOL  *This
+  );
+
+/**
+  Block IO read only mode data and updated only via members of BlockIO
+**/
+typedef struct {
+  ///
+  /// The curent media Id. If the media changes, this value is changed.
+  ///
+  UINT32  MediaId;
+
+  ///
+  /// TRUE if the media is removable; otherwise, FALSE.
+  ///
+  BOOLEAN RemovableMedia;
+
+  ///
+  /// TRUE if there is a media currently present in the device;
+  /// othersise, FALSE. THis field shows the media present status
+  /// as of the most recent ReadBlocks() or WriteBlocks() call.
+  ///
+  BOOLEAN MediaPresent;
+
+  ///
+  /// TRUE if LBA 0 is the first block of a partition; otherwise
+  /// FALSE. For media with only one partition this would be TRUE.
+  ///
+  BOOLEAN LogicalPartition;
+
+  ///
+  /// TRUE if the media is marked read-only otherwise, FALSE.
+  /// This field shows the read-only status as of the most recent WriteBlocks () call.
+  ///
+  BOOLEAN ReadOnly;
+
+  ///
+  /// TRUE if the WriteBlock () function caches write data.
+  ///
+  BOOLEAN WriteCaching;
+
+  ///
+  /// The intrinsic block size of the device. If the media changes, then
+  /// this field is updated.
+  ///
+  UINT32  BlockSize;
+
+  ///
+  /// Supplies the alignment requirement for any buffer to read or write block(s).
+  ///
+  UINT32  IoAlign;
+
+  ///
+  /// The last logical block address on the device.
+  /// If the media changes, then this field is updated.
+  ///
+  EFI_LBA LastBlock;
+
+  ///
+  /// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or equal to
+  /// EFI_BLOCK_IO_PROTOCOL_REVISION2. Returns the first LBA is aligned to
+  /// a physical block boundary.
+  ///
+  EFI_LBA LowestAlignedLba;
+
+  ///
+  /// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or equal to
+  /// EFI_BLOCK_IO_PROTOCOL_REVISION2. Returns the number of logical blocks
+  /// per physical block.
+  ///
+  UINT32 LogicalBlocksPerPhysicalBlock;
+
+  ///
+  /// Only present if EFI_BLOCK_IO_PROTOCOL.Revision is greater than or equal to
+  /// EFI_BLOCK_IO_PROTOCOL_REVISION3. Returns the optimal transfer length
+  /// granularity as a number of logical blocks.
+  ///
+  UINT32 OptimalTransferLengthGranularity;
+} EFI_BLOCK_IO_MEDIA;
+
+#define EFI_BLOCK_IO_PROTOCOL_REVISION  0x00010000
+#define EFI_BLOCK_IO_PROTOCOL_REVISION2 0x00020001
+#define EFI_BLOCK_IO_PROTOCOL_REVISION3 0x00020031
+
+///
+/// Revision defined in EFI1.1.
+///
+#define EFI_BLOCK_IO_INTERFACE_REVISION   EFI_BLOCK_IO_PROTOCOL_REVISION
+
+///
+///  This protocol provides control over block devices.
+///
+struct _EFI_BLOCK_IO_PROTOCOL {
+  ///
+  /// The revision to which the block IO interface adheres. All future
+  /// revisions must be backwards compatible. If a future version is not
+  /// back wards compatible, it is not the same GUID.
+  ///
+  UINT64              Revision;
+  ///
+  /// Pointer to the EFI_BLOCK_IO_MEDIA data for this device.
+  ///
+  EFI_BLOCK_IO_MEDIA  *Media;
+
+  EFI_BLOCK_RESET     Reset;
+  EFI_BLOCK_READ      ReadBlocks;
+  EFI_BLOCK_WRITE     WriteBlocks;
+  EFI_BLOCK_FLUSH     FlushBlocks;
+
+};
+
+extern EFI_GUID gEfiBlockIoProtocolGuid;
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/Protocol/DevicePath.h b/wimboot/wimboot-2.7.3/src/efi/Protocol/DevicePath.h
new file mode 100644 (file)
index 0000000..e466e87
--- /dev/null
@@ -0,0 +1,1169 @@
+/** @file
+  The device path protocol as defined in UEFI 2.0.
+
+  The device path represents a programmatic path to a device,
+  from a software point of view. The path must persist from boot to boot, so
+  it can not contain things like PCI bus numbers that change from boot to boot.
+
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EFI_DEVICE_PATH_PROTOCOL_H__
+#define __EFI_DEVICE_PATH_PROTOCOL_H__
+
+#include "efi/Guid/PcAnsi.h"
+
+///
+/// Device Path protocol.
+///
+#define EFI_DEVICE_PATH_PROTOCOL_GUID \
+  { \
+    0x9576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+///
+/// Device Path guid definition for backward-compatible with EFI1.1.
+///
+#define DEVICE_PATH_PROTOCOL  EFI_DEVICE_PATH_PROTOCOL_GUID
+
+#pragma pack(1)
+
+/**
+  This protocol can be used on any device handle to obtain generic path/location
+  information concerning the physical device or logical device. If the handle does
+  not logically map to a physical device, the handle may not necessarily support
+  the device path protocol. The device path describes the location of the device
+  the handle is for. The size of the Device Path can be determined from the structures
+  that make up the Device Path.
+**/
+typedef struct {
+  UINT8 Type;       ///< 0x01 Hardware Device Path.
+                    ///< 0x02 ACPI Device Path.
+                    ///< 0x03 Messaging Device Path.
+                    ///< 0x04 Media Device Path.
+                    ///< 0x05 BIOS Boot Specification Device Path.
+                    ///< 0x7F End of Hardware Device Path.
+
+  UINT8 SubType;    ///< Varies by Type
+                    ///< 0xFF End Entire Device Path, or
+                    ///< 0x01 End This Instance of a Device Path and start a new
+                    ///< Device Path.
+
+  UINT8 Length[2];  ///< Specific Device Path data. Type and Sub-Type define
+                    ///< type of data. Size of data is included in Length.
+
+} EFI_DEVICE_PATH_PROTOCOL;
+
+///
+/// Device Path protocol definition for backward-compatible with EFI1.1.
+///
+typedef EFI_DEVICE_PATH_PROTOCOL  EFI_DEVICE_PATH;
+
+///
+/// Hardware Device Paths.
+///
+#define HARDWARE_DEVICE_PATH      0x01
+
+///
+/// PCI Device Path SubType.
+///
+#define HW_PCI_DP                 0x01
+
+///
+/// PCI Device Path.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// PCI Function Number.
+  ///
+  UINT8                           Function;
+  ///
+  /// PCI Device Number.
+  ///
+  UINT8                           Device;
+} PCI_DEVICE_PATH;
+
+///
+/// PCCARD Device Path SubType.
+///
+#define HW_PCCARD_DP              0x02
+
+///
+/// PCCARD Device Path.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Function Number (0 = First Function).
+  ///
+  UINT8                           FunctionNumber;
+} PCCARD_DEVICE_PATH;
+
+///
+/// Memory Mapped Device Path SubType.
+///
+#define HW_MEMMAP_DP              0x03
+
+///
+/// Memory Mapped Device Path.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// EFI_MEMORY_TYPE
+  ///
+  UINT32                          MemoryType;
+  ///
+  /// Starting Memory Address.
+  ///
+  EFI_PHYSICAL_ADDRESS            StartingAddress;
+  ///
+  /// Ending Memory Address.
+  ///
+  EFI_PHYSICAL_ADDRESS            EndingAddress;
+} MEMMAP_DEVICE_PATH;
+
+///
+/// Hardware Vendor Device Path SubType.
+///
+#define HW_VENDOR_DP              0x04
+
+///
+/// The Vendor Device Path allows the creation of vendor-defined Device Paths. A vendor must
+/// allocate a Vendor GUID for a Device Path. The Vendor GUID can then be used to define the
+/// contents on the n bytes that follow in the Vendor Device Path node.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Vendor-assigned GUID that defines the data that follows.
+  ///
+  EFI_GUID                        Guid;
+  ///
+  /// Vendor-defined variable size data.
+  ///
+} VENDOR_DEVICE_PATH;
+
+///
+/// Controller Device Path SubType.
+///
+#define HW_CONTROLLER_DP          0x05
+
+///
+/// Controller Device Path.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Controller number.
+  ///
+  UINT32                          ControllerNumber;
+} CONTROLLER_DEVICE_PATH;
+
+///
+/// ACPI Device Paths.
+///
+#define ACPI_DEVICE_PATH          0x02
+
+///
+/// ACPI Device Path SubType.
+///
+#define ACPI_DP                   0x01
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Device's PnP hardware ID stored in a numeric 32-bit
+  /// compressed EISA-type ID. This value must match the
+  /// corresponding _HID in the ACPI name space.
+  ///
+  UINT32                          HID;
+  ///
+  /// Unique ID that is required by ACPI if two devices have the
+  /// same _HID. This value must also match the corresponding
+  /// _UID/_HID pair in the ACPI name space. Only the 32-bit
+  /// numeric value type of _UID is supported. Thus, strings must
+  /// not be used for the _UID in the ACPI name space.
+  ///
+  UINT32                          UID;
+} ACPI_HID_DEVICE_PATH;
+
+///
+/// Expanded ACPI Device Path SubType.
+///
+#define ACPI_EXTENDED_DP          0x02
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Device's PnP hardware ID stored in a numeric 32-bit
+  /// compressed EISA-type ID. This value must match the
+  /// corresponding _HID in the ACPI name space.
+  ///
+  UINT32                          HID;
+  ///
+  /// Unique ID that is required by ACPI if two devices have the
+  /// same _HID. This value must also match the corresponding
+  /// _UID/_HID pair in the ACPI name space.
+  ///
+  UINT32                          UID;
+  ///
+  /// Device's compatible PnP hardware ID stored in a numeric
+  /// 32-bit compressed EISA-type ID. This value must match at
+  /// least one of the compatible device IDs returned by the
+  /// corresponding _CID in the ACPI name space.
+  ///
+  UINT32                          CID;
+  ///
+  /// Optional variable length _HIDSTR.
+  /// Optional variable length _UIDSTR.
+  /// Optional variable length _CIDSTR.
+  ///
+} ACPI_EXTENDED_HID_DEVICE_PATH;
+
+//
+//  EISA ID Macro
+//  EISA ID Definition 32-bits
+//   bits[15:0] - three character compressed ASCII EISA ID.
+//   bits[31:16] - binary number
+//    Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z'
+//
+#define PNP_EISA_ID_CONST         0x41d0
+#define EISA_ID(_Name, _Num)      ((UINT32)((_Name) | (_Num) << 16))
+#define EISA_PNP_ID(_PNPId)       (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
+#define EFI_PNP_ID(_PNPId)        (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
+
+#define PNP_EISA_ID_MASK          0xffff
+#define EISA_ID_TO_NUM(_Id)       ((_Id) >> 16)
+
+///
+/// ACPI _ADR Device Path SubType.
+///
+#define ACPI_ADR_DP               0x03
+
+///
+/// The _ADR device path is used to contain video output device attributes to support the Graphics
+/// Output Protocol. The device path can contain multiple _ADR entries if multiple video output
+/// devices are displaying the same output.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// _ADR value. For video output devices the value of this
+  /// field comes from Table B-2 of the ACPI 3.0 specification. At
+  /// least one _ADR value is required.
+  ///
+  UINT32                          ADR;
+  //
+  // This device path may optionally contain more than one _ADR entry.
+  //
+} ACPI_ADR_DEVICE_PATH;
+
+#define ACPI_ADR_DISPLAY_TYPE_OTHER             0
+#define ACPI_ADR_DISPLAY_TYPE_VGA               1
+#define ACPI_ADR_DISPLAY_TYPE_TV                2
+#define ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL  3
+#define ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL  4
+
+#define ACPI_DISPLAY_ADR(_DeviceIdScheme, _HeadId, _NonVgaOutput, _BiosCanDetect, _VendorInfo, _Type, _Port, _Index) \
+          ((UINT32)( (((_DeviceIdScheme) & 0x1) << 31) |  \
+                      (((_HeadId)         & 0x7) << 18) |  \
+                      (((_NonVgaOutput)   & 0x1) << 17) |  \
+                      (((_BiosCanDetect)  & 0x1) << 16) |  \
+                      (((_VendorInfo)     & 0xf) << 12) |  \
+                      (((_Type)           & 0xf) << 8)  |  \
+                      (((_Port)           & 0xf) << 4)  |  \
+                       ((_Index)          & 0xf) ))
+
+///
+/// Messaging Device Paths.
+/// This Device Path is used to describe the connection of devices outside the resource domain of the
+/// system. This Device Path can describe physical messaging information like SCSI ID, or abstract
+/// information like networking protocol IP addresses.
+///
+#define MESSAGING_DEVICE_PATH     0x03
+
+///
+/// ATAPI Device Path SubType
+///
+#define MSG_ATAPI_DP              0x01
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Set to zero for primary, or one for secondary.
+  ///
+  UINT8                           PrimarySecondary;
+  ///
+  /// Set to zero for master, or one for slave mode.
+  ///
+  UINT8                           SlaveMaster;
+  ///
+  /// Logical Unit Number.
+  ///
+  UINT16                          Lun;
+} ATAPI_DEVICE_PATH;
+
+///
+/// SCSI Device Path SubType.
+///
+#define MSG_SCSI_DP               0x02
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Target ID on the SCSI bus (PUN).
+  ///
+  UINT16                          Pun;
+  ///
+  /// Logical Unit Number (LUN).
+  ///
+  UINT16                          Lun;
+} SCSI_DEVICE_PATH;
+
+///
+/// Fibre Channel SubType.
+///
+#define MSG_FIBRECHANNEL_DP       0x03
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Reserved for the future.
+  ///
+  UINT32                          Reserved;
+  ///
+  /// Fibre Channel World Wide Number.
+  ///
+  UINT64                          WWN;
+  ///
+  /// Fibre Channel Logical Unit Number.
+  ///
+  UINT64                          Lun;
+} FIBRECHANNEL_DEVICE_PATH;
+
+///
+/// Fibre Channel Ex SubType.
+///
+#define MSG_FIBRECHANNELEX_DP     0x15
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Reserved for the future.
+  ///
+  UINT32                          Reserved;
+  ///
+  /// 8 byte array containing Fibre Channel End Device Port Name.
+  ///
+  UINT8                           WWN[8];
+  ///
+  /// 8 byte array containing Fibre Channel Logical Unit Number.
+  ///
+  UINT8                           Lun[8];
+} FIBRECHANNELEX_DEVICE_PATH;
+
+///
+/// 1394 Device Path SubType
+///
+#define MSG_1394_DP               0x04
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Reserved for the future.
+  ///
+  UINT32                          Reserved;
+  ///
+  /// 1394 Global Unique ID (GUID).
+  ///
+  UINT64                          Guid;
+} F1394_DEVICE_PATH;
+
+///
+/// USB Device Path SubType.
+///
+#define MSG_USB_DP                0x05
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL      Header;
+  ///
+  /// USB Parent Port Number.
+  ///
+  UINT8                         ParentPortNumber;
+  ///
+  /// USB Interface Number.
+  ///
+  UINT8                         InterfaceNumber;
+} USB_DEVICE_PATH;
+
+///
+/// USB Class Device Path SubType.
+///
+#define MSG_USB_CLASS_DP          0x0f
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL      Header;
+  ///
+  /// Vendor ID assigned by USB-IF. A value of 0xFFFF will
+  /// match any Vendor ID.
+  ///
+  UINT16                        VendorId;
+  ///
+  /// Product ID assigned by USB-IF. A value of 0xFFFF will
+  /// match any Product ID.
+  ///
+  UINT16                        ProductId;
+  ///
+  /// The class code assigned by the USB-IF. A value of 0xFF
+  /// will match any class code.
+  ///
+  UINT8                         DeviceClass;
+  ///
+  /// The subclass code assigned by the USB-IF. A value of
+  /// 0xFF will match any subclass code.
+  ///
+  UINT8                         DeviceSubClass;
+  ///
+  /// The protocol code assigned by the USB-IF. A value of
+  /// 0xFF will match any protocol code.
+  ///
+  UINT8                         DeviceProtocol;
+} USB_CLASS_DEVICE_PATH;
+
+///
+/// USB WWID Device Path SubType.
+///
+#define MSG_USB_WWID_DP           0x10
+
+///
+/// This device path describes a USB device using its serial number.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL      Header;
+  ///
+  /// USB interface number.
+  ///
+  UINT16                        InterfaceNumber;
+  ///
+  /// USB vendor id of the device.
+  ///
+  UINT16                        VendorId;
+  ///
+  /// USB product id of the device.
+  ///
+  UINT16                        ProductId;
+  ///
+  /// Last 64-or-fewer UTF-16 characters of the USB
+  /// serial number. The length of the string is
+  /// determined by the Length field less the offset of the
+  /// Serial Number field (10)
+  ///
+  /// CHAR16                     SerialNumber[...];
+} USB_WWID_DEVICE_PATH;
+
+///
+/// Device Logical Unit SubType.
+///
+#define MSG_DEVICE_LOGICAL_UNIT_DP  0x11
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL      Header;
+  ///
+  /// Logical Unit Number for the interface.
+  ///
+  UINT8                         Lun;
+} DEVICE_LOGICAL_UNIT_DEVICE_PATH;
+
+///
+/// SATA Device Path SubType.
+///
+#define MSG_SATA_DP               0x12
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// The HBA port number that facilitates the connection to the
+  /// device or a port multiplier. The value 0xFFFF is reserved.
+  ///
+  UINT16                          HBAPortNumber;
+  ///
+  /// The Port multiplier port number that facilitates the connection
+  /// to the device. Bit 15 should be set if the device is directly
+  /// connected to the HBA.
+  ///
+  UINT16                          PortMultiplierPortNumber;
+  ///
+  /// Logical Unit Number.
+  ///
+  UINT16                          Lun;
+} SATA_DEVICE_PATH;
+
+///
+/// Flag for if the device is directly connected to the HBA.
+///
+#define SATA_HBA_DIRECT_CONNECT_FLAG 0x8000
+
+///
+/// I2O Device Path SubType.
+///
+#define MSG_I2O_DP                0x06
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Target ID (TID) for a device.
+  ///
+  UINT32                          Tid;
+} I2O_DEVICE_PATH;
+
+///
+/// MAC Address Device Path SubType.
+///
+#define MSG_MAC_ADDR_DP           0x0b
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// The MAC address for a network interface padded with 0s.
+  ///
+  EFI_MAC_ADDRESS                 MacAddress;
+  ///
+  /// Network interface type(i.e. 802.3, FDDI).
+  ///
+  UINT8                           IfType;
+} MAC_ADDR_DEVICE_PATH;
+
+///
+/// IPv4 Device Path SubType
+///
+#define MSG_IPv4_DP               0x0c
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// The local IPv4 address.
+  ///
+  EFI_IPv4_ADDRESS                LocalIpAddress;
+  ///
+  /// The remote IPv4 address.
+  ///
+  EFI_IPv4_ADDRESS                RemoteIpAddress;
+  ///
+  /// The local port number.
+  ///
+  UINT16                          LocalPort;
+  ///
+  /// The remote port number.
+  ///
+  UINT16                          RemotePort;
+  ///
+  /// The network protocol(i.e. UDP, TCP).
+  ///
+  UINT16                          Protocol;
+  ///
+  /// 0x00 - The Source IP Address was assigned though DHCP.
+  /// 0x01 - The Source IP Address is statically bound.
+  ///
+  BOOLEAN                         StaticIpAddress;
+  ///
+  /// The gateway IP address
+  ///
+  EFI_IPv4_ADDRESS                GatewayIpAddress;
+  ///
+  /// The subnet mask
+  ///
+  EFI_IPv4_ADDRESS                SubnetMask;
+} IPv4_DEVICE_PATH;
+
+///
+/// IPv6 Device Path SubType.
+///
+#define MSG_IPv6_DP               0x0d
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// The local IPv6 address.
+  ///
+  EFI_IPv6_ADDRESS                LocalIpAddress;
+  ///
+  /// The remote IPv6 address.
+  ///
+  EFI_IPv6_ADDRESS                RemoteIpAddress;
+  ///
+  /// The local port number.
+  ///
+  UINT16                          LocalPort;
+  ///
+  /// The remote port number.
+  ///
+  UINT16                          RemotePort;
+  ///
+  /// The network protocol(i.e. UDP, TCP).
+  ///
+  UINT16                          Protocol;
+  ///
+  /// 0x00 - The Local IP Address was manually configured.
+  /// 0x01 - The Local IP Address is assigned through IPv6
+  /// stateless auto-configuration.
+  /// 0x02 - The Local IP Address is assigned through IPv6
+  /// stateful configuration.
+  ///
+  UINT8                           IpAddressOrigin;
+  ///
+  /// The prefix length
+  ///
+  UINT8                           PrefixLength;
+  ///
+  /// The gateway IP address
+  ///
+  EFI_IPv6_ADDRESS                GatewayIpAddress;
+} IPv6_DEVICE_PATH;
+
+///
+/// InfiniBand Device Path SubType.
+///
+#define MSG_INFINIBAND_DP         0x09
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Flags to help identify/manage InfiniBand device path elements:
+  /// Bit 0 - IOC/Service (0b = IOC, 1b = Service).
+  /// Bit 1 - Extend Boot Environment.
+  /// Bit 2 - Console Protocol.
+  /// Bit 3 - Storage Protocol.
+  /// Bit 4 - Network Protocol.
+  /// All other bits are reserved.
+  ///
+  UINT32                          ResourceFlags;
+  ///
+  /// 128-bit Global Identifier for remote fabric port.
+  ///
+  UINT8                           PortGid[16];
+  ///
+  /// 64-bit unique identifier to remote IOC or server process.
+  /// Interpretation of field specified by Resource Flags (bit 0).
+  ///
+  UINT64                          ServiceId;
+  ///
+  /// 64-bit persistent ID of remote IOC port.
+  ///
+  UINT64                          TargetPortId;
+  ///
+  /// 64-bit persistent ID of remote device.
+  ///
+  UINT64                          DeviceId;
+} INFINIBAND_DEVICE_PATH;
+
+#define INFINIBAND_RESOURCE_FLAG_IOC_SERVICE                0x01
+#define INFINIBAND_RESOURCE_FLAG_EXTENDED_BOOT_ENVIRONMENT  0x02
+#define INFINIBAND_RESOURCE_FLAG_CONSOLE_PROTOCOL           0x04
+#define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL           0x08
+#define INFINIBAND_RESOURCE_FLAG_NETWORK_PROTOCOL           0x10
+
+///
+/// UART Device Path SubType.
+///
+#define MSG_UART_DP               0x0e
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Reserved.
+  ///
+  UINT32                          Reserved;
+  ///
+  /// The baud rate setting for the UART style device. A value of 0
+  /// means that the device's default baud rate will be used.
+  ///
+  UINT64                          BaudRate;
+  ///
+  /// The number of data bits for the UART style device. A value
+  /// of 0 means that the device's default number of data bits will be used.
+  ///
+  UINT8                           DataBits;
+  ///
+  /// The parity setting for the UART style device.
+  /// Parity 0x00 - Default Parity.
+  /// Parity 0x01 - No Parity.
+  /// Parity 0x02 - Even Parity.
+  /// Parity 0x03 - Odd Parity.
+  /// Parity 0x04 - Mark Parity.
+  /// Parity 0x05 - Space Parity.
+  ///
+  UINT8                           Parity;
+  ///
+  /// The number of stop bits for the UART style device.
+  /// Stop Bits 0x00 - Default Stop Bits.
+  /// Stop Bits 0x01 - 1 Stop Bit.
+  /// Stop Bits 0x02 - 1.5 Stop Bits.
+  /// Stop Bits 0x03 - 2 Stop Bits.
+  ///
+  UINT8                           StopBits;
+} UART_DEVICE_PATH;
+
+//
+// Use VENDOR_DEVICE_PATH struct
+//
+#define MSG_VENDOR_DP             0x0a
+typedef VENDOR_DEVICE_PATH        VENDOR_DEFINED_DEVICE_PATH;
+
+#define DEVICE_PATH_MESSAGING_PC_ANSI     EFI_PC_ANSI_GUID
+#define DEVICE_PATH_MESSAGING_VT_100      EFI_VT_100_GUID
+#define DEVICE_PATH_MESSAGING_VT_100_PLUS EFI_VT_100_PLUS_GUID
+#define DEVICE_PATH_MESSAGING_VT_UTF8     EFI_VT_UTF8_GUID
+
+///
+/// A new device path node is defined to declare flow control characteristics.
+/// UART Flow Control Messaging Device Path
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL GUID.
+  ///
+  EFI_GUID                        Guid;
+  ///
+  /// Bitmap of supported flow control types.
+  /// Bit 0 set indicates hardware flow control.
+  /// Bit 1 set indicates Xon/Xoff flow control.
+  /// All other bits are reserved and are clear.
+  ///
+  UINT32                          FlowControlMap;
+} UART_FLOW_CONTROL_DEVICE_PATH;
+
+#define UART_FLOW_CONTROL_HARDWARE         0x00000001
+#define UART_FLOW_CONTROL_XON_XOFF         0x00000010
+
+#define DEVICE_PATH_MESSAGING_SAS          EFI_SAS_DEVICE_PATH_GUID
+///
+/// Serial Attached SCSI (SAS) Device Path.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// DEVICE_PATH_MESSAGING_SAS GUID.
+  ///
+  EFI_GUID                        Guid;
+  ///
+  /// Reserved for future use.
+  ///
+  UINT32                          Reserved;
+  ///
+  /// SAS Address for Serial Attached SCSI Target.
+  ///
+  UINT64                          SasAddress;
+  ///
+  /// SAS Logical Unit Number.
+  ///
+  UINT64                          Lun;
+  ///
+  /// More Information about the device and its interconnect.
+  ///
+  UINT16                          DeviceTopology;
+  ///
+  /// Relative Target Port (RTP).
+  ///
+  UINT16                          RelativeTargetPort;
+} SAS_DEVICE_PATH;
+
+///
+/// Serial Attached SCSI (SAS) Ex Device Path SubType
+///
+#define MSG_SASEX_DP              0x16
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// 8-byte array of the SAS Address for Serial Attached SCSI Target Port.
+  ///
+  UINT8                           SasAddress[8];
+  ///
+  /// 8-byte array of the SAS Logical Unit Number.
+  ///
+  UINT8                           Lun[8];
+  ///
+  /// More Information about the device and its interconnect.
+  ///
+  UINT16                          DeviceTopology;
+  ///
+  /// Relative Target Port (RTP).
+  ///
+  UINT16                          RelativeTargetPort;
+} SASEX_DEVICE_PATH;
+
+///
+/// NvmExpress Namespace Device Path SubType.
+///
+#define MSG_NVME_NAMESPACE_DP     0x17
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  UINT32                          NamespaceId;
+  UINT64                          NamespaceUuid;
+} NVME_NAMESPACE_DEVICE_PATH;
+
+///
+/// iSCSI Device Path SubType
+///
+#define MSG_ISCSI_DP              0x13
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Network Protocol (0 = TCP, 1+ = reserved).
+  ///
+  UINT16                          NetworkProtocol;
+  ///
+  /// iSCSI Login Options.
+  ///
+  UINT16                          LoginOption;
+  ///
+  /// iSCSI Logical Unit Number.
+  ///
+  UINT64                          Lun;
+  ///
+  /// iSCSI Target Portal group tag the initiator intends
+  /// to establish a session with.
+  ///
+  UINT16                          TargetPortalGroupTag;
+  ///
+  /// iSCSI NodeTarget Name. The length of the name
+  /// is determined by subtracting the offset of this field from Length.
+  ///
+  /// CHAR8                        iSCSI Target Name.
+} ISCSI_DEVICE_PATH;
+
+#define ISCSI_LOGIN_OPTION_NO_HEADER_DIGEST             0x0000
+#define ISCSI_LOGIN_OPTION_HEADER_DIGEST_USING_CRC32C   0x0002
+#define ISCSI_LOGIN_OPTION_NO_DATA_DIGEST               0x0000
+#define ISCSI_LOGIN_OPTION_DATA_DIGEST_USING_CRC32C     0x0008
+#define ISCSI_LOGIN_OPTION_AUTHMETHOD_CHAP              0x0000
+#define ISCSI_LOGIN_OPTION_AUTHMETHOD_NON               0x1000
+#define ISCSI_LOGIN_OPTION_CHAP_BI                      0x0000
+#define ISCSI_LOGIN_OPTION_CHAP_UNI                     0x2000
+
+///
+/// VLAN Device Path SubType.
+///
+#define MSG_VLAN_DP               0x14
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// VLAN identifier (0-4094).
+  ///
+  UINT16                          VlanId;
+} VLAN_DEVICE_PATH;
+
+//
+// Media Device Path
+//
+#define MEDIA_DEVICE_PATH         0x04
+
+///
+/// Hard Drive Media Device Path SubType.
+///
+#define MEDIA_HARDDRIVE_DP        0x01
+
+///
+/// The Hard Drive Media Device Path is used to represent a partition on a hard drive.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Describes the entry in a partition table, starting with entry 1.
+  /// Partition number zero represents the entire device. Valid
+  /// partition numbers for a MBR partition are [1, 4]. Valid
+  /// partition numbers for a GPT partition are [1, NumberOfPartitionEntries].
+  ///
+  UINT32                          PartitionNumber;
+  ///
+  /// Starting LBA of the partition on the hard drive.
+  ///
+  UINT64                          PartitionStart;
+  ///
+  /// Size of the partition in units of Logical Blocks.
+  ///
+  UINT64                          PartitionSize;
+  ///
+  /// Signature unique to this partition:
+  /// If SignatureType is 0, this field has to be initialized with 16 zeros.
+  /// If SignatureType is 1, the MBR signature is stored in the first 4 bytes of this field.
+  /// The other 12 bytes are initialized with zeros.
+  /// If SignatureType is 2, this field contains a 16 byte signature.
+  ///
+  UINT8                           Signature[16];
+  ///
+  /// Partition Format: (Unused values reserved).
+  /// 0x01 - PC-AT compatible legacy MBR.
+  /// 0x02 - GUID Partition Table.
+  ///
+  UINT8                           MBRType;
+  ///
+  /// Type of Disk Signature: (Unused values reserved).
+  /// 0x00 - No Disk Signature.
+  /// 0x01 - 32-bit signature from address 0x1b8 of the type 0x01 MBR.
+  /// 0x02 - GUID signature.
+  ///
+  UINT8                           SignatureType;
+} HARDDRIVE_DEVICE_PATH;
+
+#define MBR_TYPE_PCAT             0x01
+#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
+
+#define NO_DISK_SIGNATURE         0x00
+#define SIGNATURE_TYPE_MBR        0x01
+#define SIGNATURE_TYPE_GUID       0x02
+
+///
+/// CD-ROM Media Device Path SubType.
+///
+#define MEDIA_CDROM_DP            0x02
+
+///
+/// The CD-ROM Media Device Path is used to define a system partition that exists on a CD-ROM.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Boot Entry number from the Boot Catalog. The Initial/Default entry is defined as zero.
+  ///
+  UINT32                          BootEntry;
+  ///
+  /// Starting RBA of the partition on the medium. CD-ROMs use Relative logical Block Addressing.
+  ///
+  UINT64                          PartitionStart;
+  ///
+  /// Size of the partition in units of Blocks, also called Sectors.
+  ///
+  UINT64                          PartitionSize;
+} CDROM_DEVICE_PATH;
+
+//
+// Use VENDOR_DEVICE_PATH struct
+//
+#define MEDIA_VENDOR_DP           0x03  ///< Media vendor device path subtype.
+
+///
+/// File Path Media Device Path SubType
+///
+#define MEDIA_FILEPATH_DP         0x04
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// A NULL-terminated Path string including directory and file names.
+  ///
+  CHAR16                          PathName[1];
+} FILEPATH_DEVICE_PATH;
+
+#define SIZE_OF_FILEPATH_DEVICE_PATH  OFFSET_OF(FILEPATH_DEVICE_PATH,PathName)
+
+///
+/// Media Protocol Device Path SubType.
+///
+#define MEDIA_PROTOCOL_DP         0x05
+
+///
+/// The Media Protocol Device Path is used to denote the protocol that is being
+/// used in a device path at the location of the path specified.
+/// Many protocols are inherent to the style of device path.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// The ID of the protocol.
+  ///
+  EFI_GUID                        Protocol;
+} MEDIA_PROTOCOL_DEVICE_PATH;
+
+///
+/// PIWG Firmware File SubType.
+///
+#define MEDIA_PIWG_FW_FILE_DP     0x06
+
+///
+/// This device path is used by systems implementing the UEFI PI Specification 1.0 to describe a firmware file.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Firmware file name
+  ///
+  EFI_GUID                        FvFileName;
+} MEDIA_FW_VOL_FILEPATH_DEVICE_PATH;
+
+///
+/// PIWG Firmware Volume Device Path SubType.
+///
+#define MEDIA_PIWG_FW_VOL_DP      0x07
+
+///
+/// This device path is used by systems implementing the UEFI PI Specification 1.0 to describe a firmware volume.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Firmware volume name.
+  ///
+  EFI_GUID                        FvName;
+} MEDIA_FW_VOL_DEVICE_PATH;
+
+///
+/// Media relative offset range device path.
+///
+#define MEDIA_RELATIVE_OFFSET_RANGE_DP 0x08
+
+///
+/// Used to describe the offset range of media relative.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL  Header;
+  UINT32                    Reserved;
+  UINT64                    StartingOffset;
+  UINT64                    EndingOffset;
+} MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH;
+
+///
+/// BIOS Boot Specification Device Path.
+///
+#define BBS_DEVICE_PATH           0x05
+
+///
+/// BIOS Boot Specification Device Path SubType.
+///
+#define BBS_BBS_DP                0x01
+
+///
+/// This Device Path is used to describe the booting of non-EFI-aware operating systems.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Device Type as defined by the BIOS Boot Specification.
+  ///
+  UINT16                          DeviceType;
+  ///
+  /// Status Flags as defined by the BIOS Boot Specification.
+  ///
+  UINT16                          StatusFlag;
+  ///
+  /// Null-terminated ASCII string that describes the boot device to a user.
+  ///
+  CHAR8                           String[1];
+} BBS_BBS_DEVICE_PATH;
+
+//
+// DeviceType definitions - from BBS specification
+//
+#define BBS_TYPE_FLOPPY           0x01
+#define BBS_TYPE_HARDDRIVE        0x02
+#define BBS_TYPE_CDROM            0x03
+#define BBS_TYPE_PCMCIA           0x04
+#define BBS_TYPE_USB              0x05
+#define BBS_TYPE_EMBEDDED_NETWORK 0x06
+#define BBS_TYPE_BEV              0x80
+#define BBS_TYPE_UNKNOWN          0xFF
+
+
+///
+/// Union of all possible Device Paths and pointers to Device Paths.
+///
+typedef union {
+  EFI_DEVICE_PATH_PROTOCOL                   DevPath;
+  PCI_DEVICE_PATH                            Pci;
+  PCCARD_DEVICE_PATH                         PcCard;
+  MEMMAP_DEVICE_PATH                         MemMap;
+  VENDOR_DEVICE_PATH                         Vendor;
+
+  CONTROLLER_DEVICE_PATH                     Controller;
+  ACPI_HID_DEVICE_PATH                       Acpi;
+  ACPI_EXTENDED_HID_DEVICE_PATH              ExtendedAcpi;
+  ACPI_ADR_DEVICE_PATH                       AcpiAdr;
+
+  ATAPI_DEVICE_PATH                          Atapi;
+  SCSI_DEVICE_PATH                           Scsi;
+  ISCSI_DEVICE_PATH                          Iscsi;
+  FIBRECHANNEL_DEVICE_PATH                   FibreChannel;
+  FIBRECHANNELEX_DEVICE_PATH                 FibreChannelEx;
+
+  F1394_DEVICE_PATH                          F1394;
+  USB_DEVICE_PATH                            Usb;
+  SATA_DEVICE_PATH                           Sata;
+  USB_CLASS_DEVICE_PATH                      UsbClass;
+  USB_WWID_DEVICE_PATH                       UsbWwid;
+  DEVICE_LOGICAL_UNIT_DEVICE_PATH            LogicUnit;
+  I2O_DEVICE_PATH                            I2O;
+  MAC_ADDR_DEVICE_PATH                       MacAddr;
+  IPv4_DEVICE_PATH                           Ipv4;
+  IPv6_DEVICE_PATH                           Ipv6;
+  VLAN_DEVICE_PATH                           Vlan;
+  INFINIBAND_DEVICE_PATH                     InfiniBand;
+  UART_DEVICE_PATH                           Uart;
+  UART_FLOW_CONTROL_DEVICE_PATH              UartFlowControl;
+  SAS_DEVICE_PATH                            Sas;
+  SASEX_DEVICE_PATH                          SasEx;
+  NVME_NAMESPACE_DEVICE_PATH                 NvmeNamespace;
+  HARDDRIVE_DEVICE_PATH                      HardDrive;
+  CDROM_DEVICE_PATH                          CD;
+
+  FILEPATH_DEVICE_PATH                       FilePath;
+  MEDIA_PROTOCOL_DEVICE_PATH                 MediaProtocol;
+
+  MEDIA_FW_VOL_DEVICE_PATH                   FirmwareVolume;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH          FirmwareFile;
+  MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH    Offset;
+
+  BBS_BBS_DEVICE_PATH                        Bbs;
+} EFI_DEV_PATH;
+
+
+
+typedef union {
+  EFI_DEVICE_PATH_PROTOCOL                   *DevPath;
+  PCI_DEVICE_PATH                            *Pci;
+  PCCARD_DEVICE_PATH                         *PcCard;
+  MEMMAP_DEVICE_PATH                         *MemMap;
+  VENDOR_DEVICE_PATH                         *Vendor;
+
+  CONTROLLER_DEVICE_PATH                     *Controller;
+  ACPI_HID_DEVICE_PATH                       *Acpi;
+  ACPI_EXTENDED_HID_DEVICE_PATH              *ExtendedAcpi;
+  ACPI_ADR_DEVICE_PATH                       *AcpiAdr;
+
+  ATAPI_DEVICE_PATH                          *Atapi;
+  SCSI_DEVICE_PATH                           *Scsi;
+  ISCSI_DEVICE_PATH                          *Iscsi;
+  FIBRECHANNEL_DEVICE_PATH                   *FibreChannel;
+  FIBRECHANNELEX_DEVICE_PATH                 *FibreChannelEx;
+
+  F1394_DEVICE_PATH                          *F1394;
+  USB_DEVICE_PATH                            *Usb;
+  SATA_DEVICE_PATH                           *Sata;
+  USB_CLASS_DEVICE_PATH                      *UsbClass;
+  USB_WWID_DEVICE_PATH                       *UsbWwid;
+  DEVICE_LOGICAL_UNIT_DEVICE_PATH            *LogicUnit;
+  I2O_DEVICE_PATH                            *I2O;
+  MAC_ADDR_DEVICE_PATH                       *MacAddr;
+  IPv4_DEVICE_PATH                           *Ipv4;
+  IPv6_DEVICE_PATH                           *Ipv6;
+  VLAN_DEVICE_PATH                           *Vlan;
+  INFINIBAND_DEVICE_PATH                     *InfiniBand;
+  UART_DEVICE_PATH                           *Uart;
+  UART_FLOW_CONTROL_DEVICE_PATH              *UartFlowControl;
+  SAS_DEVICE_PATH                            *Sas;
+  SASEX_DEVICE_PATH                          *SasEx;
+  NVME_NAMESPACE_DEVICE_PATH                 *NvmeNamespace;
+  HARDDRIVE_DEVICE_PATH                      *HardDrive;
+  CDROM_DEVICE_PATH                          *CD;
+
+  FILEPATH_DEVICE_PATH                       *FilePath;
+  MEDIA_PROTOCOL_DEVICE_PATH                 *MediaProtocol;
+
+  MEDIA_FW_VOL_DEVICE_PATH                   *FirmwareVolume;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH          *FirmwareFile;
+  MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH    *Offset;
+
+  BBS_BBS_DEVICE_PATH                        *Bbs;
+  UINT8                                      *Raw;
+} EFI_DEV_PATH_PTR;
+
+#pragma pack()
+
+#define END_DEVICE_PATH_TYPE                 0x7f
+#define END_ENTIRE_DEVICE_PATH_SUBTYPE       0xFF
+#define END_INSTANCE_DEVICE_PATH_SUBTYPE     0x01
+
+extern EFI_GUID gEfiDevicePathProtocolGuid;
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/Protocol/GraphicsOutput.h b/wimboot/wimboot-2.7.3/src/efi/Protocol/GraphicsOutput.h
new file mode 100644 (file)
index 0000000..0621b57
--- /dev/null
@@ -0,0 +1,276 @@
+/** @file
+  Graphics Output Protocol from the UEFI 2.0 specification.
+
+  Abstraction of a very simple graphics device.
+
+  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __GRAPHICS_OUTPUT_H__
+#define __GRAPHICS_OUTPUT_H__
+
+#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
+  { \
+    0x9042a9de, 0x23dc, 0x4a38, {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } \
+  }
+
+typedef struct _EFI_GRAPHICS_OUTPUT_PROTOCOL EFI_GRAPHICS_OUTPUT_PROTOCOL;
+
+typedef struct {
+  UINT32            RedMask;
+  UINT32            GreenMask;
+  UINT32            BlueMask;
+  UINT32            ReservedMask;
+} EFI_PIXEL_BITMASK;
+
+typedef enum {
+  ///
+  /// A pixel is 32-bits and byte zero represents red, byte one represents green,
+  /// byte two represents blue, and byte three is reserved. This is the definition
+  /// for the physical frame buffer. The byte values for the red, green, and blue
+  /// components represent the color intensity. This color intensity value range
+  /// from a minimum intensity of 0 to maximum intensity of 255.
+  ///
+  PixelRedGreenBlueReserved8BitPerColor,
+  ///
+  /// A pixel is 32-bits and byte zero represents blue, byte one represents green,
+  /// byte two represents red, and byte three is reserved. This is the definition
+  /// for the physical frame buffer. The byte values for the red, green, and blue
+  /// components represent the color intensity. This color intensity value range
+  /// from a minimum intensity of 0 to maximum intensity of 255.
+  ///
+  PixelBlueGreenRedReserved8BitPerColor,
+  ///
+  /// The Pixel definition of the physical frame buffer.
+  ///
+  PixelBitMask,
+  ///
+  /// This mode does not support a physical frame buffer.
+  ///
+  PixelBltOnly,
+  ///
+  /// Valid EFI_GRAPHICS_PIXEL_FORMAT enum values are less than this value.
+  ///
+  PixelFormatMax
+} EFI_GRAPHICS_PIXEL_FORMAT;
+
+typedef struct {
+  ///
+  /// The version of this data structure. A value of zero represents the
+  /// EFI_GRAPHICS_OUTPUT_MODE_INFORMATION structure as defined in this specification.
+  ///
+  UINT32                     Version;
+  ///
+  /// The size of video screen in pixels in the X dimension.
+  ///
+  UINT32                     HorizontalResolution;
+  ///
+  /// The size of video screen in pixels in the Y dimension.
+  ///
+  UINT32                     VerticalResolution;
+  ///
+  /// Enumeration that defines the physical format of the pixel. A value of PixelBltOnly
+  /// implies that a linear frame buffer is not available for this mode.
+  ///
+  EFI_GRAPHICS_PIXEL_FORMAT  PixelFormat;
+  ///
+  /// This bit-mask is only valid if PixelFormat is set to PixelPixelBitMask.
+  /// A bit being set defines what bits are used for what purpose such as Red, Green, Blue, or Reserved.
+  ///
+  EFI_PIXEL_BITMASK          PixelInformation;
+  ///
+  /// Defines the number of pixel elements per video memory line.
+  ///
+  UINT32                     PixelsPerScanLine;
+} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION;
+
+/**
+  Returns information for an available graphics mode that the graphics device
+  and the set of active video output devices supports.
+
+  @param  This                  The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
+  @param  ModeNumber            The mode number to return information on.
+  @param  SizeOfInfo            A pointer to the size, in bytes, of the Info buffer.
+  @param  Info                  A pointer to callee allocated buffer that returns information about ModeNumber.
+
+  @retval EFI_SUCCESS           Valid mode information was returned.
+  @retval EFI_DEVICE_ERROR      A hardware error occurred trying to retrieve the video mode.
+  @retval EFI_INVALID_PARAMETER ModeNumber is not valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE)(
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
+  IN  UINT32                                ModeNumber,
+  OUT UINTN                                 *SizeOfInfo,
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info
+  );
+
+/**
+  Set the video device into the specified mode and clears the visible portions of
+  the output display to black.
+
+  @param  This              The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
+  @param  ModeNumber        Abstraction that defines the current video mode.
+
+  @retval EFI_SUCCESS       The graphics mode specified by ModeNumber was selected.
+  @retval EFI_DEVICE_ERROR  The device had an error and could not complete the request.
+  @retval EFI_UNSUPPORTED   ModeNumber is not supported by this device.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE)(
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+  IN  UINT32                       ModeNumber
+  );
+
+typedef struct {
+  UINT8 Blue;
+  UINT8 Green;
+  UINT8 Red;
+  UINT8 Reserved;
+} EFI_GRAPHICS_OUTPUT_BLT_PIXEL;
+
+typedef union {
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Pixel;
+  UINT32                        Raw;
+} EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION;
+
+///
+/// actions for BltOperations
+///
+typedef enum {
+  ///
+  /// Write data from the BltBuffer pixel (0, 0)
+  /// directly to every pixel of the video display rectangle
+  /// (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height).
+  /// Only one pixel will be used from the BltBuffer. Delta is NOT used.
+  ///
+  EfiBltVideoFill,
+
+  ///
+  /// Read data from the video display rectangle
+  /// (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
+  /// the BltBuffer rectangle (DestinationX, DestinationY )
+  /// (DestinationX + Width, DestinationY + Height). If DestinationX or
+  /// DestinationY is not zero then Delta must be set to the length in bytes
+  /// of a row in the BltBuffer.
+  ///
+  EfiBltVideoToBltBuffer,
+
+  ///
+  /// Write data from the BltBuffer rectangle
+  /// (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
+  /// video display rectangle (DestinationX, DestinationY)
+  /// (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
+  /// not zero then Delta must be set to the length in bytes of a row in the
+  /// BltBuffer.
+  ///
+  EfiBltBufferToVideo,
+
+  ///
+  /// Copy from the video display rectangle (SourceX, SourceY)
+  /// (SourceX + Width, SourceY + Height) to the video display rectangle
+  /// (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height).
+  /// The BltBuffer and Delta are not used in this mode.
+  ///
+  EfiBltVideoToVideo,
+
+  EfiGraphicsOutputBltOperationMax
+} EFI_GRAPHICS_OUTPUT_BLT_OPERATION;
+
+/**
+  Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer.
+
+  @param  This         Protocol instance pointer.
+  @param  BltBuffer    The data to transfer to the graphics screen.
+                       Size is at least Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL).
+  @param  BltOperation The operation to perform when copying BltBuffer on to the graphics screen.
+  @param  SourceX      The X coordinate of source for the BltOperation.
+  @param  SourceY      The Y coordinate of source for the BltOperation.
+  @param  DestinationX The X coordinate of destination for the BltOperation.
+  @param  DestinationY The Y coordinate of destination for the BltOperation.
+  @param  Width        The width of a rectangle in the blt rectangle in pixels.
+  @param  Height       The height of a rectangle in the blt rectangle in pixels.
+  @param  Delta        Not used for EfiBltVideoFill or the EfiBltVideoToVideo operation.
+                       If a Delta of zero is used, the entire BltBuffer is being operated on.
+                       If a subrectangle of the BltBuffer is being used then Delta
+                       represents the number of bytes in a row of the BltBuffer.
+
+  @retval EFI_SUCCESS           BltBuffer was drawn to the graphics screen.
+  @retval EFI_INVALID_PARAMETER BltOperation is not valid.
+  @retval EFI_DEVICE_ERROR      The device had an error and could not complete the request.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT)(
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL            *This,
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL           *BltBuffer,   OPTIONAL
+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION       BltOperation,
+  IN  UINTN                                   SourceX,
+  IN  UINTN                                   SourceY,
+  IN  UINTN                                   DestinationX,
+  IN  UINTN                                   DestinationY,
+  IN  UINTN                                   Width,
+  IN  UINTN                                   Height,
+  IN  UINTN                                   Delta         OPTIONAL
+  );
+
+typedef struct {
+  ///
+  /// The number of modes supported by QueryMode() and SetMode().
+  ///
+  UINT32                                 MaxMode;
+  ///
+  /// Current Mode of the graphics device. Valid mode numbers are 0 to MaxMode -1.
+  ///
+  UINT32                                 Mode;
+  ///
+  /// Pointer to read-only EFI_GRAPHICS_OUTPUT_MODE_INFORMATION data.
+  ///
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   *Info;
+  ///
+  /// Size of Info structure in bytes.
+  ///
+  UINTN                                  SizeOfInfo;
+  ///
+  /// Base address of graphics linear frame buffer.
+  /// Offset zero in FrameBufferBase represents the upper left pixel of the display.
+  ///
+  EFI_PHYSICAL_ADDRESS                   FrameBufferBase;
+  ///
+  /// Amount of frame buffer needed to support the active mode as defined by
+  /// PixelsPerScanLine xVerticalResolution x PixelElementSize.
+  ///
+  UINTN                                  FrameBufferSize;
+} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;
+
+///
+/// Provides a basic abstraction to set video modes and copy pixels to and from
+/// the graphics controller's frame buffer. The linear address of the hardware
+/// frame buffer is also exposed so software can write directly to the video hardware.
+///
+struct _EFI_GRAPHICS_OUTPUT_PROTOCOL {
+  EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE  QueryMode;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE    SetMode;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT         Blt;
+  ///
+  /// Pointer to EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE data.
+  ///
+  EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE        *Mode;
+};
+
+extern EFI_GUID gEfiGraphicsOutputProtocolGuid;
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/Protocol/LoadedImage.h b/wimboot/wimboot-2.7.3/src/efi/Protocol/LoadedImage.h
new file mode 100644 (file)
index 0000000..12e5e2d
--- /dev/null
@@ -0,0 +1,88 @@
+/** @file
+  UEFI 2.0 Loaded image protocol definition.
+
+  Every EFI driver and application is passed an image handle when it is loaded.
+  This image handle will contain a Loaded Image Protocol.
+
+  Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __LOADED_IMAGE_PROTOCOL_H__
+#define __LOADED_IMAGE_PROTOCOL_H__
+
+#define EFI_LOADED_IMAGE_PROTOCOL_GUID \
+  { \
+    0x5B1B31A1, 0x9562, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \
+  }
+
+#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \
+  { \
+    0xbc62157e, 0x3e33, 0x4fec, {0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf } \
+  }
+
+///
+/// Protocol GUID defined in EFI1.1.
+///
+#define LOADED_IMAGE_PROTOCOL   EFI_LOADED_IMAGE_PROTOCOL_GUID
+
+///
+/// EFI_SYSTEM_TABLE & EFI_IMAGE_UNLOAD are defined in EfiApi.h
+///
+#define EFI_LOADED_IMAGE_PROTOCOL_REVISION  0x1000
+
+///
+/// Revision defined in EFI1.1.
+///
+#define EFI_LOADED_IMAGE_INFORMATION_REVISION    EFI_LOADED_IMAGE_PROTOCOL_REVISION
+
+///
+/// Can be used on any image handle to obtain information about the loaded image.
+///
+typedef struct {
+  UINT32            Revision;       ///< Defines the revision of the EFI_LOADED_IMAGE_PROTOCOL structure.
+                                    ///< All future revisions will be backward compatible to the current revision.
+  EFI_HANDLE        ParentHandle;   ///< Parent image's image handle. NULL if the image is loaded directly from
+                                    ///< the firmware's boot manager.
+  EFI_SYSTEM_TABLE  *SystemTable;   ///< the image's EFI system table pointer.
+
+  //
+  // Source location of image
+  //
+  EFI_HANDLE        DeviceHandle;   ///< The device handle that the EFI Image was loaded from.
+  EFI_DEVICE_PATH_PROTOCOL  *FilePath;  ///< A pointer to the file path portion specific to DeviceHandle
+                                        ///< that the EFI Image was loaded from.
+  VOID              *Reserved;      ///< Reserved. DO NOT USE.
+
+  //
+  // Images load options
+  //
+  UINT32            LoadOptionsSize;///< The size in bytes of LoadOptions.
+  VOID              *LoadOptions;   ///< A pointer to the image's binary load options.
+
+  //
+  // Location of where image was loaded
+  //
+  VOID              *ImageBase;     ///< The base address at which the image was loaded.
+  UINT64            ImageSize;      ///< The size in bytes of the loaded image.
+  EFI_MEMORY_TYPE   ImageCodeType;  ///< The memory type that the code sections were loaded as.
+  EFI_MEMORY_TYPE   ImageDataType;  ///< The memory type that the data sections were loaded as.
+  EFI_IMAGE_UNLOAD  Unload;
+} EFI_LOADED_IMAGE_PROTOCOL;
+
+//
+// For backward-compatible with EFI1.1.
+//
+typedef EFI_LOADED_IMAGE_PROTOCOL EFI_LOADED_IMAGE;
+
+extern EFI_GUID gEfiLoadedImageProtocolGuid;
+extern EFI_GUID gEfiLoadedImageDevicePathProtocolGuid;
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/Protocol/SimpleFileSystem.h b/wimboot/wimboot-2.7.3/src/efi/Protocol/SimpleFileSystem.h
new file mode 100644 (file)
index 0000000..37888d5
--- /dev/null
@@ -0,0 +1,562 @@
+/** @file
+  SimpleFileSystem protocol as defined in the UEFI 2.0 specification.
+
+  The SimpleFileSystem protocol is the programmatic access to the FAT (12,16,32)
+  file system specified in UEFI 2.0. It can also be used to abstract a file
+  system other than FAT.
+
+  UEFI 2.0 can boot from any valid EFI image contained in a SimpleFileSystem.
+
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __SIMPLE_FILE_SYSTEM_H__
+#define __SIMPLE_FILE_SYSTEM_H__
+
+#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \
+  { \
+    0x964e5b22, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+typedef struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL;
+
+typedef struct _EFI_FILE_PROTOCOL         EFI_FILE_PROTOCOL;
+typedef struct _EFI_FILE_PROTOCOL         *EFI_FILE_HANDLE;
+
+///
+/// Protocol GUID name defined in EFI1.1.
+///
+#define SIMPLE_FILE_SYSTEM_PROTOCOL       EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID
+
+///
+/// Protocol name defined in EFI1.1.
+///
+typedef EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   EFI_FILE_IO_INTERFACE;
+typedef EFI_FILE_PROTOCOL                 EFI_FILE;
+
+/**
+  Open the root directory on a volume.
+
+  @param  This A pointer to the volume to open the root directory.
+  @param  Root A pointer to the location to return the opened file handle for the
+               root directory.
+
+  @retval EFI_SUCCESS          The device was opened.
+  @retval EFI_UNSUPPORTED      This volume does not support the requested file system type.
+  @retval EFI_NO_MEDIA         The device has no medium.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_ACCESS_DENIED    The service denied access to the file.
+  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
+  @retval EFI_MEDIA_CHANGED    The device has a different medium in it or the medium is no
+                               longer supported. Any existing file handles for this volume are
+                               no longer valid. To access the files on the new medium, the
+                               volume must be reopened with OpenVolume().
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME)(
+  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL    *This,
+  OUT EFI_FILE_PROTOCOL                 **Root
+  );
+
+#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION  0x00010000
+
+///
+/// Revision defined in EFI1.1
+///
+#define EFI_FILE_IO_INTERFACE_REVISION  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
+
+struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL {
+  ///
+  /// The version of the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. The version
+  /// specified by this specification is 0x00010000. All future revisions
+  /// must be backwards compatible.
+  ///
+  UINT64                                      Revision;
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume;
+};
+
+/**
+  Opens a new file relative to the source file's location.
+
+  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file
+                     handle to the source location. This would typically be an open
+                     handle to a directory.
+  @param  NewHandle  A pointer to the location to return the opened handle for the new
+                     file.
+  @param  FileName   The Null-terminated string of the name of the file to be opened.
+                     The file name may contain the following path modifiers: "\", ".",
+                     and "..".
+  @param  OpenMode   The mode to open the file. The only valid combinations that the
+                     file may be opened with are: Read, Read/Write, or Create/Read/Write.
+  @param  Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the
+                     attribute bits for the newly created file.
+
+  @retval EFI_SUCCESS          The file was opened.
+  @retval EFI_NOT_FOUND        The specified file could not be found on the device.
+  @retval EFI_NO_MEDIA         The device has no medium.
+  @retval EFI_MEDIA_CHANGED    The device has a different medium in it or the medium is no
+                               longer supported.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED  An attempt was made to create a file, or open a file for write
+                               when the media is write-protected.
+  @retval EFI_ACCESS_DENIED    The service denied access to the file.
+  @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
+  @retval EFI_VOLUME_FULL      The volume is full.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_OPEN)(
+  IN EFI_FILE_PROTOCOL        *This,
+  OUT EFI_FILE_PROTOCOL       **NewHandle,
+  IN CHAR16                   *FileName,
+  IN UINT64                   OpenMode,
+  IN UINT64                   Attributes
+  );
+
+//
+// Open modes
+//
+#define EFI_FILE_MODE_READ    0x0000000000000001ULL
+#define EFI_FILE_MODE_WRITE   0x0000000000000002ULL
+#define EFI_FILE_MODE_CREATE  0x8000000000000000ULL
+
+//
+// File attributes
+//
+#define EFI_FILE_READ_ONLY  0x0000000000000001ULL
+#define EFI_FILE_HIDDEN     0x0000000000000002ULL
+#define EFI_FILE_SYSTEM     0x0000000000000004ULL
+#define EFI_FILE_RESERVED   0x0000000000000008ULL
+#define EFI_FILE_DIRECTORY  0x0000000000000010ULL
+#define EFI_FILE_ARCHIVE    0x0000000000000020ULL
+#define EFI_FILE_VALID_ATTR 0x0000000000000037ULL
+
+/**
+  Closes a specified file handle.
+
+  @param  This          A pointer to the EFI_FILE_PROTOCOL instance that is the file
+                        handle to close.
+
+  @retval EFI_SUCCESS   The file was closed.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_CLOSE)(
+  IN EFI_FILE_PROTOCOL  *This
+  );
+
+/**
+  Close and delete the file handle.
+
+  @param  This                     A pointer to the EFI_FILE_PROTOCOL instance that is the
+                                   handle to the file to delete.
+
+  @retval EFI_SUCCESS              The file was closed and deleted, and the handle was closed.
+  @retval EFI_WARN_DELETE_FAILURE  The handle was closed, but the file was not deleted.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_DELETE)(
+  IN EFI_FILE_PROTOCOL  *This
+  );
+
+/**
+  Reads data from a file.
+
+  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file
+                     handle to read data from.
+  @param  BufferSize On input, the size of the Buffer. On output, the amount of data
+                     returned in Buffer. In both cases, the size is measured in bytes.
+  @param  Buffer     The buffer into which the data is read.
+
+  @retval EFI_SUCCESS          Data was read.
+  @retval EFI_NO_MEDIA         The device has no medium.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_DEVICE_ERROR     An attempt was made to read from a deleted file.
+  @retval EFI_DEVICE_ERROR     On entry, the current file position is beyond the end of the file.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory
+                               entry. BufferSize has been updated with the size
+                               needed to complete the request.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_READ)(
+  IN EFI_FILE_PROTOCOL        *This,
+  IN OUT UINTN                *BufferSize,
+  OUT VOID                    *Buffer
+  );
+
+/**
+  Writes data to a file.
+
+  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file
+                     handle to write data to.
+  @param  BufferSize On input, the size of the Buffer. On output, the amount of data
+                     actually written. In both cases, the size is measured in bytes.
+  @param  Buffer     The buffer of data to write.
+
+  @retval EFI_SUCCESS          Data was written.
+  @retval EFI_UNSUPPORTED      Writes to open directory files are not supported.
+  @retval EFI_NO_MEDIA         The device has no medium.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_DEVICE_ERROR     An attempt was made to write to a deleted file.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED  The file or medium is write-protected.
+  @retval EFI_ACCESS_DENIED    The file was opened read only.
+  @retval EFI_VOLUME_FULL      The volume is full.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_WRITE)(
+  IN EFI_FILE_PROTOCOL        *This,
+  IN OUT UINTN                *BufferSize,
+  IN VOID                     *Buffer
+  );
+
+/**
+  Sets a file's current position.
+
+  @param  This            A pointer to the EFI_FILE_PROTOCOL instance that is the
+                          file handle to set the requested position on.
+  @param  Position        The byte position from the start of the file to set.
+
+  @retval EFI_SUCCESS      The position was set.
+  @retval EFI_UNSUPPORTED  The seek request for nonzero is not valid on open
+                           directories.
+  @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted file.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_SET_POSITION)(
+  IN EFI_FILE_PROTOCOL        *This,
+  IN UINT64                   Position
+  );
+
+/**
+  Returns a file's current position.
+
+  @param  This            A pointer to the EFI_FILE_PROTOCOL instance that is the file
+                          handle to get the current position on.
+  @param  Position        The address to return the file's current position value.
+
+  @retval EFI_SUCCESS      The position was returned.
+  @retval EFI_UNSUPPORTED  The request is not valid on open directories.
+  @retval EFI_DEVICE_ERROR An attempt was made to get the position from a deleted file.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_GET_POSITION)(
+  IN EFI_FILE_PROTOCOL        *This,
+  OUT UINT64                  *Position
+  );
+
+/**
+  Returns information about a file.
+
+  @param  This            A pointer to the EFI_FILE_PROTOCOL instance that is the file
+                          handle the requested information is for.
+  @param  InformationType The type identifier for the information being requested.
+  @param  BufferSize      On input, the size of Buffer. On output, the amount of data
+                          returned in Buffer. In both cases, the size is measured in bytes.
+  @param  Buffer          A pointer to the data buffer to return. The buffer's type is
+                          indicated by InformationType.
+
+  @retval EFI_SUCCESS          The information was returned.
+  @retval EFI_UNSUPPORTED      The InformationType is not known.
+  @retval EFI_NO_MEDIA         The device has no medium.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry.
+                               BufferSize has been updated with the size needed to complete
+                               the request.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_GET_INFO)(
+  IN EFI_FILE_PROTOCOL        *This,
+  IN EFI_GUID                 *InformationType,
+  IN OUT UINTN                *BufferSize,
+  OUT VOID                    *Buffer
+  );
+
+/**
+  Sets information about a file.
+
+  @param  File            A pointer to the EFI_FILE_PROTOCOL instance that is the file
+                          handle the information is for.
+  @param  InformationType The type identifier for the information being set.
+  @param  BufferSize      The size, in bytes, of Buffer.
+  @param  Buffer          A pointer to the data buffer to write. The buffer's type is
+                          indicated by InformationType.
+
+  @retval EFI_SUCCESS          The information was set.
+  @retval EFI_UNSUPPORTED      The InformationType is not known.
+  @retval EFI_NO_MEDIA         The device has no medium.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED  InformationType is EFI_FILE_INFO_ID and the media is
+                               read-only.
+  @retval EFI_WRITE_PROTECTED  InformationType is EFI_FILE_PROTOCOL_SYSTEM_INFO_ID
+                               and the media is read only.
+  @retval EFI_WRITE_PROTECTED  InformationType is EFI_FILE_SYSTEM_VOLUME_LABEL_ID
+                               and the media is read-only.
+  @retval EFI_ACCESS_DENIED    An attempt is made to change the name of a file to a
+                               file that is already present.
+  @retval EFI_ACCESS_DENIED    An attempt is being made to change the EFI_FILE_DIRECTORY
+                               Attribute.
+  @retval EFI_ACCESS_DENIED    An attempt is being made to change the size of a directory.
+  @retval EFI_ACCESS_DENIED    InformationType is EFI_FILE_INFO_ID and the file was opened
+                               read-only and an attempt is being made to modify a field
+                               other than Attribute.
+  @retval EFI_VOLUME_FULL      The volume is full.
+  @retval EFI_BAD_BUFFER_SIZE  BufferSize is smaller than the size of the type indicated
+                               by InformationType.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_SET_INFO)(
+  IN EFI_FILE_PROTOCOL        *This,
+  IN EFI_GUID                 *InformationType,
+  IN UINTN                    BufferSize,
+  IN VOID                     *Buffer
+  );
+
+/**
+  Flushes all modified data associated with a file to a device.
+
+  @param  This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+               handle to flush.
+
+  @retval EFI_SUCCESS          The data was flushed.
+  @retval EFI_NO_MEDIA         The device has no medium.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED  The file or medium is write-protected.
+  @retval EFI_ACCESS_DENIED    The file was opened read-only.
+  @retval EFI_VOLUME_FULL      The volume is full.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_FLUSH)(
+  IN EFI_FILE_PROTOCOL  *This
+  );
+
+typedef struct {
+  //
+  // If Event is NULL, then blocking I/O is performed.
+  // If Event is not NULL and non-blocking I/O is supported, then non-blocking I/O is performed,
+  // and Event will be signaled when the read request is completed.
+  // The caller must be prepared to handle the case where the callback associated with Event
+  // occurs before the original asynchronous I/O request call returns.
+  //
+  EFI_EVENT                   Event;
+
+  //
+  // Defines whether or not the signaled event encountered an error.
+  //
+  EFI_STATUS                  Status;
+
+  //
+  // For OpenEx():  Not Used, ignored.
+  // For ReadEx():  On input, the size of the Buffer. On output, the amount of data returned in Buffer.
+  //                In both cases, the size is measured in bytes.
+  // For WriteEx(): On input, the size of the Buffer. On output, the amount of data actually written.
+  //                In both cases, the size is measured in bytes.
+  // For FlushEx(): Not used, ignored.
+  //
+  UINTN                       BufferSize;
+
+  //
+  // For OpenEx():  Not Used, ignored.
+  // For ReadEx():  The buffer into which the data is read.
+  // For WriteEx(): The buffer of data to write.
+  // For FlushEx(): Not Used, ignored.
+  //
+  VOID                        *Buffer;
+} EFI_FILE_IO_TOKEN;
+
+/**
+  Opens a new file relative to the source directory's location.
+
+  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file
+                     handle to the source location.
+  @param  NewHandle  A pointer to the location to return the opened handle for the new
+                     file.
+  @param  FileName   The Null-terminated string of the name of the file to be opened.
+                     The file name may contain the following path modifiers: "\", ".",
+                     and "..".
+  @param  OpenMode   The mode to open the file. The only valid combinations that the
+                     file may be opened with are: Read, Read/Write, or Create/Read/Write.
+  @param  Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the
+                     attribute bits for the newly created file.
+  @param  Token      A pointer to the token associated with the transaction.
+
+  @retval EFI_SUCCESS          If Event is NULL (blocking I/O): The data was read successfully.
+                               If Event is not NULL (asynchronous I/O): The request was successfully
+                                                                        queued for processing.
+  @retval EFI_NOT_FOUND        The specified file could not be found on the device.
+  @retval EFI_NO_MEDIA         The device has no medium.
+  @retval EFI_MEDIA_CHANGED    The device has a different medium in it or the medium is no
+                               longer supported.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED  An attempt was made to create a file, or open a file for write
+                               when the media is write-protected.
+  @retval EFI_ACCESS_DENIED    The service denied access to the file.
+  @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
+  @retval EFI_VOLUME_FULL      The volume is full.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_OPEN_EX)(
+  IN EFI_FILE_PROTOCOL        *This,
+  OUT EFI_FILE_PROTOCOL       **NewHandle,
+  IN CHAR16                   *FileName,
+  IN UINT64                   OpenMode,
+  IN UINT64                   Attributes,
+  IN OUT EFI_FILE_IO_TOKEN    *Token
+  );
+
+
+/**
+  Reads data from a file.
+
+  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to read data from.
+  @param  Token      A pointer to the token associated with the transaction.
+
+  @retval EFI_SUCCESS          If Event is NULL (blocking I/O): The data was read successfully.
+                               If Event is not NULL (asynchronous I/O): The request was successfully
+                                                                        queued for processing.
+  @retval EFI_NO_MEDIA         The device has no medium.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_DEVICE_ERROR     An attempt was made to read from a deleted file.
+  @retval EFI_DEVICE_ERROR     On entry, the current file position is beyond the end of the file.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_OUT_OF_RESOURCES Unable to queue the request due to lack of resources.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_READ_EX) (
+  IN EFI_FILE_PROTOCOL        *This,
+  IN OUT EFI_FILE_IO_TOKEN    *Token
+);
+
+
+/**
+  Writes data to a file.
+
+  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to write data to.
+  @param  Token      A pointer to the token associated with the transaction.
+
+  @retval EFI_SUCCESS          If Event is NULL (blocking I/O): The data was read successfully.
+                               If Event is not NULL (asynchronous I/O): The request was successfully
+                                                                        queued for processing.
+  @retval EFI_UNSUPPORTED      Writes to open directory files are not supported.
+  @retval EFI_NO_MEDIA         The device has no medium.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_DEVICE_ERROR     An attempt was made to write to a deleted file.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED  The file or medium is write-protected.
+  @retval EFI_ACCESS_DENIED    The file was opened read only.
+  @retval EFI_VOLUME_FULL      The volume is full.
+  @retval EFI_OUT_OF_RESOURCES Unable to queue the request due to lack of resources.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_WRITE_EX) (
+  IN EFI_FILE_PROTOCOL        *This,
+  IN OUT EFI_FILE_IO_TOKEN    *Token
+);
+
+/**
+  Flushes all modified data associated with a file to a device.
+
+  @param  This  A pointer to the EFI_FILE_PROTOCOL instance that is the file
+                handle to flush.
+  @param  Token A pointer to the token associated with the transaction.
+
+  @retval EFI_SUCCESS          If Event is NULL (blocking I/O): The data was read successfully.
+                               If Event is not NULL (asynchronous I/O): The request was successfully
+                                                                        queued for processing.
+  @retval EFI_NO_MEDIA         The device has no medium.
+  @retval EFI_DEVICE_ERROR     The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED  The file or medium is write-protected.
+  @retval EFI_ACCESS_DENIED    The file was opened read-only.
+  @retval EFI_VOLUME_FULL      The volume is full.
+  @retval EFI_OUT_OF_RESOURCES Unable to queue the request due to lack of resources.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_FLUSH_EX) (
+  IN EFI_FILE_PROTOCOL        *This,
+  IN OUT EFI_FILE_IO_TOKEN    *Token
+  );
+
+#define EFI_FILE_PROTOCOL_REVISION        0x00010000
+#define EFI_FILE_PROTOCOL_REVISION2       0x00020000
+#define EFI_FILE_PROTOCOL_LATEST_REVISION EFI_FILE_PROTOCOL_REVISION2
+
+//
+// Revision defined in EFI1.1.
+//
+#define EFI_FILE_REVISION   EFI_FILE_PROTOCOL_REVISION
+
+///
+/// The EFI_FILE_PROTOCOL provides file IO access to supported file systems.
+/// An EFI_FILE_PROTOCOL provides access to a file's or directory's contents,
+/// and is also a reference to a location in the directory tree of the file system
+/// in which the file resides. With any given file handle, other files may be opened
+/// relative to this file's location, yielding new file handles.
+///
+struct _EFI_FILE_PROTOCOL {
+  ///
+  /// The version of the EFI_FILE_PROTOCOL interface. The version specified
+  /// by this specification is EFI_FILE_PROTOCOL_LATEST_REVISION.
+  /// Future versions are required to be backward compatible to version 1.0.
+  ///
+  UINT64                Revision;
+  EFI_FILE_OPEN         Open;
+  EFI_FILE_CLOSE        Close;
+  EFI_FILE_DELETE       Delete;
+  EFI_FILE_READ         Read;
+  EFI_FILE_WRITE        Write;
+  EFI_FILE_GET_POSITION GetPosition;
+  EFI_FILE_SET_POSITION SetPosition;
+  EFI_FILE_GET_INFO     GetInfo;
+  EFI_FILE_SET_INFO     SetInfo;
+  EFI_FILE_FLUSH        Flush;
+  EFI_FILE_OPEN_EX      OpenEx;
+  EFI_FILE_READ_EX      ReadEx;
+  EFI_FILE_WRITE_EX     WriteEx;
+  EFI_FILE_FLUSH_EX     FlushEx;
+};
+
+
+extern EFI_GUID gEfiSimpleFileSystemProtocolGuid;
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/Protocol/SimpleTextIn.h b/wimboot/wimboot-2.7.3/src/efi/Protocol/SimpleTextIn.h
new file mode 100644 (file)
index 0000000..a3335f0
--- /dev/null
@@ -0,0 +1,134 @@
+/** @file
+  Simple Text Input protocol from the UEFI 2.0 specification.
+
+  Abstraction of a very simple input device like a keyboard or serial
+  terminal.
+
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __SIMPLE_TEXT_IN_PROTOCOL_H__
+#define __SIMPLE_TEXT_IN_PROTOCOL_H__
+
+#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \
+  { \
+    0x387477c1, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+typedef struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL  EFI_SIMPLE_TEXT_INPUT_PROTOCOL;
+
+///
+/// Protocol GUID name defined in EFI1.1.
+///
+#define SIMPLE_INPUT_PROTOCOL   EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID
+
+///
+/// Protocol name in EFI1.1 for backward-compatible.
+///
+typedef struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL  SIMPLE_INPUT_INTERFACE;
+
+///
+/// The keystroke information for the key that was pressed.
+///
+typedef struct {
+  UINT16  ScanCode;
+  CHAR16  UnicodeChar;
+} EFI_INPUT_KEY;
+
+//
+// Required unicode control chars
+//
+#define CHAR_NULL             0x0000
+#define CHAR_BACKSPACE        0x0008
+#define CHAR_TAB              0x0009
+#define CHAR_LINEFEED         0x000A
+#define CHAR_CARRIAGE_RETURN  0x000D
+
+//
+// EFI Scan codes
+//
+#define SCAN_NULL       0x0000
+#define SCAN_UP         0x0001
+#define SCAN_DOWN       0x0002
+#define SCAN_RIGHT      0x0003
+#define SCAN_LEFT       0x0004
+#define SCAN_HOME       0x0005
+#define SCAN_END        0x0006
+#define SCAN_INSERT     0x0007
+#define SCAN_DELETE     0x0008
+#define SCAN_PAGE_UP    0x0009
+#define SCAN_PAGE_DOWN  0x000A
+#define SCAN_F1         0x000B
+#define SCAN_F2         0x000C
+#define SCAN_F3         0x000D
+#define SCAN_F4         0x000E
+#define SCAN_F5         0x000F
+#define SCAN_F6         0x0010
+#define SCAN_F7         0x0011
+#define SCAN_F8         0x0012
+#define SCAN_F9         0x0013
+#define SCAN_F10        0x0014
+#define SCAN_ESC        0x0017
+
+/**
+  Reset the input device and optionally run diagnostics
+
+  @param  This                 Protocol instance pointer.
+  @param  ExtendedVerification Driver may perform diagnostics on reset.
+
+  @retval EFI_SUCCESS          The device was reset.
+  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could not be reset.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INPUT_RESET)(
+  IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL       *This,
+  IN BOOLEAN                              ExtendedVerification
+  );
+
+/**
+  Reads the next keystroke from the input device. The WaitForKey Event can
+  be used to test for existence of a keystroke via WaitForEvent () call.
+
+  @param  This  Protocol instance pointer.
+  @param  Key   A pointer to a buffer that is filled in with the keystroke
+                information for the key that was pressed.
+
+  @retval EFI_SUCCESS      The keystroke information was returned.
+  @retval EFI_NOT_READY    There was no keystroke data available.
+  @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
+                           hardware errors.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INPUT_READ_KEY)(
+  IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL       *This,
+  OUT EFI_INPUT_KEY                       *Key
+  );
+
+///
+/// The EFI_SIMPLE_TEXT_INPUT_PROTOCOL is used on the ConsoleIn device.
+/// It is the minimum required protocol for ConsoleIn.
+///
+struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL {
+  EFI_INPUT_RESET     Reset;
+  EFI_INPUT_READ_KEY  ReadKeyStroke;
+  ///
+  /// Event to use with WaitForEvent() to wait for a key to be available
+  ///
+  EFI_EVENT           WaitForKey;
+};
+
+extern EFI_GUID gEfiSimpleTextInProtocolGuid;
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/Protocol/SimpleTextInEx.h b/wimboot/wimboot-2.7.3/src/efi/Protocol/SimpleTextInEx.h
new file mode 100644 (file)
index 0000000..0950c32
--- /dev/null
@@ -0,0 +1,325 @@
+/** @file
+  Simple Text Input Ex protocol from the UEFI 2.0 specification.
+
+  This protocol defines an extension to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+  which exposes much more state and modifier information from the input device,
+  also allows one to register a notification for a particular keystroke.
+
+  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __SIMPLE_TEXT_IN_EX_H__
+#define __SIMPLE_TEXT_IN_EX_H__
+
+#include "efi/Protocol/SimpleTextIn.h"
+
+#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \
+  {0xdd9e7534, 0x7762, 0x4698, { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } }
+
+
+typedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL;
+
+/**
+  The Reset() function resets the input device hardware. As part
+  of initialization process, the firmware/device will make a quick
+  but reasonable attempt to verify that the device is functioning.
+  If the ExtendedVerification flag is TRUE the firmware may take
+  an extended amount of time to verify the device is operating on
+  reset. Otherwise the reset operation is to occur as quickly as
+  possible. The hardware verification process is not defined by
+  this specification and is left up to the platform firmware or
+  driver to implement.
+
+  @param This                 A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
+
+  @param ExtendedVerification Indicates that the driver may
+                              perform a more exhaustive
+                              verification operation of the
+                              device during reset.
+
+
+  @retval EFI_SUCCESS       The device was reset.
+
+  @retval EFI_DEVICE_ERROR  The device is not functioning
+                            correctly and could not be reset.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INPUT_RESET_EX)(
+  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+  IN BOOLEAN                           ExtendedVerification
+);
+
+
+///
+/// EFI_KEY_TOGGLE_STATE. The toggle states are defined.
+/// They are: EFI_TOGGLE_STATE_VALID, EFI_SCROLL_LOCK_ACTIVE
+/// EFI_NUM_LOCK_ACTIVE, EFI_CAPS_LOCK_ACTIVE
+///
+typedef UINT8 EFI_KEY_TOGGLE_STATE;
+
+typedef struct _EFI_KEY_STATE {
+  ///
+  /// Reflects the currently pressed shift
+  /// modifiers for the input device. The
+  /// returned value is valid only if the high
+  /// order bit has been set.
+  ///
+  UINT32                KeyShiftState;
+  ///
+  /// Reflects the current internal state of
+  /// various toggled attributes. The returned
+  /// value is valid only if the high order
+  /// bit has been set.
+  ///
+  EFI_KEY_TOGGLE_STATE  KeyToggleState;
+} EFI_KEY_STATE;
+
+typedef struct {
+  ///
+  /// The EFI scan code and Unicode value returned from the input device.
+  ///
+  EFI_INPUT_KEY   Key;
+  ///
+  /// The current state of various toggled attributes as well as input modifier values.
+  ///
+  EFI_KEY_STATE   KeyState;
+} EFI_KEY_DATA;
+
+//
+// Any Shift or Toggle State that is valid should have
+// high order bit set.
+//
+// Shift state
+//
+#define EFI_SHIFT_STATE_VALID     0x80000000
+#define EFI_RIGHT_SHIFT_PRESSED   0x00000001
+#define EFI_LEFT_SHIFT_PRESSED    0x00000002
+#define EFI_RIGHT_CONTROL_PRESSED 0x00000004
+#define EFI_LEFT_CONTROL_PRESSED  0x00000008
+#define EFI_RIGHT_ALT_PRESSED     0x00000010
+#define EFI_LEFT_ALT_PRESSED      0x00000020
+#define EFI_RIGHT_LOGO_PRESSED    0x00000040
+#define EFI_LEFT_LOGO_PRESSED     0x00000080
+#define EFI_MENU_KEY_PRESSED      0x00000100
+#define EFI_SYS_REQ_PRESSED       0x00000200
+
+//
+// Toggle state
+//
+#define EFI_TOGGLE_STATE_VALID    0x80
+#define EFI_KEY_STATE_EXPOSED     0x40
+#define EFI_SCROLL_LOCK_ACTIVE    0x01
+#define EFI_NUM_LOCK_ACTIVE       0x02
+#define EFI_CAPS_LOCK_ACTIVE      0x04
+
+//
+// EFI Scan codes
+//
+#define SCAN_F11                  0x0015
+#define SCAN_F12                  0x0016
+#define SCAN_PAUSE                0x0048
+#define SCAN_F13                  0x0068
+#define SCAN_F14                  0x0069
+#define SCAN_F15                  0x006A
+#define SCAN_F16                  0x006B
+#define SCAN_F17                  0x006C
+#define SCAN_F18                  0x006D
+#define SCAN_F19                  0x006E
+#define SCAN_F20                  0x006F
+#define SCAN_F21                  0x0070
+#define SCAN_F22                  0x0071
+#define SCAN_F23                  0x0072
+#define SCAN_F24                  0x0073
+#define SCAN_MUTE                 0x007F
+#define SCAN_VOLUME_UP            0x0080
+#define SCAN_VOLUME_DOWN          0x0081
+#define SCAN_BRIGHTNESS_UP        0x0100
+#define SCAN_BRIGHTNESS_DOWN      0x0101
+#define SCAN_SUSPEND              0x0102
+#define SCAN_HIBERNATE            0x0103
+#define SCAN_TOGGLE_DISPLAY       0x0104
+#define SCAN_RECOVERY             0x0105
+#define SCAN_EJECT                0x0106
+
+/**
+  The function reads the next keystroke from the input device. If
+  there is no pending keystroke the function returns
+  EFI_NOT_READY. If there is a pending keystroke, then
+  KeyData.Key.ScanCode is the EFI scan code defined in Error!
+  Reference source not found. The KeyData.Key.UnicodeChar is the
+  actual printable character or is zero if the key does not
+  represent a printable character (control key, function key,
+  etc.). The KeyData.KeyState is shift state for the character
+  reflected in KeyData.Key.UnicodeChar or KeyData.Key.ScanCode .
+  When interpreting the data from this function, it should be
+  noted that if a class of printable characters that are
+  normally adjusted by shift modifiers (e.g. Shift Key + "f"
+  key) would be presented solely as a KeyData.Key.UnicodeChar
+  without the associated shift state. So in the previous example
+  of a Shift Key + "f" key being pressed, the only pertinent
+  data returned would be KeyData.Key.UnicodeChar with the value
+  of "F". This of course would not typically be the case for
+  non-printable characters such as the pressing of the Right
+  Shift Key + F10 key since the corresponding returned data
+  would be reflected both in the KeyData.KeyState.KeyShiftState
+  and KeyData.Key.ScanCode values. UEFI drivers which implement
+  the EFI_SIMPLE_TEXT_INPUT_EX protocol are required to return
+  KeyData.Key and KeyData.KeyState values. These drivers must
+  always return the most current state of
+  KeyData.KeyState.KeyShiftState and
+  KeyData.KeyState.KeyToggleState. It should also be noted that
+  certain input devices may not be able to produce shift or toggle
+  state information, and in those cases the high order bit in the
+  respective Toggle and Shift state fields should not be active.
+
+
+  @param This     A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
+
+  @param KeyData  A pointer to a buffer that is filled in with
+                  the keystroke state data for the key that was
+                  pressed.
+
+
+  @retval EFI_SUCCESS     The keystroke information was
+                          returned.
+
+  @retval EFI_NOT_READY   There was no keystroke data available.
+                          EFI_DEVICE_ERROR The keystroke
+                          information was not returned due to
+                          hardware errors.
+
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INPUT_READ_KEY_EX)(
+  IN  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+  OUT EFI_KEY_DATA                      *KeyData
+);
+
+/**
+  The SetState() function allows the input device hardware to
+  have state settings adjusted.
+
+  @param This           A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
+
+  @param KeyToggleState Pointer to the EFI_KEY_TOGGLE_STATE to
+                        set the state for the input device.
+
+
+  @retval EFI_SUCCESS       The device state was set appropriately.
+
+  @retval EFI_DEVICE_ERROR  The device is not functioning
+                            correctly and could not have the
+                            setting adjusted.
+
+  @retval EFI_UNSUPPORTED   The device does not support the
+                            ability to have its state set.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_STATE)(
+  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+  IN EFI_KEY_TOGGLE_STATE              *KeyToggleState
+);
+
+///
+/// The function will be called when the key sequence is typed specified by KeyData.
+///
+typedef
+EFI_STATUS
+(EFIAPI *EFI_KEY_NOTIFY_FUNCTION)(
+  IN EFI_KEY_DATA *KeyData
+);
+
+/**
+  The RegisterKeystrokeNotify() function registers a function
+  which will be called when a specified keystroke will occur.
+
+  @param This                     A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
+
+  @param KeyData                  A pointer to a buffer that is filled in with
+                                  the keystroke information for the key that was
+                                  pressed.
+
+  @param KeyNotificationFunction  Points to the function to be
+                                  called when the key sequence
+                                  is typed specified by KeyData.
+
+
+  @param NotifyHandle             Points to the unique handle assigned to
+                                  the registered notification.
+
+  @retval EFI_SUCCESS           The device state was set
+                                appropriately.
+
+  @retval EFI_OUT_OF_RESOURCES  Unable to allocate necessary
+                                data structures.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_REGISTER_KEYSTROKE_NOTIFY)(
+  IN  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+  IN  EFI_KEY_DATA                      *KeyData,
+  IN  EFI_KEY_NOTIFY_FUNCTION           KeyNotificationFunction,
+  OUT VOID                              **NotifyHandle
+);
+
+/**
+  The UnregisterKeystrokeNotify() function removes the
+  notification which was previously registered.
+
+  @param This               A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
+
+  @param NotificationHandle The handle of the notification
+                            function being unregistered.
+
+  @retval EFI_SUCCESS The device state was set appropriately.
+
+  @retval EFI_INVALID_PARAMETER The NotificationHandle is
+                                invalid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UNREGISTER_KEYSTROKE_NOTIFY)(
+  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,
+  IN VOID                               *NotificationHandle
+);
+
+
+///
+/// The EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL is used on the ConsoleIn
+/// device. It is an extension to the Simple Text Input protocol
+/// which allows a variety of extended shift state information to be
+/// returned.
+///
+struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL{
+  EFI_INPUT_RESET_EX              Reset;
+  EFI_INPUT_READ_KEY_EX           ReadKeyStrokeEx;
+  ///
+  /// Event to use with WaitForEvent() to wait for a key to be available.
+  ///
+  EFI_EVENT                       WaitForKeyEx;
+  EFI_SET_STATE                   SetState;
+  EFI_REGISTER_KEYSTROKE_NOTIFY   RegisterKeyNotify;
+  EFI_UNREGISTER_KEYSTROKE_NOTIFY UnregisterKeyNotify;
+};
+
+
+extern EFI_GUID gEfiSimpleTextInputExProtocolGuid;
+
+#endif
+
diff --git a/wimboot/wimboot-2.7.3/src/efi/Protocol/SimpleTextOut.h b/wimboot/wimboot-2.7.3/src/efi/Protocol/SimpleTextOut.h
new file mode 100644 (file)
index 0000000..7e1c70c
--- /dev/null
@@ -0,0 +1,404 @@
+/** @file
+  Simple Text Out protocol from the UEFI 2.0 specification.
+
+  Abstraction of a very simple text based output device like VGA text mode or
+  a serial terminal. The Simple Text Out protocol instance can represent
+  a single hardware device or a virtual device that is an aggregation
+  of multiple physical devices.
+
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __SIMPLE_TEXT_OUT_H__
+#define __SIMPLE_TEXT_OUT_H__
+
+#define EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID \
+  { \
+    0x387477c2, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+///
+/// Protocol GUID defined in EFI1.1.
+///
+#define SIMPLE_TEXT_OUTPUT_PROTOCOL   EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID
+
+typedef struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
+
+///
+/// Backward-compatible with EFI1.1.
+///
+typedef EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   SIMPLE_TEXT_OUTPUT_INTERFACE;
+
+//
+// Define's for required EFI Unicode Box Draw characters
+//
+#define BOXDRAW_HORIZONTAL                  0x2500
+#define BOXDRAW_VERTICAL                    0x2502
+#define BOXDRAW_DOWN_RIGHT                  0x250c
+#define BOXDRAW_DOWN_LEFT                   0x2510
+#define BOXDRAW_UP_RIGHT                    0x2514
+#define BOXDRAW_UP_LEFT                     0x2518
+#define BOXDRAW_VERTICAL_RIGHT              0x251c
+#define BOXDRAW_VERTICAL_LEFT               0x2524
+#define BOXDRAW_DOWN_HORIZONTAL             0x252c
+#define BOXDRAW_UP_HORIZONTAL               0x2534
+#define BOXDRAW_VERTICAL_HORIZONTAL         0x253c
+#define BOXDRAW_DOUBLE_HORIZONTAL           0x2550
+#define BOXDRAW_DOUBLE_VERTICAL             0x2551
+#define BOXDRAW_DOWN_RIGHT_DOUBLE           0x2552
+#define BOXDRAW_DOWN_DOUBLE_RIGHT           0x2553
+#define BOXDRAW_DOUBLE_DOWN_RIGHT           0x2554
+#define BOXDRAW_DOWN_LEFT_DOUBLE            0x2555
+#define BOXDRAW_DOWN_DOUBLE_LEFT            0x2556
+#define BOXDRAW_DOUBLE_DOWN_LEFT            0x2557
+#define BOXDRAW_UP_RIGHT_DOUBLE             0x2558
+#define BOXDRAW_UP_DOUBLE_RIGHT             0x2559
+#define BOXDRAW_DOUBLE_UP_RIGHT             0x255a
+#define BOXDRAW_UP_LEFT_DOUBLE              0x255b
+#define BOXDRAW_UP_DOUBLE_LEFT              0x255c
+#define BOXDRAW_DOUBLE_UP_LEFT              0x255d
+#define BOXDRAW_VERTICAL_RIGHT_DOUBLE       0x255e
+#define BOXDRAW_VERTICAL_DOUBLE_RIGHT       0x255f
+#define BOXDRAW_DOUBLE_VERTICAL_RIGHT       0x2560
+#define BOXDRAW_VERTICAL_LEFT_DOUBLE        0x2561
+#define BOXDRAW_VERTICAL_DOUBLE_LEFT        0x2562
+#define BOXDRAW_DOUBLE_VERTICAL_LEFT        0x2563
+#define BOXDRAW_DOWN_HORIZONTAL_DOUBLE      0x2564
+#define BOXDRAW_DOWN_DOUBLE_HORIZONTAL      0x2565
+#define BOXDRAW_DOUBLE_DOWN_HORIZONTAL      0x2566
+#define BOXDRAW_UP_HORIZONTAL_DOUBLE        0x2567
+#define BOXDRAW_UP_DOUBLE_HORIZONTAL        0x2568
+#define BOXDRAW_DOUBLE_UP_HORIZONTAL        0x2569
+#define BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE  0x256a
+#define BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL  0x256b
+#define BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL  0x256c
+
+//
+// EFI Required Block Elements Code Chart
+//
+#define BLOCKELEMENT_FULL_BLOCK   0x2588
+#define BLOCKELEMENT_LIGHT_SHADE  0x2591
+
+//
+// EFI Required Geometric Shapes Code Chart
+//
+#define GEOMETRICSHAPE_UP_TRIANGLE    0x25b2
+#define GEOMETRICSHAPE_RIGHT_TRIANGLE 0x25ba
+#define GEOMETRICSHAPE_DOWN_TRIANGLE  0x25bc
+#define GEOMETRICSHAPE_LEFT_TRIANGLE  0x25c4
+
+//
+// EFI Required Arrow shapes
+//
+#define ARROW_LEFT  0x2190
+#define ARROW_UP    0x2191
+#define ARROW_RIGHT 0x2192
+#define ARROW_DOWN  0x2193
+
+//
+// EFI Console Colours
+//
+#define EFI_BLACK                 0x00
+#define EFI_BLUE                  0x01
+#define EFI_GREEN                 0x02
+#define EFI_CYAN                  (EFI_BLUE | EFI_GREEN)
+#define EFI_RED                   0x04
+#define EFI_MAGENTA               (EFI_BLUE | EFI_RED)
+#define EFI_BROWN                 (EFI_GREEN | EFI_RED)
+#define EFI_LIGHTGRAY             (EFI_BLUE | EFI_GREEN | EFI_RED)
+#define EFI_BRIGHT                0x08
+#define EFI_DARKGRAY              (EFI_BRIGHT)
+#define EFI_LIGHTBLUE             (EFI_BLUE | EFI_BRIGHT)
+#define EFI_LIGHTGREEN            (EFI_GREEN | EFI_BRIGHT)
+#define EFI_LIGHTCYAN             (EFI_CYAN | EFI_BRIGHT)
+#define EFI_LIGHTRED              (EFI_RED | EFI_BRIGHT)
+#define EFI_LIGHTMAGENTA          (EFI_MAGENTA | EFI_BRIGHT)
+#define EFI_YELLOW                (EFI_BROWN | EFI_BRIGHT)
+#define EFI_WHITE                 (EFI_BLUE | EFI_GREEN | EFI_RED | EFI_BRIGHT)
+
+#define EFI_TEXT_ATTR(f, b)       ((f) | ((b) << 4))
+
+#define EFI_BACKGROUND_BLACK      0x00
+#define EFI_BACKGROUND_BLUE       0x10
+#define EFI_BACKGROUND_GREEN      0x20
+#define EFI_BACKGROUND_CYAN       (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN)
+#define EFI_BACKGROUND_RED        0x40
+#define EFI_BACKGROUND_MAGENTA    (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_RED)
+#define EFI_BACKGROUND_BROWN      (EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED)
+#define EFI_BACKGROUND_LIGHTGRAY  (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED)
+
+//
+// We currently define attributes from 0 - 7F for color manipulations
+// To internally handle the local display characteristics for a particular character,
+// Bit 7 signifies the local glyph representation for a character.  If turned on, glyphs will be
+// pulled from the wide glyph database and will display locally as a wide character (16 X 19 versus 8 X 19)
+// If bit 7 is off, the narrow glyph database will be used.  This does NOT affect information that is sent to
+// non-local displays, such as serial or LAN consoles.
+//
+#define EFI_WIDE_ATTRIBUTE  0x80
+
+/**
+  Reset the text output device hardware and optionaly run diagnostics
+
+  @param  This                 The protocol instance pointer.
+  @param  ExtendedVerification Driver may perform more exhaustive verfication
+                               operation of the device during reset.
+
+  @retval EFI_SUCCESS          The text output device was reset.
+  @retval EFI_DEVICE_ERROR     The text output device is not functioning correctly and
+                               could not be reset.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_RESET)(
+  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL        *This,
+  IN BOOLEAN                                ExtendedVerification
+  );
+
+/**
+  Write a string to the output device.
+
+  @param  This   The protocol instance pointer.
+  @param  String The NULL-terminated string to be displayed on the output
+                 device(s). All output devices must also support the Unicode
+                 drawing character codes defined in this file.
+
+  @retval EFI_SUCCESS             The string was output to the device.
+  @retval EFI_DEVICE_ERROR        The device reported an error while attempting to output
+                                  the text.
+  @retval EFI_UNSUPPORTED         The output device's mode is not currently in a
+                                  defined text mode.
+  @retval EFI_WARN_UNKNOWN_GLYPH  This warning code indicates that some of the
+                                  characters in the string could not be
+                                  rendered and were skipped.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_STRING)(
+  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL        *This,
+  IN CHAR16                                 *String
+  );
+
+/**
+  Verifies that all characters in a string can be output to the
+  target device.
+
+  @param  This   The protocol instance pointer.
+  @param  String The NULL-terminated string to be examined for the output
+                 device(s).
+
+  @retval EFI_SUCCESS      The device(s) are capable of rendering the output string.
+  @retval EFI_UNSUPPORTED  Some of the characters in the string cannot be
+                           rendered by one or more of the output devices mapped
+                           by the EFI handle.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_TEST_STRING)(
+  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL        *This,
+  IN CHAR16                                 *String
+  );
+
+/**
+  Returns information for an available text mode that the output device(s)
+  supports.
+
+  @param  This       The protocol instance pointer.
+  @param  ModeNumber The mode number to return information on.
+  @param  Columns    Returns the geometry of the text output device for the
+                     requested ModeNumber.
+  @param  Rows       Returns the geometry of the text output device for the
+                     requested ModeNumber.
+
+  @retval EFI_SUCCESS      The requested mode information was returned.
+  @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
+  @retval EFI_UNSUPPORTED  The mode number was not valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_QUERY_MODE)(
+  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL        *This,
+  IN UINTN                                  ModeNumber,
+  OUT UINTN                                 *Columns,
+  OUT UINTN                                 *Rows
+  );
+
+/**
+  Sets the output device(s) to a specified mode.
+
+  @param  This       The protocol instance pointer.
+  @param  ModeNumber The mode number to set.
+
+  @retval EFI_SUCCESS      The requested text mode was set.
+  @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
+  @retval EFI_UNSUPPORTED  The mode number was not valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_SET_MODE)(
+  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL        *This,
+  IN UINTN                                  ModeNumber
+  );
+
+/**
+  Sets the background and foreground colors for the OutputString () and
+  ClearScreen () functions.
+
+  @param  This      The protocol instance pointer.
+  @param  Attribute The attribute to set. Bits 0..3 are the foreground color, and
+                    bits 4..6 are the background color. All other bits are undefined
+                    and must be zero. The valid Attributes are defined in this file.
+
+  @retval EFI_SUCCESS       The attribute was set.
+  @retval EFI_DEVICE_ERROR  The device had an error and could not complete the request.
+  @retval EFI_UNSUPPORTED   The attribute requested is not defined.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_SET_ATTRIBUTE)(
+  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL        *This,
+  IN UINTN                                  Attribute
+  );
+
+/**
+  Clears the output device(s) display to the currently selected background
+  color.
+
+  @param  This              The protocol instance pointer.
+
+  @retval  EFI_SUCCESS      The operation completed successfully.
+  @retval  EFI_DEVICE_ERROR The device had an error and could not complete the request.
+  @retval  EFI_UNSUPPORTED  The output device is not in a valid text mode.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_CLEAR_SCREEN)(
+  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   *This
+  );
+
+/**
+  Sets the current coordinates of the cursor position
+
+  @param  This        The protocol instance pointer.
+  @param  Column      The position to set the cursor to. Must be greater than or
+                      equal to zero and less than the number of columns and rows
+                      by QueryMode ().
+  @param  Row         The position to set the cursor to. Must be greater than or
+                      equal to zero and less than the number of columns and rows
+                      by QueryMode ().
+
+  @retval EFI_SUCCESS      The operation completed successfully.
+  @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
+  @retval EFI_UNSUPPORTED  The output device is not in a valid text mode, or the
+                           cursor position is invalid for the current mode.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_SET_CURSOR_POSITION)(
+  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL        *This,
+  IN UINTN                                  Column,
+  IN UINTN                                  Row
+  );
+
+/**
+  Makes the cursor visible or invisible
+
+  @param  This    The protocol instance pointer.
+  @param  Visible If TRUE, the cursor is set to be visible. If FALSE, the cursor is
+                  set to be invisible.
+
+  @retval EFI_SUCCESS      The operation completed successfully.
+  @retval EFI_DEVICE_ERROR The device had an error and could not complete the
+                           request, or the device does not support changing
+                           the cursor mode.
+  @retval EFI_UNSUPPORTED  The output device is not in a valid text mode.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TEXT_ENABLE_CURSOR)(
+  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL        *This,
+  IN BOOLEAN                                Visible
+  );
+
+/**
+  @par Data Structure Description:
+  Mode Structure pointed to by Simple Text Out protocol.
+**/
+typedef struct {
+  ///
+  /// The number of modes supported by QueryMode () and SetMode ().
+  ///
+  INT32   MaxMode;
+
+  //
+  // current settings
+  //
+
+  ///
+  /// The text mode of the output device(s).
+  ///
+  INT32   Mode;
+  ///
+  /// The current character output attribute.
+  ///
+  INT32   Attribute;
+  ///
+  /// The cursor's column.
+  ///
+  INT32   CursorColumn;
+  ///
+  /// The cursor's row.
+  ///
+  INT32   CursorRow;
+  ///
+  /// The cursor is currently visbile or not.
+  ///
+  BOOLEAN CursorVisible;
+} EFI_SIMPLE_TEXT_OUTPUT_MODE;
+
+///
+/// The SIMPLE_TEXT_OUTPUT protocol is used to control text-based output devices.
+/// It is the minimum required protocol for any handle supplied as the ConsoleOut
+/// or StandardError device. In addition, the minimum supported text mode of such
+/// devices is at least 80 x 25 characters.
+///
+struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {
+  EFI_TEXT_RESET                Reset;
+
+  EFI_TEXT_STRING               OutputString;
+  EFI_TEXT_TEST_STRING          TestString;
+
+  EFI_TEXT_QUERY_MODE           QueryMode;
+  EFI_TEXT_SET_MODE             SetMode;
+  EFI_TEXT_SET_ATTRIBUTE        SetAttribute;
+
+  EFI_TEXT_CLEAR_SCREEN         ClearScreen;
+  EFI_TEXT_SET_CURSOR_POSITION  SetCursorPosition;
+  EFI_TEXT_ENABLE_CURSOR        EnableCursor;
+
+  ///
+  /// Pointer to SIMPLE_TEXT_OUTPUT_MODE data.
+  ///
+  EFI_SIMPLE_TEXT_OUTPUT_MODE   *Mode;
+};
+
+extern EFI_GUID gEfiSimpleTextOutProtocolGuid;
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/Uefi.h b/wimboot/wimboot-2.7.3/src/efi/Uefi.h
new file mode 100644 (file)
index 0000000..326b4ac
--- /dev/null
@@ -0,0 +1,27 @@
+/** @file
+
+  Root include file for Mde Package UEFI, UEFI_APPLICATION type modules.
+
+  This is the include file for any module of type UEFI and UEFI_APPLICATION. Uefi modules only use
+  types defined via this include file and can be ported easily to any
+  environment.
+
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __PI_UEFI_H__
+#define __PI_UEFI_H__
+
+#include "efi/Uefi/UefiBaseType.h"
+#include "efi/Uefi/UefiSpec.h"
+
+#endif
+
diff --git a/wimboot/wimboot-2.7.3/src/efi/Uefi/UefiBaseType.h b/wimboot/wimboot-2.7.3/src/efi/Uefi/UefiBaseType.h
new file mode 100644 (file)
index 0000000..fabf72e
--- /dev/null
@@ -0,0 +1,301 @@
+/** @file
+  Defines data types and constants introduced in UEFI.
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __UEFI_BASETYPE_H__
+#define __UEFI_BASETYPE_H__
+
+#include "efi/Base.h"
+
+//
+// Basic data type definitions introduced in UEFI.
+//
+
+///
+/// 128-bit buffer containing a unique identifier value.
+///
+typedef GUID                      EFI_GUID;
+///
+/// Function return status for EFI API.
+///
+typedef RETURN_STATUS             EFI_STATUS;
+///
+/// A collection of related interfaces.
+///
+typedef VOID                      *EFI_HANDLE;
+///
+/// Handle to an event structure.
+///
+typedef VOID                      *EFI_EVENT;
+///
+/// Task priority level.
+///
+typedef UINTN                     EFI_TPL;
+///
+/// Logical block address.
+///
+typedef UINT64                    EFI_LBA;
+
+///
+/// 64-bit physical memory address.
+///
+typedef UINT64                    EFI_PHYSICAL_ADDRESS;
+
+///
+/// 64-bit virtual memory address.
+///
+typedef UINT64                    EFI_VIRTUAL_ADDRESS;
+
+///
+/// EFI Time Abstraction:
+///  Year:       1900 - 9999
+///  Month:      1 - 12
+///  Day:        1 - 31
+///  Hour:       0 - 23
+///  Minute:     0 - 59
+///  Second:     0 - 59
+///  Nanosecond: 0 - 999,999,999
+///  TimeZone:   -1440 to 1440 or 2047
+///
+typedef struct {
+  UINT16  Year;
+  UINT8   Month;
+  UINT8   Day;
+  UINT8   Hour;
+  UINT8   Minute;
+  UINT8   Second;
+  UINT8   Pad1;
+  UINT32  Nanosecond;
+  INT16   TimeZone;
+  UINT8   Daylight;
+  UINT8   Pad2;
+} EFI_TIME;
+
+
+///
+/// 4-byte buffer. An IPv4 internet protocol address.
+///
+typedef struct {
+  UINT8 Addr[4];
+} EFI_IPv4_ADDRESS;
+
+///
+/// 16-byte buffer. An IPv6 internet protocol address.
+///
+typedef struct {
+  UINT8 Addr[16];
+} EFI_IPv6_ADDRESS;
+
+///
+/// 32-byte buffer containing a network Media Access Control address.
+///
+typedef struct {
+  UINT8 Addr[32];
+} EFI_MAC_ADDRESS;
+
+///
+/// 16-byte buffer aligned on a 4-byte boundary.
+/// An IPv4 or IPv6 internet protocol address.
+///
+typedef union {
+  UINT32            Addr[4];
+  EFI_IPv4_ADDRESS  v4;
+  EFI_IPv6_ADDRESS  v6;
+} EFI_IP_ADDRESS;
+
+
+///
+/// Enumeration of EFI_STATUS.
+///@{
+#define EFI_SUCCESS               RETURN_SUCCESS
+#define EFI_LOAD_ERROR            RETURN_LOAD_ERROR
+#define EFI_INVALID_PARAMETER     RETURN_INVALID_PARAMETER
+#define EFI_UNSUPPORTED           RETURN_UNSUPPORTED
+#define EFI_BAD_BUFFER_SIZE       RETURN_BAD_BUFFER_SIZE
+#define EFI_BUFFER_TOO_SMALL      RETURN_BUFFER_TOO_SMALL
+#define EFI_NOT_READY             RETURN_NOT_READY
+#define EFI_DEVICE_ERROR          RETURN_DEVICE_ERROR
+#define EFI_WRITE_PROTECTED       RETURN_WRITE_PROTECTED
+#define EFI_OUT_OF_RESOURCES      RETURN_OUT_OF_RESOURCES
+#define EFI_VOLUME_CORRUPTED      RETURN_VOLUME_CORRUPTED
+#define EFI_VOLUME_FULL           RETURN_VOLUME_FULL
+#define EFI_NO_MEDIA              RETURN_NO_MEDIA
+#define EFI_MEDIA_CHANGED         RETURN_MEDIA_CHANGED
+#define EFI_NOT_FOUND             RETURN_NOT_FOUND
+#define EFI_ACCESS_DENIED         RETURN_ACCESS_DENIED
+#define EFI_NO_RESPONSE           RETURN_NO_RESPONSE
+#define EFI_NO_MAPPING            RETURN_NO_MAPPING
+#define EFI_TIMEOUT               RETURN_TIMEOUT
+#define EFI_NOT_STARTED           RETURN_NOT_STARTED
+#define EFI_ALREADY_STARTED       RETURN_ALREADY_STARTED
+#define EFI_ABORTED               RETURN_ABORTED
+#define EFI_ICMP_ERROR            RETURN_ICMP_ERROR
+#define EFI_TFTP_ERROR            RETURN_TFTP_ERROR
+#define EFI_PROTOCOL_ERROR        RETURN_PROTOCOL_ERROR
+#define EFI_INCOMPATIBLE_VERSION  RETURN_INCOMPATIBLE_VERSION
+#define EFI_SECURITY_VIOLATION    RETURN_SECURITY_VIOLATION
+#define EFI_CRC_ERROR             RETURN_CRC_ERROR
+#define EFI_END_OF_MEDIA          RETURN_END_OF_MEDIA
+#define EFI_END_OF_FILE           RETURN_END_OF_FILE
+#define EFI_INVALID_LANGUAGE      RETURN_INVALID_LANGUAGE
+#define EFI_COMPROMISED_DATA      RETURN_COMPROMISED_DATA
+
+#define EFI_WARN_UNKNOWN_GLYPH    RETURN_WARN_UNKNOWN_GLYPH
+#define EFI_WARN_DELETE_FAILURE   RETURN_WARN_DELETE_FAILURE
+#define EFI_WARN_WRITE_FAILURE    RETURN_WARN_WRITE_FAILURE
+#define EFI_WARN_BUFFER_TOO_SMALL RETURN_WARN_BUFFER_TOO_SMALL
+#define EFI_WARN_STALE_DATA       RETURN_WARN_STALE_DATA
+///@}
+
+///
+/// Define macro to encode the status code.
+///
+#define EFIERR(_a)                ENCODE_ERROR(_a)
+
+#define EFI_ERROR(A)              RETURN_ERROR(A)
+
+///
+/// ICMP error definitions
+///@{
+#define EFI_NETWORK_UNREACHABLE   EFIERR(100)
+#define EFI_HOST_UNREACHABLE      EFIERR(101)
+#define EFI_PROTOCOL_UNREACHABLE  EFIERR(102)
+#define EFI_PORT_UNREACHABLE      EFIERR(103)
+///@}
+
+///
+/// Tcp connection status definitions
+///@{
+#define EFI_CONNECTION_FIN        EFIERR(104)
+#define EFI_CONNECTION_RESET      EFIERR(105)
+#define EFI_CONNECTION_REFUSED    EFIERR(106)
+///@}
+
+//
+// The EFI memory allocation functions work in units of EFI_PAGEs that are
+// 4KB. This should in no way be confused with the page size of the processor.
+// An EFI_PAGE is just the quanta of memory in EFI.
+//
+#define EFI_PAGE_SIZE             SIZE_4KB
+#define EFI_PAGE_MASK             0xFFF
+#define EFI_PAGE_SHIFT            12
+
+/**
+  Macro that converts a size, in bytes, to a number of EFI_PAGESs.
+
+  @param  Size      A size in bytes.  This parameter is assumed to be type UINTN.
+                    Passing in a parameter that is larger than UINTN may produce
+                    unexpected results.
+
+  @return  The number of EFI_PAGESs associated with the number of bytes specified
+           by Size.
+
+**/
+#define EFI_SIZE_TO_PAGES(Size)  (((Size) >> EFI_PAGE_SHIFT) + (((Size) & EFI_PAGE_MASK) ? 1 : 0))
+
+/**
+  Macro that converts a number of EFI_PAGEs to a size in bytes.
+
+  @param  Pages     The number of EFI_PAGES.  This parameter is assumed to be
+                    type UINTN.  Passing in a parameter that is larger than
+                    UINTN may produce unexpected results.
+
+  @return  The number of bytes associated with the number of EFI_PAGEs specified
+           by Pages.
+
+**/
+#define EFI_PAGES_TO_SIZE(Pages)  ((Pages) << EFI_PAGE_SHIFT)
+
+///
+/// PE32+ Machine type for IA32 UEFI images.
+///
+#define EFI_IMAGE_MACHINE_IA32            0x014C
+
+///
+/// PE32+ Machine type for IA64 UEFI images.
+///
+#define EFI_IMAGE_MACHINE_IA64            0x0200
+
+///
+/// PE32+ Machine type for EBC UEFI images.
+///
+#define EFI_IMAGE_MACHINE_EBC             0x0EBC
+
+///
+/// PE32+ Machine type for X64 UEFI images.
+///
+#define EFI_IMAGE_MACHINE_X64             0x8664
+
+///
+/// PE32+ Machine type for ARM mixed ARM and Thumb/Thumb2 images.
+///
+#define EFI_IMAGE_MACHINE_ARMTHUMB_MIXED  0x01C2
+
+///
+/// PE32+ Machine type for AARCH64 A64 images.
+///
+#define EFI_IMAGE_MACHINE_AARCH64  0xAA64
+
+
+#if   defined (MDE_CPU_IA32)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+  (((Machine) == EFI_IMAGE_MACHINE_IA32) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_X64)
+
+#elif defined (MDE_CPU_IPF)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+  (((Machine) == EFI_IMAGE_MACHINE_IA64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE)
+
+#elif defined (MDE_CPU_X64)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+  (((Machine) == EFI_IMAGE_MACHINE_X64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_IA32)
+
+#elif defined (MDE_CPU_ARM)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+  (((Machine) == EFI_IMAGE_MACHINE_ARMTHUMB_MIXED) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_ARMTHUMB_MIXED)
+
+#elif defined (MDE_CPU_AARCH64)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+  (((Machine) == EFI_IMAGE_MACHINE_AARCH64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE)
+
+#elif defined (MDE_CPU_EBC)
+
+///
+/// This is just to make sure you can cross compile with the EBC compiler.
+/// It does not make sense to have a PE loader coded in EBC.
+///
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_EBC)
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE)
+
+#else
+#error Unknown Processor Type
+#endif
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/Uefi/UefiGpt.h b/wimboot/wimboot-2.7.3/src/efi/Uefi/UefiGpt.h
new file mode 100644 (file)
index 0000000..5aa2ee2
--- /dev/null
@@ -0,0 +1,141 @@
+/** @file
+  EFI Guid Partition Table Format Definition.
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __UEFI_GPT_H__
+#define __UEFI_GPT_H__
+
+///
+/// The primary GUID Partition Table Header must be
+/// located in LBA 1 (i.e., the second logical block).
+///
+#define PRIMARY_PART_HEADER_LBA 1
+///
+/// EFI Partition Table Signature: "EFI PART".
+///
+#define EFI_PTAB_HEADER_ID      SIGNATURE_64 ('E','F','I',' ','P','A','R','T')
+
+#pragma pack(1)
+
+///
+/// GPT Partition Table Header.
+///
+typedef struct {
+  ///
+  /// The table header for the GPT partition Table.
+  /// This header contains EFI_PTAB_HEADER_ID.
+  ///
+  EFI_TABLE_HEADER  Header;
+  ///
+  /// The LBA that contains this data structure.
+  ///
+  EFI_LBA           MyLBA;
+  ///
+  /// LBA address of the alternate GUID Partition Table Header.
+  ///
+  EFI_LBA           AlternateLBA;
+  ///
+  /// The first usable logical block that may be used
+  /// by a partition described by a GUID Partition Entry.
+  ///
+  EFI_LBA           FirstUsableLBA;
+  ///
+  /// The last usable logical block that may be used
+  /// by a partition described by a GUID Partition Entry.
+  ///
+  EFI_LBA           LastUsableLBA;
+  ///
+  /// GUID that can be used to uniquely identify the disk.
+  ///
+  EFI_GUID          DiskGUID;
+  ///
+  /// The starting LBA of the GUID Partition Entry array.
+  ///
+  EFI_LBA           PartitionEntryLBA;
+  ///
+  /// The number of Partition Entries in the GUID Partition Entry array.
+  ///
+  UINT32            NumberOfPartitionEntries;
+  ///
+  /// The size, in bytes, of each the GUID Partition
+  /// Entry structures in the GUID Partition Entry
+  /// array. This field shall be set to a value of 128 x 2^n where n is
+  /// an integer greater than or equal to zero (e.g., 128, 256, 512, etc.).
+  ///
+  UINT32            SizeOfPartitionEntry;
+  ///
+  /// The CRC32 of the GUID Partition Entry array.
+  /// Starts at PartitionEntryLBA and is
+  /// computed over a byte length of
+  /// NumberOfPartitionEntries * SizeOfPartitionEntry.
+  ///
+  UINT32            PartitionEntryArrayCRC32;
+} EFI_PARTITION_TABLE_HEADER;
+
+///
+/// GPT Partition Entry.
+///
+typedef struct {
+  ///
+  /// Unique ID that defines the purpose and type of this Partition. A value of
+  /// zero defines that this partition entry is not being used.
+  ///
+  EFI_GUID  PartitionTypeGUID;
+  ///
+  /// GUID that is unique for every partition entry. Every partition ever
+  /// created will have a unique GUID.
+  /// This GUID must be assigned when the GUID Partition Entry is created.
+  ///
+  EFI_GUID  UniquePartitionGUID;
+  ///
+  /// Starting LBA of the partition defined by this entry
+  ///
+  EFI_LBA   StartingLBA;
+  ///
+  /// Ending LBA of the partition defined by this entry.
+  ///
+  EFI_LBA   EndingLBA;
+  ///
+  /// Attribute bits, all bits reserved by UEFI
+  /// Bit 0:      If this bit is set, the partition is required for the platform to function. The owner/creator of the
+  ///             partition indicates that deletion or modification of the contents can result in loss of platform
+  ///             features or failure for the platform to boot or operate. The system cannot function normally if
+  ///             this partition is removed, and it should be considered part of the hardware of the system.
+  ///             Actions such as running diagnostics, system recovery, or even OS install or boot, could
+  ///             potentially stop working if this partition is removed. Unless OS software or firmware
+  ///             recognizes this partition, it should never be removed or modified as the UEFI firmware or
+  ///             platform hardware may become non-functional.
+  /// Bit 1:      If this bit is set, then firmware must not produce an EFI_BLOCK_IO_PROTOCOL device for
+  ///             this partition. By not producing an EFI_BLOCK_IO_PROTOCOL partition, file system
+  ///             mappings will not be created for this partition in UEFI.
+  /// Bit 2:      This bit is set aside to let systems with traditional PC-AT BIOS firmware implementations
+  ///             inform certain limited, special-purpose software running on these systems that a GPT
+  ///             partition may be bootable. The UEFI boot manager must ignore this bit when selecting
+  ///             a UEFI-compliant application, e.g., an OS loader.
+  /// Bits 3-47:  Undefined and must be zero. Reserved for expansion by future versions of the UEFI
+  ///             specification.
+  /// Bits 48-63: Reserved for GUID specific use. The use of these bits will vary depending on the
+  ///             PartitionTypeGUID. Only the owner of the PartitionTypeGUID is allowed
+  ///             to modify these bits. They must be preserved if Bits 0-47 are modified..
+  ///
+  UINT64    Attributes;
+  ///
+  /// Null-terminated name of the partition.
+  ///
+  CHAR16    PartitionName[36];
+} EFI_PARTITION_ENTRY;
+
+#pragma pack()
+#endif
+
+
diff --git a/wimboot/wimboot-2.7.3/src/efi/Uefi/UefiInternalFormRepresentation.h b/wimboot/wimboot-2.7.3/src/efi/Uefi/UefiInternalFormRepresentation.h
new file mode 100644 (file)
index 0000000..790555e
--- /dev/null
@@ -0,0 +1,2106 @@
+/** @file
+  This file defines the encoding for the VFR (Visual Form Representation) language.
+  IFR is primarily consumed by the EFI presentation engine, and produced by EFI
+  internal application and drivers as well as all add-in card option-ROM drivers
+
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+  @par Revision Reference:
+  These definitions are from UEFI 2.1 and 2.2.
+
+**/
+
+#ifndef __UEFI_INTERNAL_FORMREPRESENTATION_H__
+#define __UEFI_INTERNAL_FORMREPRESENTATION_H__
+
+#include "efi/Guid/HiiFormMapMethodGuid.h"
+
+///
+/// The following types are currently defined:
+///
+typedef VOID*   EFI_HII_HANDLE;
+typedef CHAR16* EFI_STRING;
+typedef UINT16  EFI_IMAGE_ID;
+typedef UINT16  EFI_QUESTION_ID;
+typedef UINT16  EFI_STRING_ID;
+typedef UINT16  EFI_FORM_ID;
+typedef UINT16  EFI_VARSTORE_ID;
+typedef UINT16  EFI_ANIMATION_ID;
+
+typedef UINT16  EFI_DEFAULT_ID;
+
+typedef UINT32  EFI_HII_FONT_STYLE;
+
+
+
+#pragma pack(1)
+
+//
+// Definitions for Package Lists and Package Headers
+// Section 27.3.1
+//
+
+///
+/// The header found at the start of each package list.
+///
+typedef struct {
+  EFI_GUID               PackageListGuid;
+  UINT32                 PackageLength;
+} EFI_HII_PACKAGE_LIST_HEADER;
+
+///
+/// The header found at the start of each package.
+///
+typedef struct {
+  UINT32  Length:24;
+  UINT32  Type:8;
+  // UINT8  Data[...];
+} EFI_HII_PACKAGE_HEADER;
+
+//
+// Value of HII package type
+//
+#define EFI_HII_PACKAGE_TYPE_ALL             0x00
+#define EFI_HII_PACKAGE_TYPE_GUID            0x01
+#define EFI_HII_PACKAGE_FORMS                0x02
+#define EFI_HII_PACKAGE_STRINGS              0x04
+#define EFI_HII_PACKAGE_FONTS                0x05
+#define EFI_HII_PACKAGE_IMAGES               0x06
+#define EFI_HII_PACKAGE_SIMPLE_FONTS         0x07
+#define EFI_HII_PACKAGE_DEVICE_PATH          0x08
+#define EFI_HII_PACKAGE_KEYBOARD_LAYOUT      0x09
+#define EFI_HII_PACKAGE_ANIMATIONS           0x0A
+#define EFI_HII_PACKAGE_END                  0xDF
+#define EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN    0xE0
+#define EFI_HII_PACKAGE_TYPE_SYSTEM_END      0xFF
+
+//
+// Definitions for Simplified Font Package
+//
+
+///
+/// Contents of EFI_NARROW_GLYPH.Attributes.
+///@{
+#define EFI_GLYPH_NON_SPACING                0x01
+#define EFI_GLYPH_WIDE                       0x02
+#define EFI_GLYPH_HEIGHT                     19
+#define EFI_GLYPH_WIDTH                      8
+///@}
+
+///
+/// The EFI_NARROW_GLYPH has a preferred dimension (w x h) of 8 x 19 pixels.
+///
+typedef struct {
+  ///
+  /// The Unicode representation of the glyph. The term weight is the
+  /// technical term for a character code.
+  ///
+  CHAR16                 UnicodeWeight;
+  ///
+  /// The data element containing the glyph definitions.
+  ///
+  UINT8                  Attributes;
+  ///
+  /// The column major glyph representation of the character. Bits
+  /// with values of one indicate that the corresponding pixel is to be
+  /// on when normally displayed; those with zero are off.
+  ///
+  UINT8                  GlyphCol1[EFI_GLYPH_HEIGHT];
+} EFI_NARROW_GLYPH;
+
+///
+/// The EFI_WIDE_GLYPH has a preferred dimension (w x h) of 16 x 19 pixels, which is large enough
+/// to accommodate logographic characters.
+///
+typedef struct {
+  ///
+  /// The Unicode representation of the glyph. The term weight is the
+  /// technical term for a character code.
+  ///
+  CHAR16                 UnicodeWeight;
+  ///
+  /// The data element containing the glyph definitions.
+  ///
+  UINT8                  Attributes;
+  ///
+  /// The column major glyph representation of the character. Bits
+  /// with values of one indicate that the corresponding pixel is to be
+  /// on when normally displayed; those with zero are off.
+  ///
+  UINT8                  GlyphCol1[EFI_GLYPH_HEIGHT];
+  ///
+  /// The column major glyph representation of the character. Bits
+  /// with values of one indicate that the corresponding pixel is to be
+  /// on when normally displayed; those with zero are off.
+  ///
+  UINT8                  GlyphCol2[EFI_GLYPH_HEIGHT];
+  ///
+  /// Ensures that sizeof (EFI_WIDE_GLYPH) is twice the
+  /// sizeof (EFI_NARROW_GLYPH). The contents of Pad must
+  /// be zero.
+  ///
+  UINT8                  Pad[3];
+} EFI_WIDE_GLYPH;
+
+///
+/// A simplified font package consists of a font header
+/// followed by a series of glyph structures.
+///
+typedef struct _EFI_HII_SIMPLE_FONT_PACKAGE_HDR {
+  EFI_HII_PACKAGE_HEADER Header;
+  UINT16                 NumberOfNarrowGlyphs;
+  UINT16                 NumberOfWideGlyphs;
+  // EFI_NARROW_GLYPH       NarrowGlyphs[];
+  // EFI_WIDE_GLYPH         WideGlyphs[];
+} EFI_HII_SIMPLE_FONT_PACKAGE_HDR;
+
+//
+// Definitions for Font Package
+// Section 27.3.3
+//
+
+//
+// Value for font style
+//
+#define EFI_HII_FONT_STYLE_NORMAL            0x00000000
+#define EFI_HII_FONT_STYLE_BOLD              0x00000001
+#define EFI_HII_FONT_STYLE_ITALIC            0x00000002
+#define EFI_HII_FONT_STYLE_EMBOSS            0x00010000
+#define EFI_HII_FONT_STYLE_OUTLINE           0x00020000
+#define EFI_HII_FONT_STYLE_SHADOW            0x00040000
+#define EFI_HII_FONT_STYLE_UNDERLINE         0x00080000
+#define EFI_HII_FONT_STYLE_DBL_UNDER         0x00100000
+
+typedef struct _EFI_HII_GLYPH_INFO {
+  UINT16                 Width;
+  UINT16                 Height;
+  INT16                  OffsetX;
+  INT16                  OffsetY;
+  INT16                  AdvanceX;
+} EFI_HII_GLYPH_INFO;
+
+///
+/// The fixed header consists of a standard record header,
+/// then the character values in this section, the flags
+/// (including the encoding method) and the offsets of the glyph
+/// information, the glyph bitmaps and the character map.
+///
+typedef struct _EFI_HII_FONT_PACKAGE_HDR {
+  EFI_HII_PACKAGE_HEADER Header;
+  UINT32                 HdrSize;
+  UINT32                 GlyphBlockOffset;
+  EFI_HII_GLYPH_INFO     Cell;
+  EFI_HII_FONT_STYLE     FontStyle;
+  CHAR16                 FontFamily[1];
+} EFI_HII_FONT_PACKAGE_HDR;
+
+//
+// Value of different glyph info block types
+//
+#define EFI_HII_GIBT_END                  0x00
+#define EFI_HII_GIBT_GLYPH                0x10
+#define EFI_HII_GIBT_GLYPHS               0x11
+#define EFI_HII_GIBT_GLYPH_DEFAULT        0x12
+#define EFI_HII_GIBT_GLYPHS_DEFAULT       0x13
+#define EFI_HII_GIBT_DUPLICATE            0x20
+#define EFI_HII_GIBT_SKIP2                0x21
+#define EFI_HII_GIBT_SKIP1                0x22
+#define EFI_HII_GIBT_DEFAULTS             0x23
+#define EFI_HII_GIBT_EXT1                 0x30
+#define EFI_HII_GIBT_EXT2                 0x31
+#define EFI_HII_GIBT_EXT4                 0x32
+
+typedef struct _EFI_HII_GLYPH_BLOCK {
+  UINT8                  BlockType;
+} EFI_HII_GLYPH_BLOCK;
+
+//
+// Definition of different glyph info block types
+//
+
+typedef struct _EFI_HII_GIBT_DEFAULTS_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  EFI_HII_GLYPH_INFO     Cell;
+} EFI_HII_GIBT_DEFAULTS_BLOCK;
+
+typedef struct _EFI_HII_GIBT_DUPLICATE_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  CHAR16                 CharValue;
+} EFI_HII_GIBT_DUPLICATE_BLOCK;
+
+typedef struct _EFI_GLYPH_GIBT_END_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+} EFI_GLYPH_GIBT_END_BLOCK;
+
+typedef struct _EFI_HII_GIBT_EXT1_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  UINT8                  BlockType2;
+  UINT8                  Length;
+} EFI_HII_GIBT_EXT1_BLOCK;
+
+typedef struct _EFI_HII_GIBT_EXT2_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  UINT8                  BlockType2;
+  UINT16                 Length;
+} EFI_HII_GIBT_EXT2_BLOCK;
+
+typedef struct _EFI_HII_GIBT_EXT4_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  UINT8                  BlockType2;
+  UINT32                 Length;
+} EFI_HII_GIBT_EXT4_BLOCK;
+
+typedef struct _EFI_HII_GIBT_GLYPH_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  EFI_HII_GLYPH_INFO     Cell;
+  UINT8                  BitmapData[1];
+} EFI_HII_GIBT_GLYPH_BLOCK;
+
+typedef struct _EFI_HII_GIBT_GLYPHS_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  EFI_HII_GLYPH_INFO     Cell;
+  UINT16                 Count;
+  UINT8                  BitmapData[1];
+} EFI_HII_GIBT_GLYPHS_BLOCK;
+
+typedef struct _EFI_HII_GIBT_GLYPH_DEFAULT_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  UINT8                  BitmapData[1];
+} EFI_HII_GIBT_GLYPH_DEFAULT_BLOCK;
+
+typedef struct _EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  UINT16                 Count;
+  UINT8                  BitmapData[1];
+} EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK;
+
+typedef struct _EFI_HII_GIBT_SKIP1_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  UINT8                  SkipCount;
+} EFI_HII_GIBT_SKIP1_BLOCK;
+
+typedef struct _EFI_HII_GIBT_SKIP2_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  UINT16                 SkipCount;
+} EFI_HII_GIBT_SKIP2_BLOCK;
+
+//
+// Definitions for Device Path Package
+// Section 27.3.4
+//
+
+///
+/// The device path package is used to carry a device path
+/// associated with the package list.
+///
+typedef struct _EFI_HII_DEVICE_PATH_PACKAGE_HDR {
+  EFI_HII_PACKAGE_HEADER   Header;
+  // EFI_DEVICE_PATH_PROTOCOL DevicePath[];
+} EFI_HII_DEVICE_PATH_PACKAGE_HDR;
+
+//
+// Definitions for GUID Package
+// Section 27.3.5
+//
+
+///
+/// The GUID package is used to carry data where the format is defined by a GUID.
+///
+typedef struct _EFI_HII_GUID_PACKAGE_HDR {
+  EFI_HII_PACKAGE_HEADER  Header;
+  EFI_GUID                Guid;
+  // Data per GUID definition may follow
+} EFI_HII_GUID_PACKAGE_HDR;
+
+//
+// Definitions for String Package
+// Section 27.3.6
+//
+
+#define UEFI_CONFIG_LANG   "x-UEFI"
+#define UEFI_CONFIG_LANG_2 "x-i-UEFI"
+
+///
+/// The fixed header consists of a standard record header and then the string identifiers
+/// contained in this section and the offsets of the string and language information.
+///
+typedef struct _EFI_HII_STRING_PACKAGE_HDR {
+  EFI_HII_PACKAGE_HEADER  Header;
+  UINT32                  HdrSize;
+  UINT32                  StringInfoOffset;
+  CHAR16                  LanguageWindow[16];
+  EFI_STRING_ID           LanguageName;
+  CHAR8                   Language[1];
+} EFI_HII_STRING_PACKAGE_HDR;
+
+typedef struct {
+  UINT8                   BlockType;
+} EFI_HII_STRING_BLOCK;
+
+//
+// Value of different string information block types
+//
+#define EFI_HII_SIBT_END                     0x00
+#define EFI_HII_SIBT_STRING_SCSU             0x10
+#define EFI_HII_SIBT_STRING_SCSU_FONT        0x11
+#define EFI_HII_SIBT_STRINGS_SCSU            0x12
+#define EFI_HII_SIBT_STRINGS_SCSU_FONT       0x13
+#define EFI_HII_SIBT_STRING_UCS2             0x14
+#define EFI_HII_SIBT_STRING_UCS2_FONT        0x15
+#define EFI_HII_SIBT_STRINGS_UCS2            0x16
+#define EFI_HII_SIBT_STRINGS_UCS2_FONT       0x17
+#define EFI_HII_SIBT_DUPLICATE               0x20
+#define EFI_HII_SIBT_SKIP2                   0x21
+#define EFI_HII_SIBT_SKIP1                   0x22
+#define EFI_HII_SIBT_EXT1                    0x30
+#define EFI_HII_SIBT_EXT2                    0x31
+#define EFI_HII_SIBT_EXT4                    0x32
+#define EFI_HII_SIBT_FONT                    0x40
+
+//
+// Definition of different string information block types
+//
+
+typedef struct _EFI_HII_SIBT_DUPLICATE_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  EFI_STRING_ID           StringId;
+} EFI_HII_SIBT_DUPLICATE_BLOCK;
+
+typedef struct _EFI_HII_SIBT_END_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+} EFI_HII_SIBT_END_BLOCK;
+
+typedef struct _EFI_HII_SIBT_EXT1_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   BlockType2;
+  UINT8                   Length;
+} EFI_HII_SIBT_EXT1_BLOCK;
+
+typedef struct _EFI_HII_SIBT_EXT2_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   BlockType2;
+  UINT16                  Length;
+} EFI_HII_SIBT_EXT2_BLOCK;
+
+typedef struct _EFI_HII_SIBT_EXT4_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   BlockType2;
+  UINT32                  Length;
+} EFI_HII_SIBT_EXT4_BLOCK;
+
+typedef struct _EFI_HII_SIBT_FONT_BLOCK {
+  EFI_HII_SIBT_EXT2_BLOCK Header;
+  UINT8                   FontId;
+  UINT16                  FontSize;
+  EFI_HII_FONT_STYLE      FontStyle;
+  CHAR16                  FontName[1];
+} EFI_HII_SIBT_FONT_BLOCK;
+
+typedef struct _EFI_HII_SIBT_SKIP1_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   SkipCount;
+} EFI_HII_SIBT_SKIP1_BLOCK;
+
+typedef struct _EFI_HII_SIBT_SKIP2_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT16                  SkipCount;
+} EFI_HII_SIBT_SKIP2_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRING_SCSU_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   StringText[1];
+} EFI_HII_SIBT_STRING_SCSU_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   FontIdentifier;
+  UINT8                   StringText[1];
+} EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRINGS_SCSU_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT16                  StringCount;
+  UINT8                   StringText[1];
+} EFI_HII_SIBT_STRINGS_SCSU_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   FontIdentifier;
+  UINT16                  StringCount;
+  UINT8                   StringText[1];
+} EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRING_UCS2_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  CHAR16                  StringText[1];
+} EFI_HII_SIBT_STRING_UCS2_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   FontIdentifier;
+  CHAR16                  StringText[1];
+} EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRINGS_UCS2_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT16                  StringCount;
+  CHAR16                  StringText[1];
+} EFI_HII_SIBT_STRINGS_UCS2_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   FontIdentifier;
+  UINT16                  StringCount;
+  CHAR16                  StringText[1];
+} EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK;
+
+//
+// Definitions for Image Package
+// Section 27.3.7
+//
+
+typedef struct _EFI_HII_IMAGE_PACKAGE_HDR {
+  EFI_HII_PACKAGE_HEADER  Header;
+  UINT32                  ImageInfoOffset;
+  UINT32                  PaletteInfoOffset;
+} EFI_HII_IMAGE_PACKAGE_HDR;
+
+typedef struct _EFI_HII_IMAGE_BLOCK {
+  UINT8                   BlockType;
+} EFI_HII_IMAGE_BLOCK;
+
+//
+// Value of different image information block types
+//
+#define EFI_HII_IIBT_END               0x00
+#define EFI_HII_IIBT_IMAGE_1BIT        0x10
+#define EFI_HII_IIBT_IMAGE_1BIT_TRANS  0x11
+#define EFI_HII_IIBT_IMAGE_4BIT        0x12
+#define EFI_HII_IIBT_IMAGE_4BIT_TRANS  0x13
+#define EFI_HII_IIBT_IMAGE_8BIT        0x14
+#define EFI_HII_IIBT_IMAGE_8BIT_TRANS  0x15
+#define EFI_HII_IIBT_IMAGE_24BIT       0x16
+#define EFI_HII_IIBT_IMAGE_24BIT_TRANS 0x17
+#define EFI_HII_IIBT_IMAGE_JPEG        0x18
+#define EFI_HII_IIBT_DUPLICATE         0x20
+#define EFI_HII_IIBT_SKIP2             0x21
+#define EFI_HII_IIBT_SKIP1             0x22
+#define EFI_HII_IIBT_EXT1              0x30
+#define EFI_HII_IIBT_EXT2              0x31
+#define EFI_HII_IIBT_EXT4              0x32
+
+//
+// Definition of different image information block types
+//
+
+typedef struct _EFI_HII_IIBT_END_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+} EFI_HII_IIBT_END_BLOCK;
+
+typedef struct _EFI_HII_IIBT_EXT1_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        BlockType2;
+  UINT8                        Length;
+} EFI_HII_IIBT_EXT1_BLOCK;
+
+typedef struct _EFI_HII_IIBT_EXT2_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        BlockType2;
+  UINT16                       Length;
+} EFI_HII_IIBT_EXT2_BLOCK;
+
+typedef struct _EFI_HII_IIBT_EXT4_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        BlockType2;
+  UINT32                       Length;
+} EFI_HII_IIBT_EXT4_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_1BIT_BASE {
+  UINT16                       Width;
+  UINT16                       Height;
+  UINT8                        Data[1];
+} EFI_HII_IIBT_IMAGE_1BIT_BASE;
+
+typedef struct _EFI_HII_IIBT_IMAGE_1BIT_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        PaletteIndex;
+  EFI_HII_IIBT_IMAGE_1BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_1BIT_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_1BIT_TRANS_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        PaletteIndex;
+  EFI_HII_IIBT_IMAGE_1BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_1BIT_TRANS_BLOCK;
+
+typedef struct _EFI_HII_RGB_PIXEL {
+  UINT8                        b;
+  UINT8                        g;
+  UINT8                        r;
+} EFI_HII_RGB_PIXEL;
+
+typedef struct _EFI_HII_IIBT_IMAGE_24BIT_BASE {
+  UINT16                       Width;
+  UINT16                       Height;
+  EFI_HII_RGB_PIXEL            Bitmap[1];
+} EFI_HII_IIBT_IMAGE_24BIT_BASE;
+
+typedef struct _EFI_HII_IIBT_IMAGE_24BIT_BLOCK {
+  EFI_HII_IMAGE_BLOCK           Header;
+  EFI_HII_IIBT_IMAGE_24BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_24BIT_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_24BIT_TRANS_BLOCK {
+  EFI_HII_IMAGE_BLOCK           Header;
+  EFI_HII_IIBT_IMAGE_24BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_24BIT_TRANS_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_4BIT_BASE {
+  UINT16                       Width;
+  UINT16                       Height;
+  UINT8                        Data[1];
+} EFI_HII_IIBT_IMAGE_4BIT_BASE;
+
+typedef struct _EFI_HII_IIBT_IMAGE_4BIT_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        PaletteIndex;
+  EFI_HII_IIBT_IMAGE_4BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_4BIT_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_4BIT_TRANS_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        PaletteIndex;
+  EFI_HII_IIBT_IMAGE_4BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_4BIT_TRANS_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_8BIT_BASE {
+  UINT16                       Width;
+  UINT16                       Height;
+  UINT8                        Data[1];
+} EFI_HII_IIBT_IMAGE_8BIT_BASE;
+
+typedef struct _EFI_HII_IIBT_IMAGE_8BIT_PALETTE_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        PaletteIndex;
+  EFI_HII_IIBT_IMAGE_8BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_8BIT_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_8BIT_TRANS_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        PaletteIndex;
+  EFI_HII_IIBT_IMAGE_8BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_8BIT_TRAN_BLOCK;
+
+typedef struct _EFI_HII_IIBT_DUPLICATE_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  EFI_IMAGE_ID                 ImageId;
+} EFI_HII_IIBT_DUPLICATE_BLOCK;
+
+typedef struct _EFI_HII_IIBT_JPEG_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT32                       Size;
+  UINT8                        Data[1];
+} EFI_HII_IIBT_JPEG_BLOCK;
+
+typedef struct _EFI_HII_IIBT_SKIP1_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        SkipCount;
+} EFI_HII_IIBT_SKIP1_BLOCK;
+
+typedef struct _EFI_HII_IIBT_SKIP2_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT16                       SkipCount;
+} EFI_HII_IIBT_SKIP2_BLOCK;
+
+//
+// Definitions for Palette Information
+//
+
+typedef struct _EFI_HII_IMAGE_PALETTE_INFO_HEADER {
+  UINT16                       PaletteCount;
+} EFI_HII_IMAGE_PALETTE_INFO_HEADER;
+
+typedef struct _EFI_HII_IMAGE_PALETTE_INFO {
+  UINT16                       PaletteSize;
+  EFI_HII_RGB_PIXEL            PaletteValue[1];
+} EFI_HII_IMAGE_PALETTE_INFO;
+
+//
+// Definitions for Forms Package
+// Section 27.3.8
+//
+
+///
+/// The Form package is used to carry form-based encoding data.
+///
+typedef struct _EFI_HII_FORM_PACKAGE_HDR {
+  EFI_HII_PACKAGE_HEADER       Header;
+  // EFI_IFR_OP_HEADER         OpCodeHeader;
+  // More op-codes follow
+} EFI_HII_FORM_PACKAGE_HDR;
+
+typedef struct {
+  UINT8 Hour;
+  UINT8 Minute;
+  UINT8 Second;
+} EFI_HII_TIME;
+
+typedef struct {
+  UINT16 Year;
+  UINT8  Month;
+  UINT8  Day;
+} EFI_HII_DATE;
+
+typedef struct {
+  EFI_QUESTION_ID QuestionId;
+  EFI_FORM_ID     FormId;
+  EFI_GUID        FormSetGuid;
+  EFI_STRING_ID   DevicePath;
+} EFI_HII_REF;
+
+typedef union {
+  UINT8           u8;
+  UINT16          u16;
+  UINT32          u32;
+  UINT64          u64;
+  BOOLEAN         b;
+  EFI_HII_TIME    time;
+  EFI_HII_DATE    date;
+  EFI_STRING_ID   string; ///< EFI_IFR_TYPE_STRING, EFI_IFR_TYPE_ACTION
+  EFI_HII_REF     ref;    ///< EFI_IFR_TYPE_REF
+  // UINT8 buffer[];      ///< EFI_IFR_TYPE_BUFFER
+} EFI_IFR_TYPE_VALUE;
+
+//
+// IFR Opcodes
+//
+#define EFI_IFR_FORM_OP                0x01
+#define EFI_IFR_SUBTITLE_OP            0x02
+#define EFI_IFR_TEXT_OP                0x03
+#define EFI_IFR_IMAGE_OP               0x04
+#define EFI_IFR_ONE_OF_OP              0x05
+#define EFI_IFR_CHECKBOX_OP            0x06
+#define EFI_IFR_NUMERIC_OP             0x07
+#define EFI_IFR_PASSWORD_OP            0x08
+#define EFI_IFR_ONE_OF_OPTION_OP       0x09
+#define EFI_IFR_SUPPRESS_IF_OP         0x0A
+#define EFI_IFR_LOCKED_OP              0x0B
+#define EFI_IFR_ACTION_OP              0x0C
+#define EFI_IFR_RESET_BUTTON_OP        0x0D
+#define EFI_IFR_FORM_SET_OP            0x0E
+#define EFI_IFR_REF_OP                 0x0F
+#define EFI_IFR_NO_SUBMIT_IF_OP        0x10
+#define EFI_IFR_INCONSISTENT_IF_OP     0x11
+#define EFI_IFR_EQ_ID_VAL_OP           0x12
+#define EFI_IFR_EQ_ID_ID_OP            0x13
+#define EFI_IFR_EQ_ID_VAL_LIST_OP      0x14
+#define EFI_IFR_AND_OP                 0x15
+#define EFI_IFR_OR_OP                  0x16
+#define EFI_IFR_NOT_OP                 0x17
+#define EFI_IFR_RULE_OP                0x18
+#define EFI_IFR_GRAY_OUT_IF_OP         0x19
+#define EFI_IFR_DATE_OP                0x1A
+#define EFI_IFR_TIME_OP                0x1B
+#define EFI_IFR_STRING_OP              0x1C
+#define EFI_IFR_REFRESH_OP             0x1D
+#define EFI_IFR_DISABLE_IF_OP          0x1E
+#define EFI_IFR_ANIMATION_OP           0x1F
+#define EFI_IFR_TO_LOWER_OP            0x20
+#define EFI_IFR_TO_UPPER_OP            0x21
+#define EFI_IFR_MAP_OP                 0x22
+#define EFI_IFR_ORDERED_LIST_OP        0x23
+#define EFI_IFR_VARSTORE_OP            0x24
+#define EFI_IFR_VARSTORE_NAME_VALUE_OP 0x25
+#define EFI_IFR_VARSTORE_EFI_OP        0x26
+#define EFI_IFR_VARSTORE_DEVICE_OP     0x27
+#define EFI_IFR_VERSION_OP             0x28
+#define EFI_IFR_END_OP                 0x29
+#define EFI_IFR_MATCH_OP               0x2A
+#define EFI_IFR_GET_OP                 0x2B
+#define EFI_IFR_SET_OP                 0x2C
+#define EFI_IFR_READ_OP                0x2D
+#define EFI_IFR_WRITE_OP               0x2E
+#define EFI_IFR_EQUAL_OP               0x2F
+#define EFI_IFR_NOT_EQUAL_OP           0x30
+#define EFI_IFR_GREATER_THAN_OP        0x31
+#define EFI_IFR_GREATER_EQUAL_OP       0x32
+#define EFI_IFR_LESS_THAN_OP           0x33
+#define EFI_IFR_LESS_EQUAL_OP          0x34
+#define EFI_IFR_BITWISE_AND_OP         0x35
+#define EFI_IFR_BITWISE_OR_OP          0x36
+#define EFI_IFR_BITWISE_NOT_OP         0x37
+#define EFI_IFR_SHIFT_LEFT_OP          0x38
+#define EFI_IFR_SHIFT_RIGHT_OP         0x39
+#define EFI_IFR_ADD_OP                 0x3A
+#define EFI_IFR_SUBTRACT_OP            0x3B
+#define EFI_IFR_MULTIPLY_OP            0x3C
+#define EFI_IFR_DIVIDE_OP              0x3D
+#define EFI_IFR_MODULO_OP              0x3E
+#define EFI_IFR_RULE_REF_OP            0x3F
+#define EFI_IFR_QUESTION_REF1_OP       0x40
+#define EFI_IFR_QUESTION_REF2_OP       0x41
+#define EFI_IFR_UINT8_OP               0x42
+#define EFI_IFR_UINT16_OP              0x43
+#define EFI_IFR_UINT32_OP              0x44
+#define EFI_IFR_UINT64_OP              0x45
+#define EFI_IFR_TRUE_OP                0x46
+#define EFI_IFR_FALSE_OP               0x47
+#define EFI_IFR_TO_UINT_OP             0x48
+#define EFI_IFR_TO_STRING_OP           0x49
+#define EFI_IFR_TO_BOOLEAN_OP          0x4A
+#define EFI_IFR_MID_OP                 0x4B
+#define EFI_IFR_FIND_OP                0x4C
+#define EFI_IFR_TOKEN_OP               0x4D
+#define EFI_IFR_STRING_REF1_OP         0x4E
+#define EFI_IFR_STRING_REF2_OP         0x4F
+#define EFI_IFR_CONDITIONAL_OP         0x50
+#define EFI_IFR_QUESTION_REF3_OP       0x51
+#define EFI_IFR_ZERO_OP                0x52
+#define EFI_IFR_ONE_OP                 0x53
+#define EFI_IFR_ONES_OP                0x54
+#define EFI_IFR_UNDEFINED_OP           0x55
+#define EFI_IFR_LENGTH_OP              0x56
+#define EFI_IFR_DUP_OP                 0x57
+#define EFI_IFR_THIS_OP                0x58
+#define EFI_IFR_SPAN_OP                0x59
+#define EFI_IFR_VALUE_OP               0x5A
+#define EFI_IFR_DEFAULT_OP             0x5B
+#define EFI_IFR_DEFAULTSTORE_OP        0x5C
+#define EFI_IFR_FORM_MAP_OP            0x5D
+#define EFI_IFR_CATENATE_OP            0x5E
+#define EFI_IFR_GUID_OP                0x5F
+#define EFI_IFR_SECURITY_OP            0x60
+#define EFI_IFR_MODAL_TAG_OP           0x61
+#define EFI_IFR_REFRESH_ID_OP          0x62
+#define EFI_IFR_WARNING_IF_OP          0x63
+
+//
+// Definitions of IFR Standard Headers
+// Section 27.3.8.2
+//
+
+typedef struct _EFI_IFR_OP_HEADER {
+  UINT8                    OpCode;
+  UINT8                    Length:7;
+  UINT8                    Scope:1;
+} EFI_IFR_OP_HEADER;
+
+typedef struct _EFI_IFR_STATEMENT_HEADER {
+  EFI_STRING_ID            Prompt;
+  EFI_STRING_ID            Help;
+} EFI_IFR_STATEMENT_HEADER;
+
+typedef struct _EFI_IFR_QUESTION_HEADER {
+  EFI_IFR_STATEMENT_HEADER Header;
+  EFI_QUESTION_ID          QuestionId;
+  EFI_VARSTORE_ID          VarStoreId;
+  union {
+    EFI_STRING_ID          VarName;
+    UINT16                 VarOffset;
+  }                        VarStoreInfo;
+  UINT8                    Flags;
+} EFI_IFR_QUESTION_HEADER;
+
+//
+// Flag values of EFI_IFR_QUESTION_HEADER
+//
+#define EFI_IFR_FLAG_READ_ONLY         0x01
+#define EFI_IFR_FLAG_CALLBACK          0x04
+#define EFI_IFR_FLAG_RESET_REQUIRED    0x10
+#define EFI_IFR_FLAG_OPTIONS_ONLY      0x80
+
+//
+// Definition for Opcode Reference
+// Section 27.3.8.3
+//
+typedef struct _EFI_IFR_DEFAULTSTORE {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            DefaultName;
+  UINT16                   DefaultId;
+} EFI_IFR_DEFAULTSTORE;
+
+//
+// Default Identifier of default store
+//
+#define EFI_HII_DEFAULT_CLASS_STANDARD       0x0000
+#define EFI_HII_DEFAULT_CLASS_MANUFACTURING  0x0001
+#define EFI_HII_DEFAULT_CLASS_SAFE           0x0002
+#define EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN 0x4000
+#define EFI_HII_DEFAULT_CLASS_PLATFORM_END   0x7fff
+#define EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN 0x8000
+#define EFI_HII_DEFAULT_CLASS_HARDWARE_END   0xbfff
+#define EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN 0xc000
+#define EFI_HII_DEFAULT_CLASS_FIRMWARE_END   0xffff
+
+typedef struct _EFI_IFR_VARSTORE {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_GUID                 Guid;
+  EFI_VARSTORE_ID          VarStoreId;
+  UINT16                   Size;
+  UINT8                    Name[1];
+} EFI_IFR_VARSTORE;
+
+typedef struct _EFI_IFR_VARSTORE_EFI {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_VARSTORE_ID          VarStoreId;
+  EFI_GUID                 Guid;
+  UINT32                   Attributes;
+  UINT16                   Size;
+  UINT8                    Name[1];
+} EFI_IFR_VARSTORE_EFI;
+
+typedef struct _EFI_IFR_VARSTORE_NAME_VALUE {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_VARSTORE_ID          VarStoreId;
+  EFI_GUID                 Guid;
+} EFI_IFR_VARSTORE_NAME_VALUE;
+
+typedef struct _EFI_IFR_FORM_SET {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_GUID                 Guid;
+  EFI_STRING_ID            FormSetTitle;
+  EFI_STRING_ID            Help;
+  UINT8                    Flags;
+  // EFI_GUID              ClassGuid[];
+} EFI_IFR_FORM_SET;
+
+typedef struct _EFI_IFR_END {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_END;
+
+typedef struct _EFI_IFR_FORM {
+  EFI_IFR_OP_HEADER        Header;
+  UINT16                   FormId;
+  EFI_STRING_ID            FormTitle;
+} EFI_IFR_FORM;
+
+typedef struct _EFI_IFR_IMAGE {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IMAGE_ID             Id;
+} EFI_IFR_IMAGE;
+
+typedef struct _EFI_IFR_MODAL_TAG {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_MODAL_TAG;
+
+typedef struct _EFI_IFR_LOCKED {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_LOCKED;
+
+typedef struct _EFI_IFR_RULE {
+  EFI_IFR_OP_HEADER        Header;
+  UINT8                    RuleId;
+} EFI_IFR_RULE;
+
+typedef struct _EFI_IFR_DEFAULT {
+  EFI_IFR_OP_HEADER        Header;
+  UINT16                   DefaultId;
+  UINT8                    Type;
+  EFI_IFR_TYPE_VALUE       Value;
+} EFI_IFR_DEFAULT;
+
+typedef struct _EFI_IFR_DEFAULT_2 {
+  EFI_IFR_OP_HEADER        Header;
+  UINT16                   DefaultId;
+  UINT8                    Type;
+} EFI_IFR_DEFAULT_2;
+
+typedef struct _EFI_IFR_VALUE {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_VALUE;
+
+typedef struct _EFI_IFR_SUBTITLE {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_STATEMENT_HEADER Statement;
+  UINT8                    Flags;
+} EFI_IFR_SUBTITLE;
+
+#define EFI_IFR_FLAGS_HORIZONTAL       0x01
+
+typedef struct _EFI_IFR_CHECKBOX {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT8                    Flags;
+} EFI_IFR_CHECKBOX;
+
+#define EFI_IFR_CHECKBOX_DEFAULT       0x01
+#define EFI_IFR_CHECKBOX_DEFAULT_MFG   0x02
+
+typedef struct _EFI_IFR_TEXT {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_STATEMENT_HEADER Statement;
+  EFI_STRING_ID            TextTwo;
+} EFI_IFR_TEXT;
+
+typedef struct _EFI_IFR_REF {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  EFI_FORM_ID              FormId;
+} EFI_IFR_REF;
+
+typedef struct _EFI_IFR_REF2 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  EFI_FORM_ID              FormId;
+  EFI_QUESTION_ID          QuestionId;
+} EFI_IFR_REF2;
+
+typedef struct _EFI_IFR_REF3 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  EFI_FORM_ID              FormId;
+  EFI_QUESTION_ID          QuestionId;
+  EFI_GUID                 FormSetId;
+} EFI_IFR_REF3;
+
+typedef struct _EFI_IFR_REF4 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  EFI_FORM_ID              FormId;
+  EFI_QUESTION_ID          QuestionId;
+  EFI_GUID                 FormSetId;
+  EFI_STRING_ID            DevicePath;
+} EFI_IFR_REF4;
+
+typedef struct _EFI_IFR_REF5 {
+  EFI_IFR_OP_HEADER Header;
+  EFI_IFR_QUESTION_HEADER Question;
+} EFI_IFR_REF5;
+
+typedef struct _EFI_IFR_RESET_BUTTON {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_STATEMENT_HEADER Statement;
+  EFI_DEFAULT_ID           DefaultId;
+} EFI_IFR_RESET_BUTTON;
+
+typedef struct _EFI_IFR_ACTION {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  EFI_STRING_ID            QuestionConfig;
+} EFI_IFR_ACTION;
+
+typedef struct _EFI_IFR_ACTION_1 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+} EFI_IFR_ACTION_1;
+
+typedef struct _EFI_IFR_DATE {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT8                    Flags;
+} EFI_IFR_DATE;
+
+//
+// Flags that describe the behavior of the question.
+//
+#define EFI_QF_DATE_YEAR_SUPPRESS      0x01
+#define EFI_QF_DATE_MONTH_SUPPRESS     0x02
+#define EFI_QF_DATE_DAY_SUPPRESS       0x04
+
+#define EFI_QF_DATE_STORAGE            0x30
+#define     QF_DATE_STORAGE_NORMAL     0x00
+#define     QF_DATE_STORAGE_TIME       0x10
+#define     QF_DATE_STORAGE_WAKEUP     0x20
+
+typedef union {
+  struct {
+    UINT8 MinValue;
+    UINT8 MaxValue;
+    UINT8 Step;
+  } u8;
+  struct {
+    UINT16 MinValue;
+    UINT16 MaxValue;
+    UINT16 Step;
+  } u16;
+  struct {
+    UINT32 MinValue;
+    UINT32 MaxValue;
+    UINT32 Step;
+  } u32;
+  struct {
+    UINT64 MinValue;
+    UINT64 MaxValue;
+    UINT64 Step;
+  } u64;
+} MINMAXSTEP_DATA;
+
+typedef struct _EFI_IFR_NUMERIC {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT8                    Flags;
+  MINMAXSTEP_DATA          data;
+} EFI_IFR_NUMERIC;
+
+//
+// Flags related to the numeric question
+//
+#define EFI_IFR_NUMERIC_SIZE           0x03
+#define   EFI_IFR_NUMERIC_SIZE_1       0x00
+#define   EFI_IFR_NUMERIC_SIZE_2       0x01
+#define   EFI_IFR_NUMERIC_SIZE_4       0x02
+#define   EFI_IFR_NUMERIC_SIZE_8       0x03
+
+#define EFI_IFR_DISPLAY                0x30
+#define   EFI_IFR_DISPLAY_INT_DEC      0x00
+#define   EFI_IFR_DISPLAY_UINT_DEC     0x10
+#define   EFI_IFR_DISPLAY_UINT_HEX     0x20
+
+typedef struct _EFI_IFR_ONE_OF {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT8                    Flags;
+  MINMAXSTEP_DATA          data;
+} EFI_IFR_ONE_OF;
+
+typedef struct _EFI_IFR_STRING {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT8                    MinSize;
+  UINT8                    MaxSize;
+  UINT8                    Flags;
+} EFI_IFR_STRING;
+
+#define EFI_IFR_STRING_MULTI_LINE      0x01
+
+typedef struct _EFI_IFR_PASSWORD {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT16                   MinSize;
+  UINT16                   MaxSize;
+} EFI_IFR_PASSWORD;
+
+typedef struct _EFI_IFR_ORDERED_LIST {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT8                    MaxContainers;
+  UINT8                    Flags;
+} EFI_IFR_ORDERED_LIST;
+
+#define EFI_IFR_UNIQUE_SET             0x01
+#define EFI_IFR_NO_EMPTY_SET           0x02
+
+typedef struct _EFI_IFR_TIME {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT8                    Flags;
+} EFI_IFR_TIME;
+
+//
+// A bit-mask that determines which unique settings are active for this opcode.
+//
+#define QF_TIME_HOUR_SUPPRESS          0x01
+#define QF_TIME_MINUTE_SUPPRESS        0x02
+#define QF_TIME_SECOND_SUPPRESS        0x04
+
+#define QF_TIME_STORAGE                0x30
+#define   QF_TIME_STORAGE_NORMAL       0x00
+#define   QF_TIME_STORAGE_TIME         0x10
+#define   QF_TIME_STORAGE_WAKEUP       0x20
+
+typedef struct _EFI_IFR_DISABLE_IF {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_DISABLE_IF;
+
+typedef struct _EFI_IFR_SUPPRESS_IF {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_SUPPRESS_IF;
+
+typedef struct _EFI_IFR_GRAY_OUT_IF {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_GRAY_OUT_IF;
+
+typedef struct _EFI_IFR_INCONSISTENT_IF {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            Error;
+} EFI_IFR_INCONSISTENT_IF;
+
+typedef struct _EFI_IFR_NO_SUBMIT_IF {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            Error;
+} EFI_IFR_NO_SUBMIT_IF;
+
+typedef struct _EFI_IFR_WARNING_IF {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            Warning;
+  UINT8                    TimeOut;
+} EFI_IFR_WARNING_IF;
+
+typedef struct _EFI_IFR_REFRESH {
+  EFI_IFR_OP_HEADER        Header;
+  UINT8                    RefreshInterval;
+} EFI_IFR_REFRESH;
+
+typedef struct _EFI_IFR_VARSTORE_DEVICE {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            DevicePath;
+} EFI_IFR_VARSTORE_DEVICE;
+
+typedef struct _EFI_IFR_ONE_OF_OPTION {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            Option;
+  UINT8                    Flags;
+  UINT8                    Type;
+  EFI_IFR_TYPE_VALUE       Value;
+} EFI_IFR_ONE_OF_OPTION;
+
+//
+// Types of the option's value.
+//
+#define EFI_IFR_TYPE_NUM_SIZE_8        0x00
+#define EFI_IFR_TYPE_NUM_SIZE_16       0x01
+#define EFI_IFR_TYPE_NUM_SIZE_32       0x02
+#define EFI_IFR_TYPE_NUM_SIZE_64       0x03
+#define EFI_IFR_TYPE_BOOLEAN           0x04
+#define EFI_IFR_TYPE_TIME              0x05
+#define EFI_IFR_TYPE_DATE              0x06
+#define EFI_IFR_TYPE_STRING            0x07
+#define EFI_IFR_TYPE_OTHER             0x08
+#define EFI_IFR_TYPE_UNDEFINED         0x09
+#define EFI_IFR_TYPE_ACTION            0x0A
+#define EFI_IFR_TYPE_BUFFER            0x0B
+#define EFI_IFR_TYPE_REF               0x0C
+
+#define EFI_IFR_OPTION_DEFAULT         0x10
+#define EFI_IFR_OPTION_DEFAULT_MFG     0x20
+
+typedef struct _EFI_IFR_GUID {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_GUID                 Guid;
+  //Optional Data Follows
+} EFI_IFR_GUID;
+
+typedef struct _EFI_IFR_REFRESH_ID {
+  EFI_IFR_OP_HEADER Header;
+  EFI_GUID          RefreshEventGroupId;
+} EFI_IFR_REFRESH_ID;
+
+typedef struct _EFI_IFR_DUP {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_DUP;
+
+typedef struct _EFI_IFR_EQ_ID_ID {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_QUESTION_ID          QuestionId1;
+  EFI_QUESTION_ID          QuestionId2;
+} EFI_IFR_EQ_ID_ID;
+
+typedef struct _EFI_IFR_EQ_ID_VAL {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_QUESTION_ID          QuestionId;
+  UINT16                   Value;
+} EFI_IFR_EQ_ID_VAL;
+
+typedef struct _EFI_IFR_EQ_ID_VAL_LIST {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_QUESTION_ID          QuestionId;
+  UINT16                   ListLength;
+  UINT16                   ValueList[1];
+} EFI_IFR_EQ_ID_VAL_LIST;
+
+typedef struct _EFI_IFR_UINT8 {
+  EFI_IFR_OP_HEADER        Header;
+  UINT8 Value;
+} EFI_IFR_UINT8;
+
+typedef struct _EFI_IFR_UINT16 {
+  EFI_IFR_OP_HEADER        Header;
+  UINT16                   Value;
+} EFI_IFR_UINT16;
+
+typedef struct _EFI_IFR_UINT32 {
+  EFI_IFR_OP_HEADER        Header;
+  UINT32                   Value;
+} EFI_IFR_UINT32;
+
+typedef struct _EFI_IFR_UINT64 {
+  EFI_IFR_OP_HEADER        Header;
+  UINT64 Value;
+} EFI_IFR_UINT64;
+
+typedef struct _EFI_IFR_QUESTION_REF1 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_QUESTION_ID          QuestionId;
+} EFI_IFR_QUESTION_REF1;
+
+typedef struct _EFI_IFR_QUESTION_REF2 {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_QUESTION_REF2;
+
+typedef struct _EFI_IFR_QUESTION_REF3 {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_QUESTION_REF3;
+
+typedef struct _EFI_IFR_QUESTION_REF3_2 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            DevicePath;
+} EFI_IFR_QUESTION_REF3_2;
+
+typedef struct _EFI_IFR_QUESTION_REF3_3 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            DevicePath;
+  EFI_GUID                 Guid;
+} EFI_IFR_QUESTION_REF3_3;
+
+typedef struct _EFI_IFR_RULE_REF {
+  EFI_IFR_OP_HEADER        Header;
+  UINT8                    RuleId;
+} EFI_IFR_RULE_REF;
+
+typedef struct _EFI_IFR_STRING_REF1 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            StringId;
+} EFI_IFR_STRING_REF1;
+
+typedef struct _EFI_IFR_STRING_REF2 {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_STRING_REF2;
+
+typedef struct _EFI_IFR_THIS {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_THIS;
+
+typedef struct _EFI_IFR_TRUE {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_TRUE;
+
+typedef struct _EFI_IFR_FALSE {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_FALSE;
+
+typedef struct _EFI_IFR_ONE {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_ONE;
+
+typedef struct _EFI_IFR_ONES {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_ONES;
+
+typedef struct _EFI_IFR_ZERO {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_ZERO;
+
+typedef struct _EFI_IFR_UNDEFINED {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_UNDEFINED;
+
+typedef struct _EFI_IFR_VERSION {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_VERSION;
+
+typedef struct _EFI_IFR_LENGTH {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_LENGTH;
+
+typedef struct _EFI_IFR_NOT {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_NOT;
+
+typedef struct _EFI_IFR_BITWISE_NOT {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_BITWISE_NOT;
+
+typedef struct _EFI_IFR_TO_BOOLEAN {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_TO_BOOLEAN;
+
+///
+/// For EFI_IFR_TO_STRING, when converting from
+/// unsigned integers, these flags control the format:
+/// 0 = unsigned decimal.
+/// 1 = signed decimal.
+/// 2 = hexadecimal (lower-case alpha).
+/// 3 = hexadecimal (upper-case alpha).
+///@{
+#define EFI_IFR_STRING_UNSIGNED_DEC      0
+#define EFI_IFR_STRING_SIGNED_DEC        1
+#define EFI_IFR_STRING_LOWERCASE_HEX     2
+#define EFI_IFR_STRING_UPPERCASE_HEX     3
+///@}
+
+///
+/// When converting from a buffer, these flags control the format:
+/// 0 = ASCII.
+/// 8 = Unicode.
+///@{
+#define EFI_IFR_STRING_ASCII             0
+#define EFI_IFR_STRING_UNICODE           8
+///@}
+
+typedef struct _EFI_IFR_TO_STRING {
+  EFI_IFR_OP_HEADER        Header;
+  UINT8                    Format;
+} EFI_IFR_TO_STRING;
+
+typedef struct _EFI_IFR_TO_UINT {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_TO_UINT;
+
+typedef struct _EFI_IFR_TO_UPPER {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_TO_UPPER;
+
+typedef struct _EFI_IFR_TO_LOWER {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_TO_LOWER;
+
+typedef struct _EFI_IFR_ADD {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_ADD;
+
+typedef struct _EFI_IFR_AND {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_AND;
+
+typedef struct _EFI_IFR_BITWISE_AND {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_BITWISE_AND;
+
+typedef struct _EFI_IFR_BITWISE_OR {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_BITWISE_OR;
+
+typedef struct _EFI_IFR_CATENATE {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_CATENATE;
+
+typedef struct _EFI_IFR_DIVIDE {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_DIVIDE;
+
+typedef struct _EFI_IFR_EQUAL {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_EQUAL;
+
+typedef struct _EFI_IFR_GREATER_EQUAL {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_GREATER_EQUAL;
+
+typedef struct _EFI_IFR_GREATER_THAN {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_GREATER_THAN;
+
+typedef struct _EFI_IFR_LESS_EQUAL {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_LESS_EQUAL;
+
+typedef struct _EFI_IFR_LESS_THAN {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_LESS_THAN;
+
+typedef struct _EFI_IFR_MATCH {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_MATCH;
+
+typedef struct _EFI_IFR_MULTIPLY {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_MULTIPLY;
+
+typedef struct _EFI_IFR_MODULO {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_MODULO;
+
+typedef struct _EFI_IFR_NOT_EQUAL {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_NOT_EQUAL;
+
+typedef struct _EFI_IFR_OR {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_OR;
+
+typedef struct _EFI_IFR_SHIFT_LEFT {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_SHIFT_LEFT;
+
+typedef struct _EFI_IFR_SHIFT_RIGHT {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_SHIFT_RIGHT;
+
+typedef struct _EFI_IFR_SUBTRACT {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_SUBTRACT;
+
+typedef struct _EFI_IFR_CONDITIONAL {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_CONDITIONAL;
+
+//
+// Flags governing the matching criteria of EFI_IFR_FIND
+//
+#define EFI_IFR_FF_CASE_SENSITIVE    0x00
+#define EFI_IFR_FF_CASE_INSENSITIVE  0x01
+
+typedef struct _EFI_IFR_FIND {
+  EFI_IFR_OP_HEADER        Header;
+  UINT8                    Format;
+} EFI_IFR_FIND;
+
+typedef struct _EFI_IFR_MID {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_MID;
+
+typedef struct _EFI_IFR_TOKEN {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_TOKEN;
+
+//
+// Flags specifying whether to find the first matching string
+// or the first non-matching string.
+//
+#define EFI_IFR_FLAGS_FIRST_MATCHING     0x00
+#define EFI_IFR_FLAGS_FIRST_NON_MATCHING 0x01
+
+typedef struct _EFI_IFR_SPAN {
+  EFI_IFR_OP_HEADER        Header;
+  UINT8                    Flags;
+} EFI_IFR_SPAN;
+
+typedef struct _EFI_IFR_SECURITY {
+  ///
+  /// Standard opcode header, where Header.Op = EFI_IFR_SECURITY_OP.
+  ///
+  EFI_IFR_OP_HEADER        Header;
+  ///
+  /// Security permission level.
+  ///
+  EFI_GUID                 Permissions;
+} EFI_IFR_SECURITY;
+
+typedef struct _EFI_IFR_FORM_MAP_METHOD {
+  ///
+  /// The string identifier which provides the human-readable name of
+  /// the configuration method for this standards map form.
+  ///
+  EFI_STRING_ID            MethodTitle;
+  ///
+  /// Identifier which uniquely specifies the configuration methods
+  /// associated with this standards map form.
+  ///
+  EFI_GUID                 MethodIdentifier;
+} EFI_IFR_FORM_MAP_METHOD;
+
+typedef struct _EFI_IFR_FORM_MAP {
+  ///
+  /// The sequence that defines the type of opcode as well as the length
+  /// of the opcode being defined. Header.OpCode = EFI_IFR_FORM_MAP_OP.
+  ///
+  EFI_IFR_OP_HEADER        Header;
+  ///
+  /// The unique identifier for this particular form.
+  ///
+  EFI_FORM_ID              FormId;
+  ///
+  /// One or more configuration method's name and unique identifier.
+  ///
+  // EFI_IFR_FORM_MAP_METHOD  Methods[];
+} EFI_IFR_FORM_MAP;
+
+typedef struct _EFI_IFR_SET {
+  ///
+  /// The sequence that defines the type of opcode as well as the length
+  /// of the opcode being defined. Header.OpCode = EFI_IFR_SET_OP.
+  ///
+  EFI_IFR_OP_HEADER  Header;
+  ///
+  /// Specifies the identifier of a previously declared variable store to
+  /// use when storing the question's value.
+  ///
+  EFI_VARSTORE_ID    VarStoreId;
+  union {
+    ///
+    /// A 16-bit Buffer Storage offset.
+    ///
+    EFI_STRING_ID    VarName;
+    ///
+    /// A Name Value or EFI Variable name (VarName).
+    ///
+    UINT16           VarOffset;
+  }                  VarStoreInfo;
+  ///
+  /// Specifies the type used for storage.
+  ///
+  UINT8              VarStoreType;
+} EFI_IFR_SET;
+
+typedef struct _EFI_IFR_GET {
+  ///
+  /// The sequence that defines the type of opcode as well as the length
+  /// of the opcode being defined. Header.OpCode = EFI_IFR_GET_OP.
+  ///
+  EFI_IFR_OP_HEADER  Header;
+  ///
+  /// Specifies the identifier of a previously declared variable store to
+  /// use when retrieving the value.
+  ///
+  EFI_VARSTORE_ID    VarStoreId;
+  union {
+    ///
+    /// A 16-bit Buffer Storage offset.
+    ///
+    EFI_STRING_ID    VarName;
+    ///
+    /// A Name Value or EFI Variable name (VarName).
+    ///
+    UINT16           VarOffset;
+  }                  VarStoreInfo;
+  ///
+  /// Specifies the type used for storage.
+  ///
+  UINT8              VarStoreType;
+} EFI_IFR_GET;
+
+typedef struct _EFI_IFR_READ {
+  EFI_IFR_OP_HEADER       Header;
+} EFI_IFR_READ;
+
+typedef struct _EFI_IFR_WRITE {
+  EFI_IFR_OP_HEADER      Header;
+} EFI_IFR_WRITE;
+
+typedef struct _EFI_IFR_MAP {
+  EFI_IFR_OP_HEADER      Header;
+} EFI_IFR_MAP;
+//
+// Definitions for Keyboard Package
+// Releated definitions are in Section of EFI_HII_DATABASE_PROTOCOL
+//
+
+///
+/// Each enumeration values maps a physical key on a keyboard.
+///
+typedef enum {
+  EfiKeyLCtrl,
+  EfiKeyA0,
+  EfiKeyLAlt,
+  EfiKeySpaceBar,
+  EfiKeyA2,
+  EfiKeyA3,
+  EfiKeyA4,
+  EfiKeyRCtrl,
+  EfiKeyLeftArrow,
+  EfiKeyDownArrow,
+  EfiKeyRightArrow,
+  EfiKeyZero,
+  EfiKeyPeriod,
+  EfiKeyEnter,
+  EfiKeyLShift,
+  EfiKeyB0,
+  EfiKeyB1,
+  EfiKeyB2,
+  EfiKeyB3,
+  EfiKeyB4,
+  EfiKeyB5,
+  EfiKeyB6,
+  EfiKeyB7,
+  EfiKeyB8,
+  EfiKeyB9,
+  EfiKeyB10,
+  EfiKeyRShift,
+  EfiKeyUpArrow,
+  EfiKeyOne,
+  EfiKeyTwo,
+  EfiKeyThree,
+  EfiKeyCapsLock,
+  EfiKeyC1,
+  EfiKeyC2,
+  EfiKeyC3,
+  EfiKeyC4,
+  EfiKeyC5,
+  EfiKeyC6,
+  EfiKeyC7,
+  EfiKeyC8,
+  EfiKeyC9,
+  EfiKeyC10,
+  EfiKeyC11,
+  EfiKeyC12,
+  EfiKeyFour,
+  EfiKeyFive,
+  EfiKeySix,
+  EfiKeyPlus,
+  EfiKeyTab,
+  EfiKeyD1,
+  EfiKeyD2,
+  EfiKeyD3,
+  EfiKeyD4,
+  EfiKeyD5,
+  EfiKeyD6,
+  EfiKeyD7,
+  EfiKeyD8,
+  EfiKeyD9,
+  EfiKeyD10,
+  EfiKeyD11,
+  EfiKeyD12,
+  EfiKeyD13,
+  EfiKeyDel,
+  EfiKeyEnd,
+  EfiKeyPgDn,
+  EfiKeySeven,
+  EfiKeyEight,
+  EfiKeyNine,
+  EfiKeyE0,
+  EfiKeyE1,
+  EfiKeyE2,
+  EfiKeyE3,
+  EfiKeyE4,
+  EfiKeyE5,
+  EfiKeyE6,
+  EfiKeyE7,
+  EfiKeyE8,
+  EfiKeyE9,
+  EfiKeyE10,
+  EfiKeyE11,
+  EfiKeyE12,
+  EfiKeyBackSpace,
+  EfiKeyIns,
+  EfiKeyHome,
+  EfiKeyPgUp,
+  EfiKeyNLck,
+  EfiKeySlash,
+  EfiKeyAsterisk,
+  EfiKeyMinus,
+  EfiKeyEsc,
+  EfiKeyF1,
+  EfiKeyF2,
+  EfiKeyF3,
+  EfiKeyF4,
+  EfiKeyF5,
+  EfiKeyF6,
+  EfiKeyF7,
+  EfiKeyF8,
+  EfiKeyF9,
+  EfiKeyF10,
+  EfiKeyF11,
+  EfiKeyF12,
+  EfiKeyPrint,
+  EfiKeySLck,
+  EfiKeyPause
+} EFI_KEY;
+
+typedef struct {
+  ///
+  /// Used to describe a physical key on a keyboard.
+  ///
+  EFI_KEY                 Key;
+  ///
+  /// Unicode character code for the Key.
+  ///
+  CHAR16                  Unicode;
+  ///
+  /// Unicode character code for the key with the shift key being held down.
+  ///
+  CHAR16                  ShiftedUnicode;
+  ///
+  /// Unicode character code for the key with the Alt-GR being held down.
+  ///
+  CHAR16                  AltGrUnicode;
+  ///
+  /// Unicode character code for the key with the Alt-GR and shift keys being held down.
+  ///
+  CHAR16                  ShiftedAltGrUnicode;
+  ///
+  /// Modifier keys are defined to allow for special functionality that is not necessarily
+  /// accomplished by a printable character. Many of these modifier keys are flags to toggle
+  /// certain state bits on and off inside of a keyboard driver.
+  ///
+  UINT16                  Modifier;
+  UINT16                  AffectedAttribute;
+} EFI_KEY_DESCRIPTOR;
+
+///
+/// A key which is affected by all the standard shift modifiers.
+/// Most keys would be expected to have this bit active.
+///
+#define EFI_AFFECTED_BY_STANDARD_SHIFT       0x0001
+
+///
+/// This key is affected by the caps lock so that if a keyboard driver
+/// would need to disambiguate between a key which had a "1" defined
+/// versus an "a" character.  Having this bit turned on would tell
+/// the keyboard driver to use the appropriate shifted state or not.
+///
+#define EFI_AFFECTED_BY_CAPS_LOCK            0x0002
+
+///
+/// Similar to the case of CAPS lock, if this bit is active, the key
+/// is affected by the num lock being turned on.
+///
+#define EFI_AFFECTED_BY_NUM_LOCK             0x0004
+
+typedef struct {
+  UINT16                  LayoutLength;
+  EFI_GUID                Guid;
+  UINT32                  LayoutDescriptorStringOffset;
+  UINT8                   DescriptorCount;
+  // EFI_KEY_DESCRIPTOR    Descriptors[];
+} EFI_HII_KEYBOARD_LAYOUT;
+
+typedef struct {
+  EFI_HII_PACKAGE_HEADER  Header;
+  UINT16                  LayoutCount;
+  // EFI_HII_KEYBOARD_LAYOUT Layout[];
+} EFI_HII_KEYBOARD_PACKAGE_HDR;
+
+//
+// Modifier values
+//
+#define EFI_NULL_MODIFIER                0x0000
+#define EFI_LEFT_CONTROL_MODIFIER        0x0001
+#define EFI_RIGHT_CONTROL_MODIFIER       0x0002
+#define EFI_LEFT_ALT_MODIFIER            0x0003
+#define EFI_RIGHT_ALT_MODIFIER           0x0004
+#define EFI_ALT_GR_MODIFIER              0x0005
+#define EFI_INSERT_MODIFIER              0x0006
+#define EFI_DELETE_MODIFIER              0x0007
+#define EFI_PAGE_DOWN_MODIFIER           0x0008
+#define EFI_PAGE_UP_MODIFIER             0x0009
+#define EFI_HOME_MODIFIER                0x000A
+#define EFI_END_MODIFIER                 0x000B
+#define EFI_LEFT_SHIFT_MODIFIER          0x000C
+#define EFI_RIGHT_SHIFT_MODIFIER         0x000D
+#define EFI_CAPS_LOCK_MODIFIER           0x000E
+#define EFI_NUM_LOCK_MODIFIER            0x000F
+#define EFI_LEFT_ARROW_MODIFIER          0x0010
+#define EFI_RIGHT_ARROW_MODIFIER         0x0011
+#define EFI_DOWN_ARROW_MODIFIER          0x0012
+#define EFI_UP_ARROW_MODIFIER            0x0013
+#define EFI_NS_KEY_MODIFIER              0x0014
+#define EFI_NS_KEY_DEPENDENCY_MODIFIER   0x0015
+#define EFI_FUNCTION_KEY_ONE_MODIFIER    0x0016
+#define EFI_FUNCTION_KEY_TWO_MODIFIER    0x0017
+#define EFI_FUNCTION_KEY_THREE_MODIFIER  0x0018
+#define EFI_FUNCTION_KEY_FOUR_MODIFIER   0x0019
+#define EFI_FUNCTION_KEY_FIVE_MODIFIER   0x001A
+#define EFI_FUNCTION_KEY_SIX_MODIFIER    0x001B
+#define EFI_FUNCTION_KEY_SEVEN_MODIFIER  0x001C
+#define EFI_FUNCTION_KEY_EIGHT_MODIFIER  0x001D
+#define EFI_FUNCTION_KEY_NINE_MODIFIER   0x001E
+#define EFI_FUNCTION_KEY_TEN_MODIFIER    0x001F
+#define EFI_FUNCTION_KEY_ELEVEN_MODIFIER 0x0020
+#define EFI_FUNCTION_KEY_TWELVE_MODIFIER 0x0021
+
+//
+// Keys that have multiple control functions based on modifier
+// settings are handled in the keyboard driver implementation.
+// For instance, PRINT_KEY might have a modifier held down and
+// is still a nonprinting character, but might have an alternate
+// control function like SYSREQUEST
+//
+#define EFI_PRINT_MODIFIER               0x0022
+#define EFI_SYS_REQUEST_MODIFIER         0x0023
+#define EFI_SCROLL_LOCK_MODIFIER         0x0024
+#define EFI_PAUSE_MODIFIER               0x0025
+#define EFI_BREAK_MODIFIER               0x0026
+
+#define EFI_LEFT_LOGO_MODIFIER           0x0027
+#define EFI_RIGHT_LOGO_MODIFIER          0x0028
+#define EFI_MENU_MODIFIER                0x0029
+
+///
+/// Animation IFR opcode
+///
+typedef struct _EFI_IFR_ANIMATION {
+  ///
+  /// Standard opcode header, where Header.OpCode is
+  /// EFI_IFR_ANIMATION_OP.
+  ///
+  EFI_IFR_OP_HEADER        Header;
+  ///
+  /// Animation identifier in the HII database.
+  ///
+  EFI_ANIMATION_ID         Id;
+} EFI_IFR_ANIMATION;
+
+///
+/// HII animation package header.
+///
+typedef struct _EFI_HII_ANIMATION_PACKAGE_HDR {
+  ///
+  /// Standard package header, where Header.Type = EFI_HII_PACKAGE_ANIMATIONS.
+  ///
+  EFI_HII_PACKAGE_HEADER  Header;
+  ///
+  /// Offset, relative to this header, of the animation information. If
+  /// this is zero, then there are no animation sequences in the package.
+  ///
+  UINT32                  AnimationInfoOffset;
+} EFI_HII_ANIMATION_PACKAGE_HDR;
+
+///
+/// Animation information is encoded as a series of blocks,
+/// with each block prefixed by a single byte header EFI_HII_ANIMATION_BLOCK.
+///
+typedef struct _EFI_HII_ANIMATION_BLOCK {
+  UINT8  BlockType;
+  //UINT8  BlockBody[];
+} EFI_HII_ANIMATION_BLOCK;
+
+///
+/// Animation block types.
+///
+#define EFI_HII_AIBT_END                 0x00
+#define EFI_HII_AIBT_OVERLAY_IMAGES      0x10
+#define EFI_HII_AIBT_CLEAR_IMAGES        0x11
+#define EFI_HII_AIBT_RESTORE_SCRN        0x12
+#define EFI_HII_AIBT_OVERLAY_IMAGES_LOOP 0x18
+#define EFI_HII_AIBT_CLEAR_IMAGES_LOOP   0x19
+#define EFI_HII_AIBT_RESTORE_SCRN_LOOP   0x1A
+#define EFI_HII_AIBT_DUPLICATE           0x20
+#define EFI_HII_AIBT_SKIP2               0x21
+#define EFI_HII_AIBT_SKIP1               0x22
+#define EFI_HII_AIBT_EXT1                0x30
+#define EFI_HII_AIBT_EXT2                0x31
+#define EFI_HII_AIBT_EXT4                0x32
+
+///
+/// Extended block headers used for variable sized animation records
+/// which need an explicit length.
+///
+
+typedef struct _EFI_HII_AIBT_EXT1_BLOCK  {
+  ///
+  /// Standard animation header, where Header.BlockType = EFI_HII_AIBT_EXT1.
+  ///
+  EFI_HII_ANIMATION_BLOCK  Header;
+  ///
+  /// The block type.
+  ///
+  UINT8                    BlockType2;
+  ///
+  /// Size of the animation block, in bytes, including the animation block header.
+  ///
+  UINT8                    Length;
+} EFI_HII_AIBT_EXT1_BLOCK;
+
+typedef struct _EFI_HII_AIBT_EXT2_BLOCK {
+  ///
+  /// Standard animation header, where Header.BlockType = EFI_HII_AIBT_EXT2.
+  ///
+  EFI_HII_ANIMATION_BLOCK  Header;
+  ///
+  /// The block type
+  ///
+  UINT8                    BlockType2;
+  ///
+  /// Size of the animation block, in bytes, including the animation block header.
+  ///
+  UINT16                   Length;
+} EFI_HII_AIBT_EXT2_BLOCK;
+
+typedef struct _EFI_HII_AIBT_EXT4_BLOCK {
+  ///
+  /// Standard animation header, where Header.BlockType = EFI_HII_AIBT_EXT4.
+  ///
+  EFI_HII_ANIMATION_BLOCK  Header;
+  ///
+  /// The block type
+  ///
+  UINT8                    BlockType2;
+  ///
+  /// Size of the animation block, in bytes, including the animation block header.
+  ///
+  UINT32                   Length;
+} EFI_HII_AIBT_EXT4_BLOCK;
+
+typedef struct _EFI_HII_ANIMATION_CELL {
+  ///
+  /// The X offset from the upper left hand corner of the logical
+  /// window to position the indexed image.
+  ///
+  UINT16                    OffsetX;
+  ///
+  /// The Y offset from the upper left hand corner of the logical
+  /// window to position the indexed image.
+  ///
+  UINT16                    OffsetY;
+  ///
+  /// The image to display at the specified offset from the upper left
+  /// hand corner of the logical window.
+  ///
+  EFI_IMAGE_ID              ImageId;
+  ///
+  /// The number of milliseconds to delay after displaying the indexed
+  /// image and before continuing on to the next linked image.  If value
+  /// is zero, no delay.
+  ///
+  UINT16                    Delay;
+} EFI_HII_ANIMATION_CELL;
+
+///
+/// An animation block to describe an animation sequence that does not cycle, and
+/// where one image is simply displayed over the previous image.
+///
+typedef struct _EFI_HII_AIBT_OVERLAY_IMAGES_BLOCK {
+  ///
+  /// This is image that is to be reference by the image protocols, if the
+  /// animation function is not supported or disabled. This image can
+  /// be one particular image from the animation sequence (if any one
+  /// of the animation frames has a complete image) or an alternate
+  /// image that can be displayed alone. If the value is zero, no image
+  /// is displayed.
+  ///
+  EFI_IMAGE_ID            DftImageId;
+  ///
+  /// The overall width of the set of images (logical window width).
+  ///
+  UINT16                  Width;
+  ///
+  /// The overall height of the set of images (logical window height).
+  ///
+  UINT16                  Height;
+  ///
+  /// The number of EFI_HII_ANIMATION_CELL contained in the
+  /// animation sequence.
+  ///
+  UINT16                  CellCount;
+  ///
+  /// An array of CellCount animation cells.
+  ///
+  EFI_HII_ANIMATION_CELL  AnimationCell[1];
+} EFI_HII_AIBT_OVERLAY_IMAGES_BLOCK;
+
+///
+/// An animation block to describe an animation sequence that does not cycle,
+/// and where the logical window is cleared to the specified color before
+/// the next image is displayed.
+///
+typedef struct _EFI_HII_AIBT_CLEAR_IMAGES_BLOCK {
+  ///
+  /// This is image that is to be reference by the image protocols, if the
+  /// animation function is not supported or disabled. This image can
+  /// be one particular image from the animation sequence (if any one
+  /// of the animation frames has a complete image) or an alternate
+  /// image that can be displayed alone. If the value is zero, no image
+  /// is displayed.
+  ///
+  EFI_IMAGE_ID       DftImageId;
+  ///
+  /// The overall width of the set of images (logical window width).
+  ///
+  UINT16             Width;
+  ///
+  /// The overall height of the set of images (logical window height).
+  ///
+  UINT16             Height;
+  ///
+  /// The number of EFI_HII_ANIMATION_CELL contained in the
+  /// animation sequence.
+  ///
+  UINT16             CellCount;
+  ///
+  /// The color to clear the logical window to before displaying the
+  /// indexed image.
+  ///
+  EFI_HII_RGB_PIXEL  BackgndColor;
+  ///
+  /// An array of CellCount animation cells.
+  ///
+  EFI_HII_ANIMATION_CELL AnimationCell[1];
+} EFI_HII_AIBT_CLEAR_IMAGES_BLOCK;
+
+///
+/// An animation block to describe an animation sequence that does not cycle,
+/// and where the screen is restored to the original state before the next
+/// image is displayed.
+///
+typedef struct _EFI_HII_AIBT_RESTORE_SCRN_BLOCK {
+  ///
+  /// This is image that is to be reference by the image protocols, if the
+  /// animation function is not supported or disabled. This image can
+  /// be one particular image from the animation sequence (if any one
+  /// of the animation frames has a complete image) or an alternate
+  /// image that can be displayed alone. If the value is zero, no image
+  /// is displayed.
+  ///
+  EFI_IMAGE_ID            DftImageId;
+  ///
+  /// The overall width of the set of images (logical window width).
+  ///
+  UINT16                  Width;
+  ///
+  /// The overall height of the set of images (logical window height).
+  ///
+  UINT16                  Height;
+  ///
+  /// The number of EFI_HII_ANIMATION_CELL contained in the
+  /// animation sequence.
+  ///
+  UINT16                  CellCount;
+  ///
+  /// An array of CellCount animation cells.
+  ///
+  EFI_HII_ANIMATION_CELL  AnimationCell[1];
+} EFI_HII_AIBT_RESTORE_SCRN_BLOCK;
+
+///
+/// An animation block to describe an animation sequence that continuously cycles,
+/// and where one image is simply displayed over the previous image.
+///
+typedef EFI_HII_AIBT_OVERLAY_IMAGES_BLOCK  EFI_HII_AIBT_OVERLAY_IMAGES_LOOP_BLOCK;
+
+///
+/// An animation block to describe an animation sequence that continuously cycles,
+/// and where the logical window is cleared to the specified color before
+/// the next image is displayed.
+///
+typedef EFI_HII_AIBT_CLEAR_IMAGES_BLOCK    EFI_HII_AIBT_CLEAR_IMAGES_LOOP_BLOCK;
+
+///
+/// An animation block to describe an animation sequence that continuously cycles,
+/// and where the screen is restored to the original state before
+/// the next image is displayed.
+///
+typedef EFI_HII_AIBT_RESTORE_SCRN_BLOCK    EFI_HII_AIBT_RESTORE_SCRN_LOOP_BLOCK;
+
+///
+/// Assigns a new character value to a previously defined animation sequence.
+///
+typedef struct _EFI_HII_AIBT_DUPLICATE_BLOCK {
+  ///
+  /// The previously defined animation ID with the exact same
+  /// animation information.
+  ///
+  EFI_ANIMATION_ID  AnimationId;
+} EFI_HII_AIBT_DUPLICATE_BLOCK;
+
+///
+/// Skips animation IDs.
+///
+typedef struct _EFI_HII_AIBT_SKIP1_BLOCK {
+  ///
+  /// The unsigned 8-bit value to add to AnimationIdCurrent.
+  ///
+  UINT8  SkipCount;
+} EFI_HII_AIBT_SKIP1_BLOCK;
+
+///
+/// Skips animation IDs.
+///
+typedef struct _EFI_HII_AIBT_SKIP2_BLOCK {
+  ///
+  /// The unsigned 16-bit value to add to AnimationIdCurrent.
+  ///
+  UINT16  SkipCount;
+} EFI_HII_AIBT_SKIP2_BLOCK;
+
+#pragma pack()
+
+
+
+///
+/// References to string tokens must use this macro to enable scanning for
+/// token usages.
+///
+///
+/// STRING_TOKEN is not defined in UEFI specification. But it is placed
+/// here for the easy access by C files and VFR source files.
+///
+#define STRING_TOKEN(t) t
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/Uefi/UefiMultiPhase.h b/wimboot/wimboot-2.7.3/src/efi/Uefi/UefiMultiPhase.h
new file mode 100644 (file)
index 0000000..33c383e
--- /dev/null
@@ -0,0 +1,193 @@
+/** @file
+  This includes some definitions introduced in UEFI that will be used in both PEI and DXE phases.
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __UEFI_MULTIPHASE_H__
+#define __UEFI_MULTIPHASE_H__
+
+#include "efi/Guid/WinCertificate.h"
+///
+/// Enumeration of memory types introduced in UEFI.
+///
+typedef enum {
+  ///
+  /// Not used.
+  ///
+  EfiReservedMemoryType,
+  ///
+  /// The code portions of a loaded application.
+  /// (Note that UEFI OS loaders are UEFI applications.)
+  ///
+  EfiLoaderCode,
+  ///
+  /// The data portions of a loaded application and the default data allocation
+  /// type used by an application to allocate pool memory.
+  ///
+  EfiLoaderData,
+  ///
+  /// The code portions of a loaded Boot Services Driver.
+  ///
+  EfiBootServicesCode,
+  ///
+  /// The data portions of a loaded Boot Serves Driver, and the default data
+  /// allocation type used by a Boot Services Driver to allocate pool memory.
+  ///
+  EfiBootServicesData,
+  ///
+  /// The code portions of a loaded Runtime Services Driver.
+  ///
+  EfiRuntimeServicesCode,
+  ///
+  /// The data portions of a loaded Runtime Services Driver and the default
+  /// data allocation type used by a Runtime Services Driver to allocate pool memory.
+  ///
+  EfiRuntimeServicesData,
+  ///
+  /// Free (unallocated) memory.
+  ///
+  EfiConventionalMemory,
+  ///
+  /// Memory in which errors have been detected.
+  ///
+  EfiUnusableMemory,
+  ///
+  /// Memory that holds the ACPI tables.
+  ///
+  EfiACPIReclaimMemory,
+  ///
+  /// Address space reserved for use by the firmware.
+  ///
+  EfiACPIMemoryNVS,
+  ///
+  /// Used by system firmware to request that a memory-mapped IO region
+  /// be mapped by the OS to a virtual address so it can be accessed by EFI runtime services.
+  ///
+  EfiMemoryMappedIO,
+  ///
+  /// System memory-mapped IO region that is used to translate memory
+  /// cycles to IO cycles by the processor.
+  ///
+  EfiMemoryMappedIOPortSpace,
+  ///
+  /// Address space reserved by the firmware for code that is part of the processor.
+  ///
+  EfiPalCode,
+  EfiMaxMemoryType
+} EFI_MEMORY_TYPE;
+
+///
+/// Data structure that precedes all of the standard EFI table types.
+///
+typedef struct {
+  ///
+  /// A 64-bit signature that identifies the type of table that follows.
+  /// Unique signatures have been generated for the EFI System Table,
+  /// the EFI Boot Services Table, and the EFI Runtime Services Table.
+  ///
+  UINT64  Signature;
+  ///
+  /// The revision of the EFI Specification to which this table
+  /// conforms. The upper 16 bits of this field contain the major
+  /// revision value, and the lower 16 bits contain the minor revision
+  /// value. The minor revision values are limited to the range of 00..99.
+  ///
+  UINT32  Revision;
+  ///
+  /// The size, in bytes, of the entire table including the EFI_TABLE_HEADER.
+  ///
+  UINT32  HeaderSize;
+  ///
+  /// The 32-bit CRC for the entire table. This value is computed by
+  /// setting this field to 0, and computing the 32-bit CRC for HeaderSize bytes.
+  ///
+  UINT32  CRC32;
+  ///
+  /// Reserved field that must be set to 0.
+  ///
+  UINT32  Reserved;
+} EFI_TABLE_HEADER;
+
+///
+/// Attributes of variable.
+///
+#define EFI_VARIABLE_NON_VOLATILE                            0x00000001
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS                      0x00000002
+#define EFI_VARIABLE_RUNTIME_ACCESS                          0x00000004
+///
+/// This attribute is identified by the mnemonic 'HR'
+/// elsewhere in this specification.
+///
+#define EFI_VARIABLE_HARDWARE_ERROR_RECORD                   0x00000008
+///
+/// Attributes of Authenticated Variable
+///
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS              0x00000010
+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS   0x00000020
+#define EFI_VARIABLE_APPEND_WRITE                            0x00000040
+
+
+///
+/// AuthInfo is a WIN_CERTIFICATE using the wCertificateType
+/// WIN_CERTIFICATE_UEFI_GUID and the CertType
+/// EFI_CERT_TYPE_RSA2048_SHA256_GUID. If the attribute specifies
+/// authenticated access, then the Data buffer should begin with an
+/// authentication descriptor prior to the data payload and DataSize
+/// should reflect the the data.and descriptor size. The caller
+/// shall digest the Monotonic Count value and the associated data
+/// for the variable update using the SHA-256 1-way hash algorithm.
+/// The ensuing the 32-byte digest will be signed using the private
+/// key associated w/ the public/private 2048-bit RSA key-pair. The
+/// WIN_CERTIFICATE shall be used to describe the signature of the
+/// Variable data *Data. In addition, the signature will also
+/// include the MonotonicCount value to guard against replay attacks.
+///
+typedef struct {
+  ///
+  /// Included in the signature of
+  /// AuthInfo.Used to ensure freshness/no
+  /// replay. Incremented during each
+  /// "Write" access.
+  ///
+  UINT64                      MonotonicCount;
+  ///
+  /// Provides the authorization for the variable
+  /// access. It is a signature across the
+  /// variable data and the  Monotonic Count
+  /// value. Caller uses Private key that is
+  /// associated with a public key that has been
+  /// provisioned via the key exchange.
+  ///
+  WIN_CERTIFICATE_UEFI_GUID   AuthInfo;
+} EFI_VARIABLE_AUTHENTICATION;
+
+///
+/// When the attribute EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS is
+/// set, then the Data buffer shall begin with an instance of a complete (and serialized)
+/// EFI_VARIABLE_AUTHENTICATION_2 descriptor. The descriptor shall be followed by the new
+/// variable value and DataSize shall reflect the combined size of the descriptor and the new
+/// variable value. The authentication descriptor is not part of the variable data and is not
+/// returned by subsequent calls to GetVariable().
+///
+typedef struct {
+  ///
+  /// For the TimeStamp value, components Pad1, Nanosecond, TimeZone, Daylight and
+  /// Pad2 shall be set to 0. This means that the time shall always be expressed in GMT.
+  ///
+  EFI_TIME                    TimeStamp;
+  ///
+  /// Only a CertType of  EFI_CERT_TYPE_PKCS7_GUID is accepted.
+  ///
+  WIN_CERTIFICATE_UEFI_GUID   AuthInfo;
+ } EFI_VARIABLE_AUTHENTICATION_2;
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/Uefi/UefiPxe.h b/wimboot/wimboot-2.7.3/src/efi/Uefi/UefiPxe.h
new file mode 100644 (file)
index 0000000..15faf10
--- /dev/null
@@ -0,0 +1,1772 @@
+/** @file
+  This header file contains all of the PXE type definitions,
+  structure prototypes, global variables and constants that
+  are needed for porting PXE to EFI.
+
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+  @par Revision Reference:
+  32/64-bit PXE specification:
+  alpha-4, 99-Dec-17.
+
+**/
+
+#ifndef __EFI_PXE_H__
+#define __EFI_PXE_H__
+
+#pragma pack(1)
+
+#define PXE_BUSTYPE(a, b, c, d) \
+    ( \
+      (((PXE_UINT32) (d) & 0xFF) << 24) | (((PXE_UINT32) (c) & 0xFF) << 16) | (((PXE_UINT32) (b) & 0xFF) << 8) | \
+        ((PXE_UINT32) (a) & 0xFF) \
+    )
+
+///
+/// UNDI ROM ID and devive ID signature.
+///
+#define PXE_BUSTYPE_PXE PXE_BUSTYPE ('!', 'P', 'X', 'E')
+
+///
+/// BUS ROM ID signatures.
+///
+#define PXE_BUSTYPE_PCI     PXE_BUSTYPE ('P', 'C', 'I', 'R')
+#define PXE_BUSTYPE_PC_CARD PXE_BUSTYPE ('P', 'C', 'C', 'R')
+#define PXE_BUSTYPE_USB     PXE_BUSTYPE ('U', 'S', 'B', 'R')
+#define PXE_BUSTYPE_1394    PXE_BUSTYPE ('1', '3', '9', '4')
+
+#define PXE_SWAP_UINT16(n)  ((((PXE_UINT16) (n) & 0x00FF) << 8) | (((PXE_UINT16) (n) & 0xFF00) >> 8))
+
+#define PXE_SWAP_UINT32(n) \
+  ((((PXE_UINT32)(n) & 0x000000FF) << 24) | \
+   (((PXE_UINT32)(n) & 0x0000FF00) << 8)  | \
+   (((PXE_UINT32)(n) & 0x00FF0000) >> 8)  | \
+   (((PXE_UINT32)(n) & 0xFF000000) >> 24))
+
+#define PXE_SWAP_UINT64(n) \
+  ((((PXE_UINT64)(n) & 0x00000000000000FFULL) << 56) | \
+   (((PXE_UINT64)(n) & 0x000000000000FF00ULL) << 40) | \
+   (((PXE_UINT64)(n) & 0x0000000000FF0000ULL) << 24) | \
+   (((PXE_UINT64)(n) & 0x00000000FF000000ULL) << 8)  | \
+   (((PXE_UINT64)(n) & 0x000000FF00000000ULL) >> 8)  | \
+   (((PXE_UINT64)(n) & 0x0000FF0000000000ULL) >> 24) | \
+   (((PXE_UINT64)(n) & 0x00FF000000000000ULL) >> 40) | \
+   (((PXE_UINT64)(n) & 0xFF00000000000000ULL) >> 56))
+
+
+#define PXE_CPBSIZE_NOT_USED  0               ///< zero
+#define PXE_DBSIZE_NOT_USED   0               ///< zero
+#define PXE_CPBADDR_NOT_USED  (PXE_UINT64) 0  ///< zero
+#define PXE_DBADDR_NOT_USED   (PXE_UINT64) 0  ///< zero
+#define PXE_CONST             CONST
+
+#define PXE_VOLATILE          volatile
+
+typedef VOID           PXE_VOID;
+typedef UINT8          PXE_UINT8;
+typedef UINT16         PXE_UINT16;
+typedef UINT32         PXE_UINT32;
+typedef UINTN          PXE_UINTN;
+
+///
+/// Typedef unsigned long PXE_UINT64.
+///
+typedef UINT64      PXE_UINT64;
+
+typedef PXE_UINT8 PXE_BOOL;
+#define PXE_FALSE 0            ///< zero
+#define PXE_TRUE  (!PXE_FALSE)
+
+typedef PXE_UINT16      PXE_OPCODE;
+
+///
+/// Return UNDI operational state.
+///
+#define PXE_OPCODE_GET_STATE  0x0000
+
+///
+/// Change UNDI operational state from Stopped to Started.
+///
+#define PXE_OPCODE_START  0x0001
+
+///
+/// Change UNDI operational state from Started to Stopped.
+///
+#define PXE_OPCODE_STOP 0x0002
+
+///
+/// Get UNDI initialization information.
+///
+#define PXE_OPCODE_GET_INIT_INFO  0x0003
+
+///
+/// Get NIC configuration information.
+///
+#define PXE_OPCODE_GET_CONFIG_INFO  0x0004
+
+///
+/// Changed UNDI operational state from Started to Initialized.
+///
+#define PXE_OPCODE_INITIALIZE 0x0005
+
+///
+/// Re-initialize the NIC H/W.
+///
+#define PXE_OPCODE_RESET  0x0006
+
+///
+/// Change the UNDI operational state from Initialized to Started.
+///
+#define PXE_OPCODE_SHUTDOWN 0x0007
+
+///
+/// Read & change state of external interrupt enables.
+///
+#define PXE_OPCODE_INTERRUPT_ENABLES  0x0008
+
+///
+/// Read & change state of packet receive filters.
+///
+#define PXE_OPCODE_RECEIVE_FILTERS  0x0009
+
+///
+/// Read & change station MAC address.
+///
+#define PXE_OPCODE_STATION_ADDRESS  0x000A
+
+///
+/// Read traffic statistics.
+///
+#define PXE_OPCODE_STATISTICS 0x000B
+
+///
+/// Convert multicast IP address to multicast MAC address.
+///
+#define PXE_OPCODE_MCAST_IP_TO_MAC  0x000C
+
+///
+/// Read or change non-volatile storage on the NIC.
+///
+#define PXE_OPCODE_NVDATA 0x000D
+
+///
+/// Get & clear interrupt status.
+///
+#define PXE_OPCODE_GET_STATUS 0x000E
+
+///
+/// Fill media header in packet for transmit.
+///
+#define PXE_OPCODE_FILL_HEADER  0x000F
+
+///
+/// Transmit packet(s).
+///
+#define PXE_OPCODE_TRANSMIT 0x0010
+
+///
+/// Receive packet.
+///
+#define PXE_OPCODE_RECEIVE  0x0011
+
+///
+/// Last valid PXE UNDI OpCode number.
+///
+#define PXE_OPCODE_LAST_VALID 0x0011
+
+typedef PXE_UINT16  PXE_OPFLAGS;
+
+#define PXE_OPFLAGS_NOT_USED  0x0000
+
+//
+// //////////////////////////////////////
+// UNDI Get State
+//
+// No OpFlags
+
+////////////////////////////////////////
+// UNDI Start
+//
+// No OpFlags
+
+////////////////////////////////////////
+// UNDI Stop
+//
+// No OpFlags
+
+////////////////////////////////////////
+// UNDI Get Init Info
+//
+// No Opflags
+
+////////////////////////////////////////
+// UNDI Get Config Info
+//
+// No Opflags
+
+///
+/// UNDI Initialize
+///
+#define PXE_OPFLAGS_INITIALIZE_CABLE_DETECT_MASK    0x0001
+#define PXE_OPFLAGS_INITIALIZE_DETECT_CABLE         0x0000
+#define PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE  0x0001
+
+///
+///
+/// UNDI Reset
+///
+#define PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS  0x0001
+#define PXE_OPFLAGS_RESET_DISABLE_FILTERS     0x0002
+
+///
+/// UNDI Shutdown.
+///
+/// No OpFlags.
+
+///
+/// UNDI Interrupt Enables.
+///
+///
+/// Select whether to enable or disable external interrupt signals.
+/// Setting both enable and disable will return PXE_STATCODE_INVALID_OPFLAGS.
+///
+#define PXE_OPFLAGS_INTERRUPT_OPMASK  0xC000
+#define PXE_OPFLAGS_INTERRUPT_ENABLE  0x8000
+#define PXE_OPFLAGS_INTERRUPT_DISABLE 0x4000
+#define PXE_OPFLAGS_INTERRUPT_READ    0x0000
+
+///
+/// Enable receive interrupts.  An external interrupt will be generated
+/// after a complete non-error packet has been received.
+///
+#define PXE_OPFLAGS_INTERRUPT_RECEIVE 0x0001
+
+///
+/// Enable transmit interrupts.  An external interrupt will be generated
+/// after a complete non-error packet has been transmitted.
+///
+#define PXE_OPFLAGS_INTERRUPT_TRANSMIT  0x0002
+
+///
+/// Enable command interrupts.  An external interrupt will be generated
+/// when command execution stops.
+///
+#define PXE_OPFLAGS_INTERRUPT_COMMAND 0x0004
+
+///
+/// Generate software interrupt.  Setting this bit generates an external
+/// interrupt, if it is supported by the hardware.
+///
+#define PXE_OPFLAGS_INTERRUPT_SOFTWARE  0x0008
+
+///
+/// UNDI Receive Filters.
+///
+///
+/// Select whether to enable or disable receive filters.
+/// Setting both enable and disable will return PXE_STATCODE_INVALID_OPCODE.
+///
+#define PXE_OPFLAGS_RECEIVE_FILTER_OPMASK   0xC000
+#define PXE_OPFLAGS_RECEIVE_FILTER_ENABLE   0x8000
+#define PXE_OPFLAGS_RECEIVE_FILTER_DISABLE  0x4000
+#define PXE_OPFLAGS_RECEIVE_FILTER_READ     0x0000
+
+///
+/// To reset the contents of the multicast MAC address filter list,
+/// set this OpFlag:
+///
+#define PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST 0x2000
+
+///
+/// Enable unicast packet receiving.  Packets sent to the current station
+/// MAC address will be received.
+///
+#define PXE_OPFLAGS_RECEIVE_FILTER_UNICAST  0x0001
+
+///
+/// Enable broadcast packet receiving.  Packets sent to the broadcast
+/// MAC address will be received.
+///
+#define PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST  0x0002
+
+///
+/// Enable filtered multicast packet receiving.  Packets sent to any
+/// of the multicast MAC addresses in the multicast MAC address filter
+/// list will be received.  If the filter list is empty, no multicast
+///
+#define PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST 0x0004
+
+///
+/// Enable promiscuous packet receiving.  All packets will be received.
+///
+#define PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS  0x0008
+
+///
+/// Enable promiscuous multicast packet receiving.  All multicast
+/// packets will be received.
+///
+#define PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST  0x0010
+
+///
+/// UNDI Station Address.
+///
+#define PXE_OPFLAGS_STATION_ADDRESS_READ   0x0000
+#define PXE_OPFLAGS_STATION_ADDRESS_WRITE  0x0000
+#define PXE_OPFLAGS_STATION_ADDRESS_RESET  0x0001
+
+///
+/// UNDI Statistics.
+///
+#define PXE_OPFLAGS_STATISTICS_READ   0x0000
+#define PXE_OPFLAGS_STATISTICS_RESET  0x0001
+
+///
+/// UNDI MCast IP to MAC.
+///
+///
+/// Identify the type of IP address in the CPB.
+///
+#define PXE_OPFLAGS_MCAST_IP_TO_MAC_OPMASK  0x0003
+#define PXE_OPFLAGS_MCAST_IPV4_TO_MAC       0x0000
+#define PXE_OPFLAGS_MCAST_IPV6_TO_MAC       0x0001
+
+///
+/// UNDI NvData.
+///
+///
+/// Select the type of non-volatile data operation.
+///
+#define PXE_OPFLAGS_NVDATA_OPMASK 0x0001
+#define PXE_OPFLAGS_NVDATA_READ   0x0000
+#define PXE_OPFLAGS_NVDATA_WRITE  0x0001
+
+///
+/// UNDI Get Status.
+///
+///
+/// Return current interrupt status.  This will also clear any interrupts
+/// that are currently set.  This can be used in a polling routine.  The
+/// interrupt flags are still set and cleared even when the interrupts
+/// are disabled.
+///
+#define PXE_OPFLAGS_GET_INTERRUPT_STATUS  0x0001
+
+///
+/// Return list of transmitted buffers for recycling.  Transmit buffers
+/// must not be changed or unallocated until they have recycled.  After
+/// issuing a transmit command, wait for a transmit complete interrupt.
+/// When a transmit complete interrupt is received, read the transmitted
+/// buffers.  Do not plan on getting one buffer per interrupt.  Some
+/// NICs and UNDIs may transmit multiple buffers per interrupt.
+///
+#define PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS 0x0002
+
+///
+/// Return current media status.
+///
+#define PXE_OPFLAGS_GET_MEDIA_STATUS    0x0004
+
+///
+/// UNDI Fill Header.
+///
+#define PXE_OPFLAGS_FILL_HEADER_OPMASK      0x0001
+#define PXE_OPFLAGS_FILL_HEADER_FRAGMENTED  0x0001
+#define PXE_OPFLAGS_FILL_HEADER_WHOLE       0x0000
+
+///
+/// UNDI Transmit.
+///
+///
+/// S/W UNDI only.  Return after the packet has been transmitted.  A
+/// transmit complete interrupt will still be generated and the transmit
+/// buffer will have to be recycled.
+///
+#define PXE_OPFLAGS_SWUNDI_TRANSMIT_OPMASK  0x0001
+#define PXE_OPFLAGS_TRANSMIT_BLOCK          0x0001
+#define PXE_OPFLAGS_TRANSMIT_DONT_BLOCK     0x0000
+
+#define PXE_OPFLAGS_TRANSMIT_OPMASK     0x0002
+#define PXE_OPFLAGS_TRANSMIT_FRAGMENTED 0x0002
+#define PXE_OPFLAGS_TRANSMIT_WHOLE      0x0000
+
+///
+/// UNDI Receive.
+///
+/// No OpFlags.
+///
+
+///
+/// PXE STATFLAGS.
+///
+typedef PXE_UINT16  PXE_STATFLAGS;
+
+#define PXE_STATFLAGS_INITIALIZE  0x0000
+
+///
+/// Common StatFlags that can be returned by all commands.
+///
+///
+/// The COMMAND_COMPLETE and COMMAND_FAILED status flags must be
+/// implemented by all UNDIs.  COMMAND_QUEUED is only needed by UNDIs
+/// that support command queuing.
+///
+#define PXE_STATFLAGS_STATUS_MASK       0xC000
+#define PXE_STATFLAGS_COMMAND_COMPLETE  0xC000
+#define PXE_STATFLAGS_COMMAND_FAILED    0x8000
+#define PXE_STATFLAGS_COMMAND_QUEUED    0x4000
+
+///
+/// UNDI Get State.
+///
+#define PXE_STATFLAGS_GET_STATE_MASK        0x0003
+#define PXE_STATFLAGS_GET_STATE_INITIALIZED 0x0002
+#define PXE_STATFLAGS_GET_STATE_STARTED     0x0001
+#define PXE_STATFLAGS_GET_STATE_STOPPED     0x0000
+
+///
+/// UNDI Start.
+///
+/// No additional StatFlags.
+///
+
+///
+/// UNDI Get Init Info.
+///
+#define PXE_STATFLAGS_CABLE_DETECT_MASK           0x0001
+#define PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED  0x0000
+#define PXE_STATFLAGS_CABLE_DETECT_SUPPORTED      0x0001
+
+#define PXE_STATFLAGS_GET_STATUS_NO_MEDIA_MASK           0x0002
+#define PXE_STATFLAGS_GET_STATUS_NO_MEDIA_NOT_SUPPORTED  0x0000
+#define PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED      0x0002
+
+///
+/// UNDI Initialize.
+///
+#define PXE_STATFLAGS_INITIALIZED_NO_MEDIA  0x0001
+
+///
+/// UNDI Reset.
+///
+#define PXE_STATFLAGS_RESET_NO_MEDIA  0x0001
+
+///
+/// UNDI Shutdown.
+///
+/// No additional StatFlags.
+
+///
+/// UNDI Interrupt Enables.
+///
+///
+/// If set, receive interrupts are enabled.
+///
+#define PXE_STATFLAGS_INTERRUPT_RECEIVE 0x0001
+
+///
+/// If set, transmit interrupts are enabled.
+///
+#define PXE_STATFLAGS_INTERRUPT_TRANSMIT  0x0002
+
+///
+/// If set, command interrupts are enabled.
+///
+#define PXE_STATFLAGS_INTERRUPT_COMMAND 0x0004
+
+///
+/// UNDI Receive Filters.
+///
+
+///
+/// If set, unicast packets will be received.
+///
+#define PXE_STATFLAGS_RECEIVE_FILTER_UNICAST  0x0001
+
+///
+/// If set, broadcast packets will be received.
+///
+#define PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST  0x0002
+
+///
+/// If set, multicast packets that match up with the multicast address
+/// filter list will be received.
+///
+#define PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST 0x0004
+
+///
+/// If set, all packets will be received.
+///
+#define PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS  0x0008
+
+///
+/// If set, all multicast packets will be received.
+///
+#define PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST  0x0010
+
+///
+/// UNDI Station Address.
+///
+/// No additional StatFlags.
+///
+
+///
+/// UNDI Statistics.
+///
+/// No additional StatFlags.
+///
+
+///
+//// UNDI MCast IP to MAC.
+////
+//// No additional StatFlags.
+
+///
+/// UNDI NvData.
+///
+/// No additional StatFlags.
+///
+
+///
+/// UNDI Get Status.
+///
+
+///
+/// Use to determine if an interrupt has occurred.
+///
+#define PXE_STATFLAGS_GET_STATUS_INTERRUPT_MASK 0x000F
+#define PXE_STATFLAGS_GET_STATUS_NO_INTERRUPTS  0x0000
+
+///
+/// If set, at least one receive interrupt occurred.
+///
+#define PXE_STATFLAGS_GET_STATUS_RECEIVE  0x0001
+
+///
+/// If set, at least one transmit interrupt occurred.
+///
+#define PXE_STATFLAGS_GET_STATUS_TRANSMIT 0x0002
+
+///
+/// If set, at least one command interrupt occurred.
+///
+#define PXE_STATFLAGS_GET_STATUS_COMMAND  0x0004
+
+///
+/// If set, at least one software interrupt occurred.
+///
+#define PXE_STATFLAGS_GET_STATUS_SOFTWARE 0x0008
+
+///
+/// This flag is set if the transmitted buffer queue is empty.  This flag
+/// will be set if all transmitted buffer addresses get written into the DB.
+///
+#define PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY  0x0010
+
+///
+/// This flag is set if no transmitted buffer addresses were written
+/// into the DB.  (This could be because DBsize was too small.)
+///
+#define PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN  0x0020
+
+///
+/// This flag is set if there is no media detected.
+///
+#define PXE_STATFLAGS_GET_STATUS_NO_MEDIA  0x0040
+
+///
+/// UNDI Fill Header.
+///
+/// No additional StatFlags.
+///
+
+///
+/// UNDI Transmit.
+///
+/// No additional StatFlags.
+
+///
+/// UNDI Receive
+///.
+
+///
+/// No additional StatFlags.
+///
+typedef PXE_UINT16  PXE_STATCODE;
+
+#define PXE_STATCODE_INITIALIZE 0x0000
+
+///
+/// Common StatCodes returned by all UNDI commands, UNDI protocol functions
+/// and BC protocol functions.
+///
+#define PXE_STATCODE_SUCCESS              0x0000
+
+#define PXE_STATCODE_INVALID_CDB          0x0001
+#define PXE_STATCODE_INVALID_CPB          0x0002
+#define PXE_STATCODE_BUSY                 0x0003
+#define PXE_STATCODE_QUEUE_FULL           0x0004
+#define PXE_STATCODE_ALREADY_STARTED      0x0005
+#define PXE_STATCODE_NOT_STARTED          0x0006
+#define PXE_STATCODE_NOT_SHUTDOWN         0x0007
+#define PXE_STATCODE_ALREADY_INITIALIZED  0x0008
+#define PXE_STATCODE_NOT_INITIALIZED      0x0009
+#define PXE_STATCODE_DEVICE_FAILURE       0x000A
+#define PXE_STATCODE_NVDATA_FAILURE       0x000B
+#define PXE_STATCODE_UNSUPPORTED          0x000C
+#define PXE_STATCODE_BUFFER_FULL          0x000D
+#define PXE_STATCODE_INVALID_PARAMETER    0x000E
+#define PXE_STATCODE_INVALID_UNDI         0x000F
+#define PXE_STATCODE_IPV4_NOT_SUPPORTED   0x0010
+#define PXE_STATCODE_IPV6_NOT_SUPPORTED   0x0011
+#define PXE_STATCODE_NOT_ENOUGH_MEMORY    0x0012
+#define PXE_STATCODE_NO_DATA              0x0013
+
+typedef PXE_UINT16  PXE_IFNUM;
+
+///
+/// This interface number must be passed to the S/W UNDI Start command.
+///
+#define PXE_IFNUM_START 0x0000
+
+///
+/// This interface number is returned by the S/W UNDI Get State and
+/// Start commands if information in the CDB, CPB or DB is invalid.
+///
+#define PXE_IFNUM_INVALID 0x0000
+
+typedef PXE_UINT16  PXE_CONTROL;
+
+///
+/// Setting this flag directs the UNDI to queue this command for later
+/// execution if the UNDI is busy and it supports command queuing.
+/// If queuing is not supported, a PXE_STATCODE_INVALID_CONTROL error
+/// is returned.  If the queue is full, a PXE_STATCODE_CDB_QUEUE_FULL
+/// error is returned.
+///
+#define PXE_CONTROL_QUEUE_IF_BUSY 0x0002
+
+///
+/// These two bit values are used to determine if there are more UNDI
+/// CDB structures following this one.  If the link bit is set, there
+/// must be a CDB structure following this one.  Execution will start
+/// on the next CDB structure as soon as this one completes successfully.
+/// If an error is generated by this command, execution will stop.
+///
+#define PXE_CONTROL_LINK              0x0001
+#define PXE_CONTROL_LAST_CDB_IN_LIST  0x0000
+
+typedef PXE_UINT8   PXE_FRAME_TYPE;
+
+#define PXE_FRAME_TYPE_NONE                     0x00
+#define PXE_FRAME_TYPE_UNICAST                  0x01
+#define PXE_FRAME_TYPE_BROADCAST                0x02
+#define PXE_FRAME_TYPE_FILTERED_MULTICAST       0x03
+#define PXE_FRAME_TYPE_PROMISCUOUS              0x04
+#define PXE_FRAME_TYPE_PROMISCUOUS_MULTICAST    0x05
+
+#define PXE_FRAME_TYPE_MULTICAST                PXE_FRAME_TYPE_FILTERED_MULTICAST
+
+typedef PXE_UINT32  PXE_IPV4;
+
+typedef PXE_UINT32  PXE_IPV6[4];
+#define PXE_MAC_LENGTH  32
+
+typedef PXE_UINT8   PXE_MAC_ADDR[PXE_MAC_LENGTH];
+
+typedef PXE_UINT8   PXE_IFTYPE;
+typedef UINT16      PXE_MEDIA_PROTOCOL;
+
+///
+/// This information is from the ARP section of RFC 1700.
+///
+///     1 Ethernet (10Mb)                                    [JBP]
+///     2 Experimental Ethernet (3Mb)                        [JBP]
+///     3 Amateur Radio AX.25                                [PXK]
+///     4 Proteon ProNET Token Ring                          [JBP]
+///     5 Chaos                                              [GXP]
+///     6 IEEE 802 Networks                                  [JBP]
+///     7 ARCNET                                             [JBP]
+///     8 Hyperchannel                                       [JBP]
+///     9 Lanstar                                             [TU]
+///    10 Autonet Short Address                             [MXB1]
+///    11 LocalTalk                                         [JKR1]
+///    12 LocalNet (IBM* PCNet or SYTEK* LocalNET)           [JXM]
+///    13 Ultra link                                        [RXD2]
+///    14 SMDS                                              [GXC1]
+///    15 Frame Relay                                        [AGM]
+///    16 Asynchronous Transmission Mode (ATM)              [JXB2]
+///    17 HDLC                                               [JBP]
+///    18 Fibre Channel                            [Yakov Rekhter]
+///    19 Asynchronous Transmission Mode (ATM)      [Mark Laubach]
+///    20 Serial Line                                        [JBP]
+///    21 Asynchronous Transmission Mode (ATM)              [MXB1]
+///
+/// * Other names and brands may be claimed as the property of others.
+///
+#define PXE_IFTYPE_ETHERNET       0x01
+#define PXE_IFTYPE_TOKENRING      0x04
+#define PXE_IFTYPE_FIBRE_CHANNEL  0x12
+
+typedef struct s_pxe_hw_undi {
+  PXE_UINT32  Signature;      ///< PXE_ROMID_SIGNATURE.
+  PXE_UINT8   Len;            ///< sizeof(PXE_HW_UNDI).
+  PXE_UINT8   Fudge;          ///< makes 8-bit cksum equal zero.
+  PXE_UINT8   Rev;            ///< PXE_ROMID_REV.
+  PXE_UINT8   IFcnt;          ///< physical connector count lower byte.
+  PXE_UINT8   MajorVer;       ///< PXE_ROMID_MAJORVER.
+  PXE_UINT8   MinorVer;       ///< PXE_ROMID_MINORVER.
+  PXE_UINT8   IFcntExt;       ///< physical connector count upper byte.
+  PXE_UINT8   reserved;       ///< zero, not used.
+  PXE_UINT32  Implementation; ///< implementation flags.
+  ///< reserved             ///< vendor use.
+  ///< UINT32 Status;       ///< status port.
+  ///< UINT32 Command;      ///< command port.
+  ///< UINT64 CDBaddr;      ///< CDB address port.
+  ///<
+} PXE_HW_UNDI;
+
+///
+/// Status port bit definitions.
+///
+
+///
+/// UNDI operation state.
+///
+#define PXE_HWSTAT_STATE_MASK   0xC0000000
+#define PXE_HWSTAT_BUSY         0xC0000000
+#define PXE_HWSTAT_INITIALIZED  0x80000000
+#define PXE_HWSTAT_STARTED      0x40000000
+#define PXE_HWSTAT_STOPPED      0x00000000
+
+///
+/// If set, last command failed.
+///
+#define PXE_HWSTAT_COMMAND_FAILED 0x20000000
+
+///
+/// If set, identifies enabled receive filters.
+///
+#define PXE_HWSTAT_PROMISCUOUS_MULTICAST_RX_ENABLED 0x00001000
+#define PXE_HWSTAT_PROMISCUOUS_RX_ENABLED           0x00000800
+#define PXE_HWSTAT_BROADCAST_RX_ENABLED             0x00000400
+#define PXE_HWSTAT_MULTICAST_RX_ENABLED             0x00000200
+#define PXE_HWSTAT_UNICAST_RX_ENABLED               0x00000100
+
+///
+/// If set, identifies enabled external interrupts.
+///
+#define PXE_HWSTAT_SOFTWARE_INT_ENABLED     0x00000080
+#define PXE_HWSTAT_TX_COMPLETE_INT_ENABLED  0x00000040
+#define PXE_HWSTAT_PACKET_RX_INT_ENABLED    0x00000020
+#define PXE_HWSTAT_CMD_COMPLETE_INT_ENABLED 0x00000010
+
+///
+/// If set, identifies pending interrupts.
+///
+#define PXE_HWSTAT_SOFTWARE_INT_PENDING     0x00000008
+#define PXE_HWSTAT_TX_COMPLETE_INT_PENDING  0x00000004
+#define PXE_HWSTAT_PACKET_RX_INT_PENDING    0x00000002
+#define PXE_HWSTAT_CMD_COMPLETE_INT_PENDING 0x00000001
+
+///
+/// Command port definitions.
+///
+
+///
+/// If set, CDB identified in CDBaddr port is given to UNDI.
+/// If not set, other bits in this word will be processed.
+///
+#define PXE_HWCMD_ISSUE_COMMAND   0x80000000
+#define PXE_HWCMD_INTS_AND_FILTS  0x00000000
+
+///
+/// Use these to enable/disable receive filters.
+///
+#define PXE_HWCMD_PROMISCUOUS_MULTICAST_RX_ENABLE 0x00001000
+#define PXE_HWCMD_PROMISCUOUS_RX_ENABLE           0x00000800
+#define PXE_HWCMD_BROADCAST_RX_ENABLE             0x00000400
+#define PXE_HWCMD_MULTICAST_RX_ENABLE             0x00000200
+#define PXE_HWCMD_UNICAST_RX_ENABLE               0x00000100
+
+///
+/// Use these to enable/disable external interrupts.
+///
+#define PXE_HWCMD_SOFTWARE_INT_ENABLE     0x00000080
+#define PXE_HWCMD_TX_COMPLETE_INT_ENABLE  0x00000040
+#define PXE_HWCMD_PACKET_RX_INT_ENABLE    0x00000020
+#define PXE_HWCMD_CMD_COMPLETE_INT_ENABLE 0x00000010
+
+///
+/// Use these to clear pending external interrupts.
+///
+#define PXE_HWCMD_CLEAR_SOFTWARE_INT      0x00000008
+#define PXE_HWCMD_CLEAR_TX_COMPLETE_INT   0x00000004
+#define PXE_HWCMD_CLEAR_PACKET_RX_INT     0x00000002
+#define PXE_HWCMD_CLEAR_CMD_COMPLETE_INT  0x00000001
+
+typedef struct s_pxe_sw_undi {
+  PXE_UINT32  Signature;      ///< PXE_ROMID_SIGNATURE.
+  PXE_UINT8   Len;            ///< sizeof(PXE_SW_UNDI).
+  PXE_UINT8   Fudge;          ///< makes 8-bit cksum zero.
+  PXE_UINT8   Rev;            ///< PXE_ROMID_REV.
+  PXE_UINT8   IFcnt;          ///< physical connector count lower byte.
+  PXE_UINT8   MajorVer;       ///< PXE_ROMID_MAJORVER.
+  PXE_UINT8   MinorVer;       ///< PXE_ROMID_MINORVER.
+  PXE_UINT8   IFcntExt;       ///< physical connector count upper byte.
+  PXE_UINT8   reserved1;      ///< zero, not used.
+  PXE_UINT32  Implementation; ///< Implementation flags.
+  PXE_UINT64  EntryPoint;     ///< API entry point.
+  PXE_UINT8   reserved2[3];   ///< zero, not used.
+  PXE_UINT8   BusCnt;         ///< number of bustypes supported.
+  PXE_UINT32  BusType[1];     ///< list of supported bustypes.
+} PXE_SW_UNDI;
+
+typedef union u_pxe_undi {
+  PXE_HW_UNDI hw;
+  PXE_SW_UNDI sw;
+} PXE_UNDI;
+
+///
+/// Signature of !PXE structure.
+///
+#define PXE_ROMID_SIGNATURE PXE_BUSTYPE ('!', 'P', 'X', 'E')
+
+///
+/// !PXE structure format revision
+///.
+#define PXE_ROMID_REV 0x02
+
+///
+/// UNDI command interface revision.  These are the values that get sent
+/// in option 94 (Client Network Interface Identifier) in the DHCP Discover
+/// and PXE Boot Server Request packets.
+///
+#define PXE_ROMID_MAJORVER    0x03
+#define PXE_ROMID_MINORVER    0x01
+
+///
+/// Implementation flags.
+///
+#define PXE_ROMID_IMP_HW_UNDI                             0x80000000
+#define PXE_ROMID_IMP_SW_VIRT_ADDR                        0x40000000
+#define PXE_ROMID_IMP_64BIT_DEVICE                        0x00010000
+#define PXE_ROMID_IMP_FRAG_SUPPORTED                      0x00008000
+#define PXE_ROMID_IMP_CMD_LINK_SUPPORTED                  0x00004000
+#define PXE_ROMID_IMP_CMD_QUEUE_SUPPORTED                 0x00002000
+#define PXE_ROMID_IMP_MULTI_FRAME_SUPPORTED               0x00001000
+#define PXE_ROMID_IMP_NVDATA_SUPPORT_MASK                 0x00000C00
+#define PXE_ROMID_IMP_NVDATA_BULK_WRITABLE                0x00000C00
+#define PXE_ROMID_IMP_NVDATA_SPARSE_WRITABLE              0x00000800
+#define PXE_ROMID_IMP_NVDATA_READ_ONLY                    0x00000400
+#define PXE_ROMID_IMP_NVDATA_NOT_AVAILABLE                0x00000000
+#define PXE_ROMID_IMP_STATISTICS_SUPPORTED                0x00000200
+#define PXE_ROMID_IMP_STATION_ADDR_SETTABLE               0x00000100
+#define PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED  0x00000080
+#define PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED            0x00000040
+#define PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED              0x00000020
+#define PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED     0x00000010
+#define PXE_ROMID_IMP_SOFTWARE_INT_SUPPORTED              0x00000008
+#define PXE_ROMID_IMP_TX_COMPLETE_INT_SUPPORTED           0x00000004
+#define PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED             0x00000002
+#define PXE_ROMID_IMP_CMD_COMPLETE_INT_SUPPORTED          0x00000001
+
+typedef struct s_pxe_cdb {
+  PXE_OPCODE    OpCode;
+  PXE_OPFLAGS   OpFlags;
+  PXE_UINT16    CPBsize;
+  PXE_UINT16    DBsize;
+  PXE_UINT64    CPBaddr;
+  PXE_UINT64    DBaddr;
+  PXE_STATCODE  StatCode;
+  PXE_STATFLAGS StatFlags;
+  PXE_UINT16    IFnum;
+  PXE_CONTROL   Control;
+} PXE_CDB;
+
+typedef union u_pxe_ip_addr {
+  PXE_IPV6  IPv6;
+  PXE_IPV4  IPv4;
+} PXE_IP_ADDR;
+
+typedef union pxe_device {
+  ///
+  /// PCI and PC Card NICs are both identified using bus, device
+  /// and function numbers.  For PC Card, this may require PC
+  /// Card services to be loaded in the BIOS or preboot
+  /// environment.
+  ///
+  struct {
+    ///
+    /// See S/W UNDI ROMID structure definition for PCI and
+    /// PCC BusType definitions.
+    ///
+    PXE_UINT32  BusType;
+
+    ///
+    /// Bus, device & function numbers that locate this device.
+    ///
+    PXE_UINT16  Bus;
+    PXE_UINT8   Device;
+    PXE_UINT8   Function;
+  }
+  PCI, PCC;
+
+} PXE_DEVICE;
+
+///
+/// cpb and db definitions
+///
+#define MAX_PCI_CONFIG_LEN    64  ///< # of dwords.
+#define MAX_EEPROM_LEN        128 ///< # of dwords.
+#define MAX_XMIT_BUFFERS      32  ///< recycling Q length for xmit_done.
+#define MAX_MCAST_ADDRESS_CNT 8
+
+typedef struct s_pxe_cpb_start_30 {
+  ///
+  /// PXE_VOID Delay(UINTN microseconds);
+  ///
+  /// UNDI will never request a delay smaller than 10 microseconds
+  /// and will always request delays in increments of 10 microseconds.
+  /// The Delay() CallBack routine must delay between n and n + 10
+  /// microseconds before returning control to the UNDI.
+  ///
+  /// This field cannot be set to zero.
+  ///
+  UINT64  Delay;
+
+  ///
+  /// PXE_VOID Block(UINT32 enable);
+  ///
+  /// UNDI may need to block multi-threaded/multi-processor access to
+  /// critical code sections when programming or accessing the network
+  /// device.  To this end, a blocking service is needed by the UNDI.
+  /// When UNDI needs a block, it will call Block() passing a non-zero
+  /// value.  When UNDI no longer needs a block, it will call Block()
+  /// with a zero value.  When called, if the Block() is already enabled,
+  /// do not return control to the UNDI until the previous Block() is
+  /// disabled.
+  ///
+  /// This field cannot be set to zero.
+  ///
+  UINT64  Block;
+
+  ///
+  /// PXE_VOID Virt2Phys(UINT64 virtual, UINT64 physical_ptr);
+  ///
+  /// UNDI will pass the virtual address of a buffer and the virtual
+  /// address of a 64-bit physical buffer.  Convert the virtual address
+  /// to a physical address and write the result to the physical address
+  /// buffer.  If virtual and physical addresses are the same, just
+  /// copy the virtual address to the physical address buffer.
+  ///
+  /// This field can be set to zero if virtual and physical addresses
+  /// are equal.
+  ///
+  UINT64  Virt2Phys;
+  ///
+  /// PXE_VOID Mem_IO(UINT8 read_write, UINT8 len, UINT64 port,
+  ///              UINT64 buf_addr);
+  ///
+  /// UNDI will read or write the device io space using this call back
+  /// function. It passes the number of bytes as the len parameter and it
+  /// will be either 1,2,4 or 8.
+  ///
+  /// This field can not be set to zero.
+  ///
+  UINT64  Mem_IO;
+} PXE_CPB_START_30;
+
+typedef struct s_pxe_cpb_start_31 {
+  ///
+  /// PXE_VOID Delay(UINT64 UnqId, UINTN microseconds);
+  ///
+  /// UNDI will never request a delay smaller than 10 microseconds
+  /// and will always request delays in increments of 10 microseconds.
+  /// The Delay() CallBack routine must delay between n and n + 10
+  /// microseconds before returning control to the UNDI.
+  ///
+  /// This field cannot be set to zero.
+  ///
+  UINT64  Delay;
+
+  ///
+  /// PXE_VOID Block(UINT64 unq_id, UINT32 enable);
+  ///
+  /// UNDI may need to block multi-threaded/multi-processor access to
+  /// critical code sections when programming or accessing the network
+  /// device.  To this end, a blocking service is needed by the UNDI.
+  /// When UNDI needs a block, it will call Block() passing a non-zero
+  /// value.  When UNDI no longer needs a block, it will call Block()
+  /// with a zero value.  When called, if the Block() is already enabled,
+  /// do not return control to the UNDI until the previous Block() is
+  /// disabled.
+  ///
+  /// This field cannot be set to zero.
+  ///
+  UINT64  Block;
+
+  ///
+  /// PXE_VOID Virt2Phys(UINT64 UnqId, UINT64 virtual, UINT64 physical_ptr);
+  ///
+  /// UNDI will pass the virtual address of a buffer and the virtual
+  /// address of a 64-bit physical buffer.  Convert the virtual address
+  /// to a physical address and write the result to the physical address
+  /// buffer.  If virtual and physical addresses are the same, just
+  /// copy the virtual address to the physical address buffer.
+  ///
+  /// This field can be set to zero if virtual and physical addresses
+  /// are equal.
+  ///
+  UINT64  Virt2Phys;
+  ///
+  /// PXE_VOID Mem_IO(UINT64 UnqId, UINT8 read_write, UINT8 len, UINT64 port,
+  ///              UINT64 buf_addr);
+  ///
+  /// UNDI will read or write the device io space using this call back
+  /// function. It passes the number of bytes as the len parameter and it
+  /// will be either 1,2,4 or 8.
+  ///
+  /// This field can not be set to zero.
+  ///
+  UINT64  Mem_IO;
+  ///
+  /// PXE_VOID Map_Mem(UINT64 unq_id, UINT64 virtual_addr, UINT32 size,
+  ///                 UINT32 Direction, UINT64 mapped_addr);
+  ///
+  /// UNDI will pass the virtual address of a buffer, direction of the data
+  /// flow from/to the mapped buffer (the constants are defined below)
+  /// and a place holder (pointer) for the mapped address.
+  /// This call will Map the given address to a physical DMA address and write
+  /// the result to the mapped_addr pointer.  If there is no need to
+  /// map the given address to a lower address (i.e. the given address is
+  /// associated with a physical address that is already compatible to be
+  /// used with the DMA, it converts the given virtual address to it's
+  /// physical address and write that in the mapped address pointer.
+  ///
+  /// This field can be set to zero if there is no mapping service available.
+  ///
+  UINT64  Map_Mem;
+
+  ///
+  /// PXE_VOID UnMap_Mem(UINT64 unq_id, UINT64 virtual_addr, UINT32 size,
+  ///            UINT32 Direction, UINT64 mapped_addr);
+  ///
+  /// UNDI will pass the virtual and mapped addresses of a buffer.
+  /// This call will un map the given address.
+  ///
+  /// This field can be set to zero if there is no unmapping service available.
+  ///
+  UINT64  UnMap_Mem;
+
+  ///
+  /// PXE_VOID Sync_Mem(UINT64 unq_id, UINT64 virtual,
+  ///            UINT32 size, UINT32 Direction, UINT64 mapped_addr);
+  ///
+  /// UNDI will pass the virtual and mapped addresses of a buffer.
+  /// This call will synchronize the contents of both the virtual and mapped.
+  /// buffers for the given Direction.
+  ///
+  /// This field can be set to zero if there is no service available.
+  ///
+  UINT64  Sync_Mem;
+
+  ///
+  /// protocol driver can provide anything for this Unique_ID, UNDI remembers
+  /// that as just a 64bit value assocaited to the interface specified by
+  /// the ifnum and gives it back as a parameter to all the call-back routines
+  /// when calling for that interface!
+  ///
+  UINT64  Unique_ID;
+} PXE_CPB_START_31;
+
+#define TO_AND_FROM_DEVICE    0
+#define FROM_DEVICE           1
+#define TO_DEVICE             2
+
+#define PXE_DELAY_MILLISECOND 1000
+#define PXE_DELAY_SECOND      1000000
+#define PXE_IO_READ           0
+#define PXE_IO_WRITE          1
+#define PXE_MEM_READ          2
+#define PXE_MEM_WRITE         4
+
+typedef struct s_pxe_db_get_init_info {
+  ///
+  /// Minimum length of locked memory buffer that must be given to
+  /// the Initialize command. Giving UNDI more memory will generally
+  /// give better performance.
+  ///
+  /// If MemoryRequired is zero, the UNDI does not need and will not
+  /// use system memory to receive and transmit packets.
+  ///
+  PXE_UINT32  MemoryRequired;
+
+  ///
+  /// Maximum frame data length for Tx/Rx excluding the media header.
+  ///
+  PXE_UINT32  FrameDataLen;
+
+  ///
+  /// Supported link speeds are in units of mega bits.  Common ethernet
+  /// values are 10, 100 and 1000.  Unused LinkSpeeds[] entries are zero
+  /// filled.
+  ///
+  PXE_UINT32  LinkSpeeds[4];
+
+  ///
+  /// Number of non-volatile storage items.
+  ///
+  PXE_UINT32  NvCount;
+
+  ///
+  /// Width of non-volatile storage item in bytes.  0, 1, 2 or 4
+  ///
+  PXE_UINT16  NvWidth;
+
+  ///
+  /// Media header length.  This is the typical media header length for
+  /// this UNDI.  This information is needed when allocating receive
+  /// and transmit buffers.
+  ///
+  PXE_UINT16  MediaHeaderLen;
+
+  ///
+  /// Number of bytes in the NIC hardware (MAC) address.
+  ///
+  PXE_UINT16  HWaddrLen;
+
+  ///
+  /// Maximum number of multicast MAC addresses in the multicast
+  /// MAC address filter list.
+  ///
+  PXE_UINT16  MCastFilterCnt;
+
+  ///
+  /// Default number and size of transmit and receive buffers that will
+  /// be allocated by the UNDI.  If MemoryRequired is non-zero, this
+  /// allocation will come out of the memory buffer given to the Initialize
+  /// command.  If MemoryRequired is zero, this allocation will come out of
+  /// memory on the NIC.
+  ///
+  PXE_UINT16  TxBufCnt;
+  PXE_UINT16  TxBufSize;
+  PXE_UINT16  RxBufCnt;
+  PXE_UINT16  RxBufSize;
+
+  ///
+  /// Hardware interface types defined in the Assigned Numbers RFC
+  /// and used in DHCP and ARP packets.
+  /// See the PXE_IFTYPE typedef and PXE_IFTYPE_xxx macros.
+  ///
+  PXE_UINT8   IFtype;
+
+  ///
+  /// Supported duplex.  See PXE_DUPLEX_xxxxx #defines below.
+  ///
+  PXE_UINT8   SupportedDuplexModes;
+
+  ///
+  /// Supported loopback options.  See PXE_LOOPBACK_xxxxx #defines below.
+  ///
+  PXE_UINT8   SupportedLoopBackModes;
+} PXE_DB_GET_INIT_INFO;
+
+#define PXE_MAX_TXRX_UNIT_ETHER           1500
+
+#define PXE_HWADDR_LEN_ETHER              0x0006
+#define PXE_MAC_HEADER_LEN_ETHER          0x000E
+
+#define PXE_DUPLEX_ENABLE_FULL_SUPPORTED  1
+#define PXE_DUPLEX_FORCE_FULL_SUPPORTED   2
+
+#define PXE_LOOPBACK_INTERNAL_SUPPORTED   1
+#define PXE_LOOPBACK_EXTERNAL_SUPPORTED   2
+
+typedef struct s_pxe_pci_config_info {
+  ///
+  /// This is the flag field for the PXE_DB_GET_CONFIG_INFO union.
+  /// For PCI bus devices, this field is set to PXE_BUSTYPE_PCI.
+  ///
+  UINT32  BusType;
+
+  ///
+  /// This identifies the PCI network device that this UNDI interface.
+  /// is bound to.
+  ///
+  UINT16  Bus;
+  UINT8   Device;
+  UINT8   Function;
+
+  ///
+  /// This is a copy of the PCI configuration space for this
+  /// network device.
+  ///
+  union {
+    UINT8   Byte[256];
+    UINT16  Word[128];
+    UINT32  Dword[64];
+  } Config;
+} PXE_PCI_CONFIG_INFO;
+
+typedef struct s_pxe_pcc_config_info {
+  ///
+  /// This is the flag field for the PXE_DB_GET_CONFIG_INFO union.
+  /// For PCC bus devices, this field is set to PXE_BUSTYPE_PCC.
+  ///
+  PXE_UINT32  BusType;
+
+  ///
+  /// This identifies the PCC network device that this UNDI interface
+  /// is bound to.
+  ///
+  PXE_UINT16  Bus;
+  PXE_UINT8   Device;
+  PXE_UINT8   Function;
+
+  ///
+  /// This is a copy of the PCC configuration space for this
+  /// network device.
+  ///
+  union {
+    PXE_UINT8   Byte[256];
+    PXE_UINT16  Word[128];
+    PXE_UINT32  Dword[64];
+  } Config;
+} PXE_PCC_CONFIG_INFO;
+
+typedef union u_pxe_db_get_config_info {
+  PXE_PCI_CONFIG_INFO   pci;
+  PXE_PCC_CONFIG_INFO   pcc;
+} PXE_DB_GET_CONFIG_INFO;
+
+typedef struct s_pxe_cpb_initialize {
+  ///
+  /// Address of first (lowest) byte of the memory buffer.  This buffer must
+  /// be in contiguous physical memory and cannot be swapped out.  The UNDI
+  /// will be using this for transmit and receive buffering.
+  ///
+  PXE_UINT64  MemoryAddr;
+
+  ///
+  /// MemoryLength must be greater than or equal to MemoryRequired
+  /// returned by the Get Init Info command.
+  ///
+  PXE_UINT32  MemoryLength;
+
+  ///
+  /// Desired link speed in Mbit/sec.  Common ethernet values are 10, 100
+  /// and 1000.  Setting a value of zero will auto-detect and/or use the
+  /// default link speed (operation depends on UNDI/NIC functionality).
+  ///
+  PXE_UINT32  LinkSpeed;
+
+  ///
+  /// Suggested number and size of receive and transmit buffers to
+  /// allocate.  If MemoryAddr and MemoryLength are non-zero, this
+  /// allocation comes out of the supplied memory buffer.  If MemoryAddr
+  /// and MemoryLength are zero, this allocation comes out of memory
+  /// on the NIC.
+  ///
+  /// If these fields are set to zero, the UNDI will allocate buffer
+  /// counts and sizes as it sees fit.
+  ///
+  PXE_UINT16  TxBufCnt;
+  PXE_UINT16  TxBufSize;
+  PXE_UINT16  RxBufCnt;
+  PXE_UINT16  RxBufSize;
+
+  ///
+  /// The following configuration parameters are optional and must be zero
+  /// to use the default values.
+  ///
+  PXE_UINT8   DuplexMode;
+
+  PXE_UINT8   LoopBackMode;
+} PXE_CPB_INITIALIZE;
+
+#define PXE_DUPLEX_DEFAULT      0x00
+#define PXE_FORCE_FULL_DUPLEX   0x01
+#define PXE_ENABLE_FULL_DUPLEX  0x02
+#define PXE_FORCE_HALF_DUPLEX   0x04
+#define PXE_DISABLE_FULL_DUPLEX 0x08
+
+#define LOOPBACK_NORMAL         0
+#define LOOPBACK_INTERNAL       1
+#define LOOPBACK_EXTERNAL       2
+
+typedef struct s_pxe_db_initialize {
+  ///
+  /// Actual amount of memory used from the supplied memory buffer.  This
+  /// may be less that the amount of memory suppllied and may be zero if
+  /// the UNDI and network device do not use external memory buffers.
+  ///
+  /// Memory used by the UNDI and network device is allocated from the
+  /// lowest memory buffer address.
+  ///
+  PXE_UINT32  MemoryUsed;
+
+  ///
+  /// Actual number and size of receive and transmit buffers that were
+  /// allocated.
+  ///
+  PXE_UINT16  TxBufCnt;
+  PXE_UINT16  TxBufSize;
+  PXE_UINT16  RxBufCnt;
+  PXE_UINT16  RxBufSize;
+} PXE_DB_INITIALIZE;
+
+typedef struct s_pxe_cpb_receive_filters {
+  ///
+  /// List of multicast MAC addresses.  This list, if present, will
+  /// replace the existing multicast MAC address filter list.
+  ///
+  PXE_MAC_ADDR  MCastList[MAX_MCAST_ADDRESS_CNT];
+} PXE_CPB_RECEIVE_FILTERS;
+
+typedef struct s_pxe_db_receive_filters {
+  ///
+  /// Filtered multicast MAC address list.
+  ///
+  PXE_MAC_ADDR  MCastList[MAX_MCAST_ADDRESS_CNT];
+} PXE_DB_RECEIVE_FILTERS;
+
+typedef struct s_pxe_cpb_station_address {
+  ///
+  /// If supplied and supported, the current station MAC address
+  /// will be changed.
+  ///
+  PXE_MAC_ADDR  StationAddr;
+} PXE_CPB_STATION_ADDRESS;
+
+typedef struct s_pxe_dpb_station_address {
+  ///
+  /// Current station MAC address.
+  ///
+  PXE_MAC_ADDR  StationAddr;
+
+  ///
+  /// Station broadcast MAC address.
+  ///
+  PXE_MAC_ADDR  BroadcastAddr;
+
+  ///
+  /// Permanent station MAC address.
+  ///
+  PXE_MAC_ADDR  PermanentAddr;
+} PXE_DB_STATION_ADDRESS;
+
+typedef struct s_pxe_db_statistics {
+  ///
+  /// Bit field identifying what statistic data is collected by the
+  /// UNDI/NIC.
+  /// If bit 0x00 is set, Data[0x00] is collected.
+  /// If bit 0x01 is set, Data[0x01] is collected.
+  /// If bit 0x20 is set, Data[0x20] is collected.
+  /// If bit 0x21 is set, Data[0x21] is collected.
+  /// Etc.
+  ///
+  PXE_UINT64  Supported;
+
+  ///
+  /// Statistic data.
+  ///
+  PXE_UINT64  Data[64];
+} PXE_DB_STATISTICS;
+
+///
+/// Total number of frames received.  Includes frames with errors and
+/// dropped frames.
+///
+#define PXE_STATISTICS_RX_TOTAL_FRAMES  0x00
+
+///
+/// Number of valid frames received and copied into receive buffers.
+///
+#define PXE_STATISTICS_RX_GOOD_FRAMES 0x01
+
+///
+/// Number of frames below the minimum length for the media.
+/// This would be <64 for ethernet.
+///
+#define PXE_STATISTICS_RX_UNDERSIZE_FRAMES  0x02
+
+///
+/// Number of frames longer than the maxminum length for the
+/// media.  This would be >1500 for ethernet.
+///
+#define PXE_STATISTICS_RX_OVERSIZE_FRAMES 0x03
+
+///
+/// Valid frames that were dropped because receive buffers were full.
+///
+#define PXE_STATISTICS_RX_DROPPED_FRAMES  0x04
+
+///
+/// Number of valid unicast frames received and not dropped.
+///
+#define PXE_STATISTICS_RX_UNICAST_FRAMES  0x05
+
+///
+/// Number of valid broadcast frames received and not dropped.
+///
+#define PXE_STATISTICS_RX_BROADCAST_FRAMES  0x06
+
+///
+/// Number of valid mutlicast frames received and not dropped.
+///
+#define PXE_STATISTICS_RX_MULTICAST_FRAMES  0x07
+
+///
+/// Number of frames w/ CRC or alignment errors.
+///
+#define PXE_STATISTICS_RX_CRC_ERROR_FRAMES  0x08
+
+///
+/// Total number of bytes received.  Includes frames with errors
+/// and dropped frames.
+///
+#define PXE_STATISTICS_RX_TOTAL_BYTES 0x09
+
+///
+/// Transmit statistics.
+///
+#define PXE_STATISTICS_TX_TOTAL_FRAMES      0x0A
+#define PXE_STATISTICS_TX_GOOD_FRAMES       0x0B
+#define PXE_STATISTICS_TX_UNDERSIZE_FRAMES  0x0C
+#define PXE_STATISTICS_TX_OVERSIZE_FRAMES   0x0D
+#define PXE_STATISTICS_TX_DROPPED_FRAMES    0x0E
+#define PXE_STATISTICS_TX_UNICAST_FRAMES    0x0F
+#define PXE_STATISTICS_TX_BROADCAST_FRAMES  0x10
+#define PXE_STATISTICS_TX_MULTICAST_FRAMES  0x11
+#define PXE_STATISTICS_TX_CRC_ERROR_FRAMES  0x12
+#define PXE_STATISTICS_TX_TOTAL_BYTES       0x13
+
+///
+/// Number of collisions detection on this subnet.
+///
+#define PXE_STATISTICS_COLLISIONS 0x14
+
+///
+/// Number of frames destined for unsupported protocol.
+///
+#define PXE_STATISTICS_UNSUPPORTED_PROTOCOL 0x15
+
+typedef struct s_pxe_cpb_mcast_ip_to_mac {
+  ///
+  /// Multicast IP address to be converted to multicast MAC address.
+  ///
+  PXE_IP_ADDR IP;
+} PXE_CPB_MCAST_IP_TO_MAC;
+
+typedef struct s_pxe_db_mcast_ip_to_mac {
+  ///
+  /// Multicast MAC address.
+  ///
+  PXE_MAC_ADDR  MAC;
+} PXE_DB_MCAST_IP_TO_MAC;
+
+typedef struct s_pxe_cpb_nvdata_sparse {
+  ///
+  /// NvData item list.  Only items in this list will be updated.
+  ///
+  struct {
+    ///
+    ///  Non-volatile storage address to be changed.
+    ///
+    PXE_UINT32  Addr;
+
+    ///
+    /// Data item to write into above storage address.
+    ///
+    union {
+      PXE_UINT8   Byte;
+      PXE_UINT16  Word;
+      PXE_UINT32  Dword;
+    } Data;
+  } Item[MAX_EEPROM_LEN];
+} PXE_CPB_NVDATA_SPARSE;
+
+///
+/// When using bulk update, the size of the CPB structure must be
+/// the same size as the non-volatile NIC storage.
+///
+typedef union u_pxe_cpb_nvdata_bulk {
+  ///
+  /// Array of byte-wide data items.
+  ///
+  PXE_UINT8   Byte[MAX_EEPROM_LEN << 2];
+
+  ///
+  /// Array of word-wide data items.
+  ///
+  PXE_UINT16  Word[MAX_EEPROM_LEN << 1];
+
+  ///
+  /// Array of dword-wide data items.
+  ///
+  PXE_UINT32  Dword[MAX_EEPROM_LEN];
+} PXE_CPB_NVDATA_BULK;
+
+typedef struct s_pxe_db_nvdata {
+  ///
+  /// Arrays of data items from non-volatile storage.
+  ///
+  union {
+    ///
+    /// Array of byte-wide data items.
+    ///
+    PXE_UINT8   Byte[MAX_EEPROM_LEN << 2];
+
+    ///
+    /// Array of word-wide data items.
+    ///
+    PXE_UINT16  Word[MAX_EEPROM_LEN << 1];
+
+    ///
+    /// Array of dword-wide data items.
+    ///
+    PXE_UINT32  Dword[MAX_EEPROM_LEN];
+  } Data;
+} PXE_DB_NVDATA;
+
+typedef struct s_pxe_db_get_status {
+  ///
+  /// Length of next receive frame (header + data).  If this is zero,
+  /// there is no next receive frame available.
+  ///
+  PXE_UINT32  RxFrameLen;
+
+  ///
+  /// Reserved, set to zero.
+  ///
+  PXE_UINT32  reserved;
+
+  ///
+  ///  Addresses of transmitted buffers that need to be recycled.
+  ///
+  PXE_UINT64  TxBuffer[MAX_XMIT_BUFFERS];
+} PXE_DB_GET_STATUS;
+
+typedef struct s_pxe_cpb_fill_header {
+  ///
+  /// Source and destination MAC addresses.  These will be copied into
+  /// the media header without doing byte swapping.
+  ///
+  PXE_MAC_ADDR  SrcAddr;
+  PXE_MAC_ADDR  DestAddr;
+
+  ///
+  /// Address of first byte of media header.  The first byte of packet data
+  /// follows the last byte of the media header.
+  ///
+  PXE_UINT64        MediaHeader;
+
+  ///
+  /// Length of packet data in bytes (not including the media header).
+  ///
+  PXE_UINT32        PacketLen;
+
+  ///
+  /// Protocol type.  This will be copied into the media header without
+  /// doing byte swapping.  Protocol type numbers can be obtained from
+  /// the Assigned Numbers RFC 1700.
+  ///
+  PXE_UINT16        Protocol;
+
+  ///
+  /// Length of the media header in bytes.
+  ///
+  PXE_UINT16        MediaHeaderLen;
+} PXE_CPB_FILL_HEADER;
+
+#define PXE_PROTOCOL_ETHERNET_IP  0x0800
+#define PXE_PROTOCOL_ETHERNET_ARP 0x0806
+#define MAX_XMIT_FRAGMENTS        16
+
+typedef struct s_pxe_cpb_fill_header_fragmented {
+  ///
+  /// Source and destination MAC addresses.  These will be copied into
+  /// the media header without doing byte swapping.
+  ///
+  PXE_MAC_ADDR        SrcAddr;
+  PXE_MAC_ADDR        DestAddr;
+
+  ///
+  /// Length of packet data in bytes (not including the media header).
+  ///
+  PXE_UINT32          PacketLen;
+
+  ///
+  /// Protocol type.  This will be copied into the media header without
+  /// doing byte swapping.  Protocol type numbers can be obtained from
+  /// the Assigned Numbers RFC 1700.
+  ///
+  PXE_MEDIA_PROTOCOL  Protocol;
+
+  ///
+  /// Length of the media header in bytes.
+  ///
+  PXE_UINT16          MediaHeaderLen;
+
+  ///
+  /// Number of packet fragment descriptors.
+  ///
+  PXE_UINT16          FragCnt;
+
+  ///
+  /// Reserved, must be set to zero.
+  ///
+  PXE_UINT16          reserved;
+
+  ///
+  /// Array of packet fragment descriptors.  The first byte of the media
+  /// header is the first byte of the first fragment.
+  ///
+  struct {
+    ///
+    /// Address of this packet fragment.
+    ///
+    PXE_UINT64  FragAddr;
+
+    ///
+    /// Length of this packet fragment.
+    ///
+    PXE_UINT32  FragLen;
+
+    ///
+    /// Reserved, must be set to zero.
+    ///
+    PXE_UINT32  reserved;
+  } FragDesc[MAX_XMIT_FRAGMENTS];
+}
+PXE_CPB_FILL_HEADER_FRAGMENTED;
+
+typedef struct s_pxe_cpb_transmit {
+  ///
+  /// Address of first byte of frame buffer.  This is also the first byte
+  /// of the media header.
+  ///
+  PXE_UINT64  FrameAddr;
+
+  ///
+  /// Length of the data portion of the frame buffer in bytes.  Do not
+  /// include the length of the media header.
+  ///
+  PXE_UINT32  DataLen;
+
+  ///
+  /// Length of the media header in bytes.
+  ///
+  PXE_UINT16  MediaheaderLen;
+
+  ///
+  /// Reserved, must be zero.
+  ///
+  PXE_UINT16  reserved;
+} PXE_CPB_TRANSMIT;
+
+typedef struct s_pxe_cpb_transmit_fragments {
+  ///
+  /// Length of packet data in bytes (not including the media header).
+  ///
+  PXE_UINT32  FrameLen;
+
+  ///
+  /// Length of the media header in bytes.
+  ///
+  PXE_UINT16  MediaheaderLen;
+
+  ///
+  /// Number of packet fragment descriptors.
+  ///
+  PXE_UINT16  FragCnt;
+
+  ///
+  /// Array of frame fragment descriptors.  The first byte of the first
+  /// fragment is also the first byte of the media header.
+  ///
+  struct {
+    ///
+    /// Address of this frame fragment.
+    ///
+    PXE_UINT64  FragAddr;
+
+    ///
+    /// Length of this frame fragment.
+    ///
+    PXE_UINT32  FragLen;
+
+    ///
+    /// Reserved, must be set to zero.
+    ///
+    PXE_UINT32  reserved;
+  } FragDesc[MAX_XMIT_FRAGMENTS];
+}
+PXE_CPB_TRANSMIT_FRAGMENTS;
+
+typedef struct s_pxe_cpb_receive {
+  ///
+  /// Address of first byte of receive buffer.  This is also the first byte
+  /// of the frame header.
+  ///
+  PXE_UINT64  BufferAddr;
+
+  ///
+  /// Length of receive buffer.  This must be large enough to hold the
+  /// received frame (media header + data).  If the length of smaller than
+  /// the received frame, data will be lost.
+  ///
+  PXE_UINT32  BufferLen;
+
+  ///
+  /// Reserved, must be set to zero.
+  ///
+  PXE_UINT32  reserved;
+} PXE_CPB_RECEIVE;
+
+typedef struct s_pxe_db_receive {
+  ///
+  /// Source and destination MAC addresses from media header.
+  ///
+  PXE_MAC_ADDR        SrcAddr;
+  PXE_MAC_ADDR        DestAddr;
+
+  ///
+  /// Length of received frame.  May be larger than receive buffer size.
+  /// The receive buffer will not be overwritten.  This is how to tell
+  /// if data was lost because the receive buffer was too small.
+  ///
+  PXE_UINT32          FrameLen;
+
+  ///
+  /// Protocol type from media header.
+  ///
+  PXE_MEDIA_PROTOCOL  Protocol;
+
+  ///
+  /// Length of media header in received frame.
+  ///
+  PXE_UINT16          MediaHeaderLen;
+
+  ///
+  /// Type of receive frame.
+  ///
+  PXE_FRAME_TYPE      Type;
+
+  ///
+  /// Reserved, must be zero.
+  ///
+  PXE_UINT8           reserved[7];
+
+} PXE_DB_RECEIVE;
+
+#pragma pack()
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/Uefi/UefiSpec.h b/wimboot/wimboot-2.7.3/src/efi/Uefi/UefiSpec.h
new file mode 100644 (file)
index 0000000..7a7c0b3
--- /dev/null
@@ -0,0 +1,2144 @@
+/** @file
+  Include file that supports UEFI.
+
+  This include file must contain things defined in the UEFI 2.4 specification.
+  If a code construct is defined in the UEFI 2.4 specification it must be included
+  by this include file.
+
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __UEFI_SPEC_H__
+#define __UEFI_SPEC_H__
+
+#include "efi/Uefi/UefiMultiPhase.h"
+
+#include "efi/Protocol/DevicePath.h"
+#include "efi/Protocol/SimpleTextIn.h"
+#include "efi/Protocol/SimpleTextInEx.h"
+#include "efi/Protocol/SimpleTextOut.h"
+
+///
+/// Enumeration of EFI memory allocation types.
+///
+typedef enum {
+  ///
+  /// Allocate any available range of pages that satisfies the request.
+  ///
+  AllocateAnyPages,
+  ///
+  /// Allocate any available range of pages whose uppermost address is less than
+  /// or equal to a specified maximum address.
+  ///
+  AllocateMaxAddress,
+  ///
+  /// Allocate pages at a specified address.
+  ///
+  AllocateAddress,
+  ///
+  /// Maximum enumeration value that may be used for bounds checking.
+  ///
+  MaxAllocateType
+} EFI_ALLOCATE_TYPE;
+
+//
+// Bit definitions for EFI_TIME.Daylight
+//
+#define EFI_TIME_ADJUST_DAYLIGHT  0x01
+#define EFI_TIME_IN_DAYLIGHT      0x02
+
+///
+/// Value definition for EFI_TIME.TimeZone.
+///
+#define EFI_UNSPECIFIED_TIMEZONE  0x07FF
+
+//
+// Memory cacheability attributes
+//
+#define EFI_MEMORY_UC   0x0000000000000001ULL
+#define EFI_MEMORY_WC   0x0000000000000002ULL
+#define EFI_MEMORY_WT   0x0000000000000004ULL
+#define EFI_MEMORY_WB   0x0000000000000008ULL
+#define EFI_MEMORY_UCE  0x0000000000000010ULL
+//
+// Physical memory protection attributes
+//
+#define EFI_MEMORY_WP   0x0000000000001000ULL
+#define EFI_MEMORY_RP   0x0000000000002000ULL
+#define EFI_MEMORY_XP   0x0000000000004000ULL
+//
+// Runtime memory attribute
+//
+#define EFI_MEMORY_RUNTIME  0x8000000000000000ULL
+
+///
+/// Memory descriptor version number.
+///
+#define EFI_MEMORY_DESCRIPTOR_VERSION 1
+
+///
+/// Definition of an EFI memory descriptor.
+///
+typedef struct {
+  ///
+  /// Type of the memory region.  See EFI_MEMORY_TYPE.
+  ///
+  UINT32                Type;
+  ///
+  /// Physical address of the first byte of the memory region.  Must aligned
+  /// on a 4 KB boundary.
+  ///
+  EFI_PHYSICAL_ADDRESS  PhysicalStart;
+  ///
+  /// Virtual address of the first byte of the memory region.  Must aligned
+  /// on a 4 KB boundary.
+  ///
+  EFI_VIRTUAL_ADDRESS   VirtualStart;
+  ///
+  /// Number of 4KB pages in the memory region.
+  ///
+  UINT64                NumberOfPages;
+  ///
+  /// Attributes of the memory region that describe the bit mask of capabilities
+  /// for that memory region, and not necessarily the current settings for that
+  /// memory region.
+  ///
+  UINT64                Attribute;
+} EFI_MEMORY_DESCRIPTOR;
+
+/**
+  Allocates memory pages from the system.
+
+  @param  Type        The type of allocation to perform.
+  @param  MemoryType  The type of memory to allocate.
+  @param  Pages       The number of contiguous 4 KB pages to allocate.
+  @param  Memory      The pointer to a physical address. On input, the way in which the address is
+                      used depends on the value of Type.
+
+  @retval EFI_SUCCESS           The requested pages were allocated.
+  @retval EFI_INVALID_PARAMETER 1) Type is not AllocateAnyPages or
+                                AllocateMaxAddress or AllocateAddress.
+                                2) MemoryType is in the range
+                                3) Memory is NULL.
+                                EfiMaxMemoryType..0x7FFFFFFF.
+  @retval EFI_OUT_OF_RESOURCES  The pages could not be allocated.
+  @retval EFI_NOT_FOUND         The requested pages could not be found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ALLOCATE_PAGES)(
+  IN     EFI_ALLOCATE_TYPE            Type,
+  IN     EFI_MEMORY_TYPE              MemoryType,
+  IN     UINTN                        Pages,
+  IN OUT EFI_PHYSICAL_ADDRESS         *Memory
+  );
+
+/**
+  Frees memory pages.
+
+  @param  Memory      The base physical address of the pages to be freed.
+  @param  Pages       The number of contiguous 4 KB pages to free.
+
+  @retval EFI_SUCCESS           The requested pages were freed.
+  @retval EFI_INVALID_PARAMETER Memory is not a page-aligned address or Pages is invalid.
+  @retval EFI_NOT_FOUND         The requested memory pages were not allocated with
+                                AllocatePages().
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FREE_PAGES)(
+  IN  EFI_PHYSICAL_ADDRESS         Memory,
+  IN  UINTN                        Pages
+  );
+
+/**
+  Returns the current memory map.
+
+  @param  MemoryMapSize         A pointer to the size, in bytes, of the MemoryMap buffer.
+                                On input, this is the size of the buffer allocated by the caller.
+                                On output, it is the size of the buffer returned by the firmware if
+                                the buffer was large enough, or the size of the buffer needed to contain
+                                the map if the buffer was too small.
+  @param  MemoryMap             A pointer to the buffer in which firmware places the current memory
+                                map.
+  @param  MapKey                A pointer to the location in which firmware returns the key for the
+                                current memory map.
+  @param  DescriptorSize        A pointer to the location in which firmware returns the size, in bytes, of
+                                an individual EFI_MEMORY_DESCRIPTOR.
+  @param  DescriptorVersion     A pointer to the location in which firmware returns the version number
+                                associated with the EFI_MEMORY_DESCRIPTOR.
+
+  @retval EFI_SUCCESS           The memory map was returned in the MemoryMap buffer.
+  @retval EFI_BUFFER_TOO_SMALL  The MemoryMap buffer was too small. The current buffer size
+                                needed to hold the memory map is returned in MemoryMapSize.
+  @retval EFI_INVALID_PARAMETER 1) MemoryMapSize is NULL.
+                                2) The MemoryMap buffer is not too small and MemoryMap is
+                                   NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_MEMORY_MAP)(
+  IN OUT UINTN                       *MemoryMapSize,
+  IN OUT EFI_MEMORY_DESCRIPTOR       *MemoryMap,
+  OUT    UINTN                       *MapKey,
+  OUT    UINTN                       *DescriptorSize,
+  OUT    UINT32                      *DescriptorVersion
+  );
+
+/**
+  Allocates pool memory.
+
+  @param  PoolType              The type of pool to allocate.
+  @param  Size                  The number of bytes to allocate from the pool.
+  @param  Buffer                A pointer to a pointer to the allocated buffer if the call succeeds;
+                                undefined otherwise.
+
+  @retval EFI_SUCCESS           The requested number of bytes was allocated.
+  @retval EFI_OUT_OF_RESOURCES  The pool requested could not be allocated.
+  @retval EFI_INVALID_PARAMETER PoolType was invalid or Buffer is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ALLOCATE_POOL)(
+  IN  EFI_MEMORY_TYPE              PoolType,
+  IN  UINTN                        Size,
+  OUT VOID                         **Buffer
+  );
+
+/**
+  Returns pool memory to the system.
+
+  @param  Buffer                The pointer to the buffer to free.
+
+  @retval EFI_SUCCESS           The memory was returned to the system.
+  @retval EFI_INVALID_PARAMETER Buffer was invalid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FREE_POOL)(
+  IN  VOID                         *Buffer
+  );
+
+/**
+  Changes the runtime addressing mode of EFI firmware from physical to virtual.
+
+  @param  MemoryMapSize         The size in bytes of VirtualMap.
+  @param  DescriptorSize        The size in bytes of an entry in the VirtualMap.
+  @param  DescriptorVersion     The version of the structure entries in VirtualMap.
+  @param  VirtualMap            An array of memory descriptors which contain new virtual
+                                address mapping information for all runtime ranges.
+
+  @retval EFI_SUCCESS           The virtual address map has been applied.
+  @retval EFI_UNSUPPORTED       EFI firmware is not at runtime, or the EFI firmware is already in
+                                virtual address mapped mode.
+  @retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is invalid.
+  @retval EFI_NO_MAPPING        A virtual address was not supplied for a range in the memory
+                                map that requires a mapping.
+  @retval EFI_NOT_FOUND         A virtual address was supplied for an address that is not found
+                                in the memory map.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP)(
+  IN  UINTN                        MemoryMapSize,
+  IN  UINTN                        DescriptorSize,
+  IN  UINT32                       DescriptorVersion,
+  IN  EFI_MEMORY_DESCRIPTOR        *VirtualMap
+  );
+
+/**
+  Connects one or more drivers to a controller.
+
+  @param  ControllerHandle      The handle of the controller to which driver(s) are to be connected.
+  @param  DriverImageHandle     A pointer to an ordered list handles that support the
+                                EFI_DRIVER_BINDING_PROTOCOL.
+  @param  RemainingDevicePath   A pointer to the device path that specifies a child of the
+                                controller specified by ControllerHandle.
+  @param  Recursive             If TRUE, then ConnectController() is called recursively
+                                until the entire tree of controllers below the controller specified
+                                by ControllerHandle have been created. If FALSE, then
+                                the tree of controllers is only expanded one level.
+
+  @retval EFI_SUCCESS           1) One or more drivers were connected to ControllerHandle.
+                                2) No drivers were connected to ControllerHandle, but
+                                RemainingDevicePath is not NULL, and it is an End Device
+                                Path Node.
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+  @retval EFI_NOT_FOUND         1) There are no EFI_DRIVER_BINDING_PROTOCOL instances
+                                present in the system.
+                                2) No drivers were connected to ControllerHandle.
+  @retval EFI_SECURITY_VIOLATION
+                                The user has no permission to start UEFI device drivers on the device path
+                                associated with the ControllerHandle or specified by the RemainingDevicePath.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONNECT_CONTROLLER)(
+  IN  EFI_HANDLE                    ControllerHandle,
+  IN  EFI_HANDLE                    *DriverImageHandle,   OPTIONAL
+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath, OPTIONAL
+  IN  BOOLEAN                       Recursive
+  );
+
+/**
+  Disconnects one or more drivers from a controller.
+
+  @param  ControllerHandle      The handle of the controller from which driver(s) are to be disconnected.
+  @param  DriverImageHandle     The driver to disconnect from ControllerHandle.
+                                If DriverImageHandle is NULL, then all the drivers currently managing
+                                ControllerHandle are disconnected from ControllerHandle.
+  @param  ChildHandle           The handle of the child to destroy.
+                                If ChildHandle is NULL, then all the children of ControllerHandle are
+                                destroyed before the drivers are disconnected from ControllerHandle.
+
+  @retval EFI_SUCCESS           1) One or more drivers were disconnected from the controller.
+                                2) On entry, no drivers are managing ControllerHandle.
+                                3) DriverImageHandle is not NULL, and on entry
+                                   DriverImageHandle is not managing ControllerHandle.
+  @retval EFI_INVALID_PARAMETER 1) ControllerHandle is NULL.
+                                2) DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE.
+                                3) ChildHandle is not NULL, and it is not a valid EFI_HANDLE.
+                                4) DriverImageHandle does not support the EFI_DRIVER_BINDING_PROTOCOL.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to disconnect any drivers from
+                                ControllerHandle.
+  @retval EFI_DEVICE_ERROR      The controller could not be disconnected because of a device error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DISCONNECT_CONTROLLER)(
+  IN  EFI_HANDLE                     ControllerHandle,
+  IN  EFI_HANDLE                     DriverImageHandle, OPTIONAL
+  IN  EFI_HANDLE                     ChildHandle        OPTIONAL
+  );
+
+
+
+//
+// ConvertPointer DebugDisposition type.
+//
+#define EFI_OPTIONAL_PTR     0x00000001
+
+/**
+  Determines the new virtual address that is to be used on subsequent memory accesses.
+
+  @param  DebugDisposition      Supplies type information for the pointer being converted.
+  @param  Address               A pointer to a pointer that is to be fixed to be the value needed
+                                for the new virtual address mappings being applied.
+
+  @retval EFI_SUCCESS           The pointer pointed to by Address was modified.
+  @retval EFI_INVALID_PARAMETER 1) Address is NULL.
+                                2) *Address is NULL and DebugDisposition does
+                                not have the EFI_OPTIONAL_PTR bit set.
+  @retval EFI_NOT_FOUND         The pointer pointed to by Address was not found to be part
+                                of the current memory map. This is normally fatal.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONVERT_POINTER)(
+  IN     UINTN                      DebugDisposition,
+  IN OUT VOID                       **Address
+  );
+
+
+//
+// These types can be ORed together as needed - for example,
+// EVT_TIMER might be Ored with EVT_NOTIFY_WAIT or
+// EVT_NOTIFY_SIGNAL.
+//
+#define EVT_TIMER                         0x80000000
+#define EVT_RUNTIME                       0x40000000
+#define EVT_NOTIFY_WAIT                   0x00000100
+#define EVT_NOTIFY_SIGNAL                 0x00000200
+
+#define EVT_SIGNAL_EXIT_BOOT_SERVICES     0x00000201
+#define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202
+
+//
+// The event's NotifyContext pointer points to a runtime memory
+// address.
+// The event is deprecated in UEFI2.0 and later specifications.
+//
+#define EVT_RUNTIME_CONTEXT               0x20000000
+
+
+/**
+  Invoke a notification event
+
+  @param  Event                 Event whose notification function is being invoked.
+  @param  Context               The pointer to the notification function's context,
+                                which is implementation-dependent.
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_EVENT_NOTIFY)(
+  IN  EFI_EVENT                Event,
+  IN  VOID                     *Context
+  );
+
+/**
+  Creates an event.
+
+  @param  Type                  The type of event to create and its mode and attributes.
+  @param  NotifyTpl             The task priority level of event notifications, if needed.
+  @param  NotifyFunction        The pointer to the event's notification function, if any.
+  @param  NotifyContext         The pointer to the notification function's context; corresponds to parameter
+                                Context in the notification function.
+  @param  Event                 The pointer to the newly created event if the call succeeds; undefined
+                                otherwise.
+
+  @retval EFI_SUCCESS           The event structure was created.
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+  @retval EFI_OUT_OF_RESOURCES  The event could not be allocated.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CREATE_EVENT)(
+  IN  UINT32                       Type,
+  IN  EFI_TPL                      NotifyTpl,
+  IN  EFI_EVENT_NOTIFY             NotifyFunction,
+  IN  VOID                         *NotifyContext,
+  OUT EFI_EVENT                    *Event
+  );
+
+/**
+  Creates an event in a group.
+
+  @param  Type                  The type of event to create and its mode and attributes.
+  @param  NotifyTpl             The task priority level of event notifications,if needed.
+  @param  NotifyFunction        The pointer to the event's notification function, if any.
+  @param  NotifyContext         The pointer to the notification function's context; corresponds to parameter
+                                Context in the notification function.
+  @param  EventGroup            The pointer to the unique identifier of the group to which this event belongs.
+                                If this is NULL, then the function behaves as if the parameters were passed
+                                to CreateEvent.
+  @param  Event                 The pointer to the newly created event if the call succeeds; undefined
+                                otherwise.
+
+  @retval EFI_SUCCESS           The event structure was created.
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+  @retval EFI_OUT_OF_RESOURCES  The event could not be allocated.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CREATE_EVENT_EX)(
+  IN       UINT32                 Type,
+  IN       EFI_TPL                NotifyTpl,
+  IN       EFI_EVENT_NOTIFY       NotifyFunction OPTIONAL,
+  IN CONST VOID                   *NotifyContext OPTIONAL,
+  IN CONST EFI_GUID               *EventGroup    OPTIONAL,
+  OUT      EFI_EVENT              *Event
+  );
+
+///
+/// Timer delay types
+///
+typedef enum {
+  ///
+  /// An event's timer settings is to be cancelled and not trigger time is to be set/
+  ///
+  TimerCancel,
+  ///
+  /// An event is to be signaled periodically at a specified interval from the current time.
+  ///
+  TimerPeriodic,
+  ///
+  /// An event is to be signaled once at a specified interval from the current time.
+  ///
+  TimerRelative
+} EFI_TIMER_DELAY;
+
+/**
+  Sets the type of timer and the trigger time for a timer event.
+
+  @param  Event                 The timer event that is to be signaled at the specified time.
+  @param  Type                  The type of time that is specified in TriggerTime.
+  @param  TriggerTime           The number of 100ns units until the timer expires.
+                                A TriggerTime of 0 is legal.
+                                If Type is TimerRelative and TriggerTime is 0, then the timer
+                                event will be signaled on the next timer tick.
+                                If Type is TimerPeriodic and TriggerTime is 0, then the timer
+                                event will be signaled on every timer tick.
+
+  @retval EFI_SUCCESS           The event has been set to be signaled at the requested time.
+  @retval EFI_INVALID_PARAMETER Event or Type is not valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_TIMER)(
+  IN  EFI_EVENT                Event,
+  IN  EFI_TIMER_DELAY          Type,
+  IN  UINT64                   TriggerTime
+  );
+
+/**
+  Signals an event.
+
+  @param  Event                 The event to signal.
+
+  @retval EFI_SUCCESS           The event has been signaled.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIGNAL_EVENT)(
+  IN  EFI_EVENT                Event
+  );
+
+/**
+  Stops execution until an event is signaled.
+
+  @param  NumberOfEvents        The number of events in the Event array.
+  @param  Event                 An array of EFI_EVENT.
+  @param  Index                 The pointer to the index of the event which satisfied the wait condition.
+
+  @retval EFI_SUCCESS           The event indicated by Index was signaled.
+  @retval EFI_INVALID_PARAMETER 1) NumberOfEvents is 0.
+                                2) The event indicated by Index is of type
+                                   EVT_NOTIFY_SIGNAL.
+  @retval EFI_UNSUPPORTED       The current TPL is not TPL_APPLICATION.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WAIT_FOR_EVENT)(
+  IN  UINTN                    NumberOfEvents,
+  IN  EFI_EVENT                *Event,
+  OUT UINTN                    *Index
+  );
+
+/**
+  Closes an event.
+
+  @param  Event                 The event to close.
+
+  @retval EFI_SUCCESS           The event has been closed.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CLOSE_EVENT)(
+  IN EFI_EVENT                Event
+  );
+
+/**
+  Checks whether an event is in the signaled state.
+
+  @param  Event                 The event to check.
+
+  @retval EFI_SUCCESS           The event is in the signaled state.
+  @retval EFI_NOT_READY         The event is not in the signaled state.
+  @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CHECK_EVENT)(
+  IN EFI_EVENT                Event
+  );
+
+
+//
+// Task priority level
+//
+#define TPL_APPLICATION       4
+#define TPL_CALLBACK          8
+#define TPL_NOTIFY            16
+#define TPL_HIGH_LEVEL        31
+
+
+/**
+  Raises a task's priority level and returns its previous level.
+
+  @param  NewTpl                The new task priority level.
+
+  @return Previous task priority level
+
+**/
+typedef
+EFI_TPL
+(EFIAPI *EFI_RAISE_TPL)(
+  IN EFI_TPL      NewTpl
+  );
+
+/**
+  Restores a task's priority level to its previous value.
+
+  @param  OldTpl                The previous task priority level to restore.
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_RESTORE_TPL)(
+  IN EFI_TPL      OldTpl
+  );
+
+/**
+  Returns the value of a variable.
+
+  @param  VariableName          A Null-terminated string that is the name of the vendor's
+                                variable.
+  @param  VendorGuid            A unique identifier for the vendor.
+  @param  Attributes            If not NULL, a pointer to the memory location to return the
+                                attributes bitmask for the variable.
+  @param  DataSize              On input, the size in bytes of the return Data buffer.
+                                On output the size of data returned in Data.
+  @param  Data                  The buffer to return the contents of the variable.
+
+  @retval EFI_SUCCESS            The function completed successfully.
+  @retval EFI_NOT_FOUND          The variable was not found.
+  @retval EFI_BUFFER_TOO_SMALL   The DataSize is too small for the result.
+  @retval EFI_INVALID_PARAMETER  VariableName is NULL.
+  @retval EFI_INVALID_PARAMETER  VendorGuid is NULL.
+  @retval EFI_INVALID_PARAMETER  DataSize is NULL.
+  @retval EFI_INVALID_PARAMETER  The DataSize is not too small and Data is NULL.
+  @retval EFI_DEVICE_ERROR       The variable could not be retrieved due to a hardware error.
+  @retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_VARIABLE)(
+  IN     CHAR16                      *VariableName,
+  IN     EFI_GUID                    *VendorGuid,
+  OUT    UINT32                      *Attributes,    OPTIONAL
+  IN OUT UINTN                       *DataSize,
+  OUT    VOID                        *Data
+  );
+
+/**
+  Enumerates the current variable names.
+
+  @param  VariableNameSize      The size of the VariableName buffer.
+  @param  VariableName          On input, supplies the last VariableName that was returned
+                                by GetNextVariableName(). On output, returns the Nullterminated
+                                string of the current variable.
+  @param  VendorGuid            On input, supplies the last VendorGuid that was returned by
+                                GetNextVariableName(). On output, returns the
+                                VendorGuid of the current variable.
+
+  @retval EFI_SUCCESS           The function completed successfully.
+  @retval EFI_NOT_FOUND         The next variable was not found.
+  @retval EFI_BUFFER_TOO_SMALL  The VariableNameSize is too small for the result.
+  @retval EFI_INVALID_PARAMETER VariableNameSize is NULL.
+  @retval EFI_INVALID_PARAMETER VariableName is NULL.
+  @retval EFI_INVALID_PARAMETER VendorGuid is NULL.
+  @retval EFI_DEVICE_ERROR      The variable could not be retrieved due to a hardware error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME)(
+  IN OUT UINTN                    *VariableNameSize,
+  IN OUT CHAR16                   *VariableName,
+  IN OUT EFI_GUID                 *VendorGuid
+  );
+
+/**
+  Sets the value of a variable.
+
+  @param  VariableName           A Null-terminated string that is the name of the vendor's variable.
+                                 Each VariableName is unique for each VendorGuid. VariableName must
+                                 contain 1 or more characters. If VariableName is an empty string,
+                                 then EFI_INVALID_PARAMETER is returned.
+  @param  VendorGuid             A unique identifier for the vendor.
+  @param  Attributes             Attributes bitmask to set for the variable.
+  @param  DataSize               The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE,
+                                 EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or
+                                 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero
+                                 causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is
+                                 set, then a SetVariable() call with a DataSize of zero will not cause any change to
+                                 the variable value (the timestamp associated with the variable may be updated however
+                                 even if no new data value is provided,see the description of the
+                                 EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not
+                                 be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated).
+  @param  Data                   The contents for the variable.
+
+  @retval EFI_SUCCESS            The firmware has successfully stored the variable and its data as
+                                 defined by the Attributes.
+  @retval EFI_INVALID_PARAMETER  An invalid combination of attribute bits, name, and GUID was supplied, or the
+                                 DataSize exceeds the maximum allowed.
+  @retval EFI_INVALID_PARAMETER  VariableName is an empty string.
+  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.
+  @retval EFI_DEVICE_ERROR       The variable could not be retrieved due to a hardware error.
+  @retval EFI_WRITE_PROTECTED    The variable in question is read-only.
+  @retval EFI_WRITE_PROTECTED    The variable in question cannot be deleted.
+  @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
+                                 or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but the AuthInfo
+                                 does NOT pass the validation check carried out by the firmware.
+
+  @retval EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_VARIABLE)(
+  IN  CHAR16                       *VariableName,
+  IN  EFI_GUID                     *VendorGuid,
+  IN  UINT32                       Attributes,
+  IN  UINTN                        DataSize,
+  IN  VOID                         *Data
+  );
+
+
+///
+/// This provides the capabilities of the
+/// real time clock device as exposed through the EFI interfaces.
+///
+typedef struct {
+  ///
+  /// Provides the reporting resolution of the real-time clock device in
+  /// counts per second. For a normal PC-AT CMOS RTC device, this
+  /// value would be 1 Hz, or 1, to indicate that the device only reports
+  /// the time to the resolution of 1 second.
+  ///
+  UINT32    Resolution;
+  ///
+  /// Provides the timekeeping accuracy of the real-time clock in an
+  /// error rate of 1E-6 parts per million. For a clock with an accuracy
+  /// of 50 parts per million, the value in this field would be
+  /// 50,000,000.
+  ///
+  UINT32    Accuracy;
+  ///
+  /// A TRUE indicates that a time set operation clears the device's
+  /// time below the Resolution reporting level. A FALSE
+  /// indicates that the state below the Resolution level of the
+  /// device is not cleared when the time is set. Normal PC-AT CMOS
+  /// RTC devices set this value to FALSE.
+  ///
+  BOOLEAN   SetsToZero;
+} EFI_TIME_CAPABILITIES;
+
+/**
+  Returns the current time and date information, and the time-keeping capabilities
+  of the hardware platform.
+
+  @param  Time                  A pointer to storage to receive a snapshot of the current time.
+  @param  Capabilities          An optional pointer to a buffer to receive the real time clock
+                                device's capabilities.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER Time is NULL.
+  @retval EFI_DEVICE_ERROR      The time could not be retrieved due to hardware error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_TIME)(
+  OUT  EFI_TIME                    *Time,
+  OUT  EFI_TIME_CAPABILITIES       *Capabilities OPTIONAL
+  );
+
+/**
+  Sets the current local time and date information.
+
+  @param  Time                  A pointer to the current time.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER A time field is out of range.
+  @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_TIME)(
+  IN  EFI_TIME                     *Time
+  );
+
+/**
+  Returns the current wakeup alarm clock setting.
+
+  @param  Enabled               Indicates if the alarm is currently enabled or disabled.
+  @param  Pending               Indicates if the alarm signal is pending and requires acknowledgement.
+  @param  Time                  The current alarm setting.
+
+  @retval EFI_SUCCESS           The alarm settings were returned.
+  @retval EFI_INVALID_PARAMETER Enabled is NULL.
+  @retval EFI_INVALID_PARAMETER Pending is NULL.
+  @retval EFI_INVALID_PARAMETER Time is NULL.
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.
+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_WAKEUP_TIME)(
+  OUT BOOLEAN                     *Enabled,
+  OUT BOOLEAN                     *Pending,
+  OUT EFI_TIME                    *Time
+  );
+
+/**
+  Sets the system wakeup alarm clock time.
+
+  @param  Enabled               Enable or disable the wakeup alarm.
+  @param  Time                  If Enable is TRUE, the time to set the wakeup alarm for.
+                                If Enable is FALSE, then this parameter is optional, and may be NULL.
+
+  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled. If
+                                Enable is FALSE, then the wakeup alarm was disabled.
+  @retval EFI_INVALID_PARAMETER A time field is out of range.
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.
+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_WAKEUP_TIME)(
+  IN  BOOLEAN                      Enable,
+  IN  EFI_TIME                     *Time   OPTIONAL
+  );
+
+/**
+  Loads an EFI image into memory.
+
+  @param  BootPolicy            If TRUE, indicates that the request originates from the boot
+                                manager, and that the boot manager is attempting to load
+                                FilePath as a boot selection. Ignored if SourceBuffer is
+                                not NULL.
+  @param  ParentImageHandle     The caller's image handle.
+  @param  DevicePath            The DeviceHandle specific file path from which the image is
+                                loaded.
+  @param  SourceBuffer          If not NULL, a pointer to the memory location containing a copy
+                                of the image to be loaded.
+  @param  SourceSize            The size in bytes of SourceBuffer. Ignored if SourceBuffer is NULL.
+  @param  ImageHandle           The pointer to the returned image handle that is created when the
+                                image is successfully loaded.
+
+  @retval EFI_SUCCESS           Image was loaded into memory correctly.
+  @retval EFI_NOT_FOUND         Both SourceBuffer and DevicePath are NULL.
+  @retval EFI_INVALID_PARAMETER One or more parametes are invalid.
+  @retval EFI_UNSUPPORTED       The image type is not supported.
+  @retval EFI_OUT_OF_RESOURCES  Image was not loaded due to insufficient resources.
+  @retval EFI_LOAD_ERROR        Image was not loaded because the image format was corrupt or not
+                                understood.
+  @retval EFI_DEVICE_ERROR      Image was not loaded because the device returned a read error.
+  @retval EFI_ACCESS_DENIED     Image was not loaded because the platform policy prohibits the
+                                image from being loaded. NULL is returned in *ImageHandle.
+  @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a
+                                valid EFI_LOADED_IMAGE_PROTOCOL. However, the current
+                                platform policy specifies that the image should not be started.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_LOAD)(
+  IN  BOOLEAN                      BootPolicy,
+  IN  EFI_HANDLE                   ParentImageHandle,
+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath,
+  IN  VOID                         *SourceBuffer OPTIONAL,
+  IN  UINTN                        SourceSize,
+  OUT EFI_HANDLE                   *ImageHandle
+  );
+
+/**
+  Transfers control to a loaded image's entry point.
+
+  @param  ImageHandle           Handle of image to be started.
+  @param  ExitDataSize          The pointer to the size, in bytes, of ExitData.
+  @param  ExitData              The pointer to a pointer to a data buffer that includes a Null-terminated
+                                string, optionally followed by additional binary data.
+
+  @retval EFI_INVALID_PARAMETER  ImageHandle is either an invalid image handle or the image
+                                 has already been initialized with StartImage.
+  @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started.
+  @return Exit code from image
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_START)(
+  IN  EFI_HANDLE                  ImageHandle,
+  OUT UINTN                       *ExitDataSize,
+  OUT CHAR16                      **ExitData    OPTIONAL
+  );
+
+/**
+  Terminates a loaded EFI image and returns control to boot services.
+
+  @param  ImageHandle           Handle that identifies the image. This parameter is passed to the
+                                image on entry.
+  @param  ExitStatus            The image's exit code.
+  @param  ExitDataSize          The size, in bytes, of ExitData. Ignored if ExitStatus is EFI_SUCCESS.
+  @param  ExitData              The pointer to a data buffer that includes a Null-terminated string,
+                                optionally followed by additional binary data. The string is a
+                                description that the caller may use to further indicate the reason
+                                for the image's exit. ExitData is only valid if ExitStatus
+                                is something other than EFI_SUCCESS. The ExitData buffer
+                                must be allocated by calling AllocatePool().
+
+  @retval EFI_SUCCESS           The image specified by ImageHandle was unloaded.
+  @retval EFI_INVALID_PARAMETER The image specified by ImageHandle has been loaded and
+                                started with LoadImage() and StartImage(), but the
+                                image is not the currently executing image.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_EXIT)(
+  IN  EFI_HANDLE                   ImageHandle,
+  IN  EFI_STATUS                   ExitStatus,
+  IN  UINTN                        ExitDataSize,
+  IN  CHAR16                       *ExitData     OPTIONAL
+  );
+
+/**
+  Unloads an image.
+
+  @param  ImageHandle           Handle that identifies the image to be unloaded.
+
+  @retval EFI_SUCCESS           The image has been unloaded.
+  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_UNLOAD)(
+  IN  EFI_HANDLE                   ImageHandle
+  );
+
+/**
+  Terminates all boot services.
+
+  @param  ImageHandle           Handle that identifies the exiting image.
+  @param  MapKey                Key to the latest memory map.
+
+  @retval EFI_SUCCESS           Boot services have been terminated.
+  @retval EFI_INVALID_PARAMETER MapKey is incorrect.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_EXIT_BOOT_SERVICES)(
+  IN  EFI_HANDLE                   ImageHandle,
+  IN  UINTN                        MapKey
+  );
+
+/**
+  Induces a fine-grained stall.
+
+  @param  Microseconds          The number of microseconds to stall execution.
+
+  @retval EFI_SUCCESS           Execution was stalled at least the requested number of
+                                Microseconds.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_STALL)(
+  IN  UINTN                    Microseconds
+  );
+
+/**
+  Sets the system's watchdog timer.
+
+  @param  Timeout               The number of seconds to set the watchdog timer to.
+  @param  WatchdogCode          The numeric code to log on a watchdog timer timeout event.
+  @param  DataSize              The size, in bytes, of WatchdogData.
+  @param  WatchdogData          A data buffer that includes a Null-terminated string, optionally
+                                followed by additional binary data.
+
+  @retval EFI_SUCCESS           The timeout has been set.
+  @retval EFI_INVALID_PARAMETER The supplied WatchdogCode is invalid.
+  @retval EFI_UNSUPPORTED       The system does not have a watchdog timer.
+  @retval EFI_DEVICE_ERROR      The watchdog timer could not be programmed due to a hardware
+                                error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_WATCHDOG_TIMER)(
+  IN UINTN                    Timeout,
+  IN UINT64                   WatchdogCode,
+  IN UINTN                    DataSize,
+  IN CHAR16                   *WatchdogData OPTIONAL
+  );
+
+///
+/// Enumeration of reset types.
+///
+typedef enum {
+  ///
+  /// Used to induce a system-wide reset. This sets all circuitry within the
+  /// system to its initial state.  This type of reset is asynchronous to system
+  /// operation and operates withgout regard to cycle boundaries.  EfiColdReset
+  /// is tantamount to a system power cycle.
+  ///
+  EfiResetCold,
+  ///
+  /// Used to induce a system-wide initialization. The processors are set to their
+  /// initial state, and pending cycles are not corrupted.  If the system does
+  /// not support this reset type, then an EfiResetCold must be performed.
+  ///
+  EfiResetWarm,
+  ///
+  /// Used to induce an entry into a power state equivalent to the ACPI G2/S5 or G3
+  /// state.  If the system does not support this reset type, then when the system
+  /// is rebooted, it should exhibit the EfiResetCold attributes.
+  ///
+  EfiResetShutdown,
+  ///
+  /// Used to induce a system-wide reset. The exact type of the reset is defined by
+  /// the EFI_GUID that follows the Null-terminated Unicode string passed into
+  /// ResetData. If the platform does not recognize the EFI_GUID in ResetData the
+  /// platform must pick a supported reset type to perform. The platform may
+  /// optionally log the parameters from any non-normal reset that occurs.
+  ///
+  EfiResetPlatformSpecific
+} EFI_RESET_TYPE;
+
+/**
+  Resets the entire platform.
+
+  @param  ResetType             The type of reset to perform.
+  @param  ResetStatus           The status code for the reset.
+  @param  DataSize              The size, in bytes, of WatchdogData.
+  @param  ResetData             For a ResetType of EfiResetCold, EfiResetWarm, or
+                                EfiResetShutdown the data buffer starts with a Null-terminated
+                                string, optionally followed by additional binary data.
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_RESET_SYSTEM)(
+  IN EFI_RESET_TYPE           ResetType,
+  IN EFI_STATUS               ResetStatus,
+  IN UINTN                    DataSize,
+  IN VOID                     *ResetData OPTIONAL
+  );
+
+/**
+  Returns a monotonically increasing count for the platform.
+
+  @param  Count                 The pointer to returned value.
+
+  @retval EFI_SUCCESS           The next monotonic count was returned.
+  @retval EFI_INVALID_PARAMETER Count is NULL.
+  @retval EFI_DEVICE_ERROR      The device is not functioning properly.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT)(
+  OUT UINT64                  *Count
+  );
+
+/**
+  Returns the next high 32 bits of the platform's monotonic counter.
+
+  @param  HighCount             The pointer to returned value.
+
+  @retval EFI_SUCCESS           The next high monotonic count was returned.
+  @retval EFI_INVALID_PARAMETER HighCount is NULL.
+  @retval EFI_DEVICE_ERROR      The device is not functioning properly.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT)(
+  OUT UINT32                  *HighCount
+  );
+
+/**
+  Computes and returns a 32-bit CRC for a data buffer.
+
+  @param  Data                  A pointer to the buffer on which the 32-bit CRC is to be computed.
+  @param  DataSize              The number of bytes in the buffer Data.
+  @param  Crc32                 The 32-bit CRC that was computed for the data buffer specified by Data
+                                and DataSize.
+
+  @retval EFI_SUCCESS           The 32-bit CRC was computed for the data buffer and returned in
+                                Crc32.
+  @retval EFI_INVALID_PARAMETER Data is NULL.
+  @retval EFI_INVALID_PARAMETER Crc32 is NULL.
+  @retval EFI_INVALID_PARAMETER DataSize is 0.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CALCULATE_CRC32)(
+  IN  VOID                              *Data,
+  IN  UINTN                             DataSize,
+  OUT UINT32                            *Crc32
+  );
+
+/**
+  Copies the contents of one buffer to another buffer.
+
+  @param  Destination           The pointer to the destination buffer of the memory copy.
+  @param  Source                The pointer to the source buffer of the memory copy.
+  @param  Length                Number of bytes to copy from Source to Destination.
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_COPY_MEM)(
+  IN VOID     *Destination,
+  IN VOID     *Source,
+  IN UINTN    Length
+  );
+
+/**
+  The SetMem() function fills a buffer with a specified value.
+
+  @param  Buffer                The pointer to the buffer to fill.
+  @param  Size                  Number of bytes in Buffer to fill.
+  @param  Value                 Value to fill Buffer with.
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_SET_MEM)(
+  IN VOID     *Buffer,
+  IN UINTN    Size,
+  IN UINT8    Value
+  );
+
+///
+/// Enumeration of EFI Interface Types
+///
+typedef enum {
+  ///
+  /// Indicates that the supplied protocol interface is supplied in native form.
+  ///
+  EFI_NATIVE_INTERFACE
+} EFI_INTERFACE_TYPE;
+
+/**
+  Installs a protocol interface on a device handle. If the handle does not exist, it is created and added
+  to the list of handles in the system. InstallMultipleProtocolInterfaces() performs
+  more error checking than InstallProtocolInterface(), so it is recommended that
+  InstallMultipleProtocolInterfaces() be used in place of
+  InstallProtocolInterface()
+
+  @param  Handle                A pointer to the EFI_HANDLE on which the interface is to be installed.
+  @param  Protocol              The numeric ID of the protocol interface.
+  @param  InterfaceType         Indicates whether Interface is supplied in native form.
+  @param  Interface             A pointer to the protocol interface.
+
+  @retval EFI_SUCCESS           The protocol interface was installed.
+  @retval EFI_OUT_OF_RESOURCES  Space for a new handle could not be allocated.
+  @retval EFI_INVALID_PARAMETER Handle is NULL.
+  @retval EFI_INVALID_PARAMETER Protocol is NULL.
+  @retval EFI_INVALID_PARAMETER InterfaceType is not EFI_NATIVE_INTERFACE.
+  @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE)(
+  IN OUT EFI_HANDLE               *Handle,
+  IN     EFI_GUID                 *Protocol,
+  IN     EFI_INTERFACE_TYPE       InterfaceType,
+  IN     VOID                     *Interface
+  );
+
+/**
+  Installs one or more protocol interfaces into the boot services environment.
+
+  @param  Handle                The pointer to a handle to install the new protocol interfaces on,
+                                or a pointer to NULL if a new handle is to be allocated.
+  @param  ...                   A variable argument list containing pairs of protocol GUIDs and protocol
+                                interfaces.
+
+  @retval EFI_SUCCESS           All the protocol interface was installed.
+  @retval EFI_OUT_OF_RESOURCES  There was not enough memory in pool to install all the protocols.
+  @retval EFI_ALREADY_STARTED   A Device Path Protocol instance was passed in that is already present in
+                                the handle database.
+  @retval EFI_INVALID_PARAMETER Handle is NULL.
+  @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)(
+  IN OUT EFI_HANDLE           *Handle,
+  ...
+  );
+
+/**
+  Reinstalls a protocol interface on a device handle.
+
+  @param  Handle                Handle on which the interface is to be reinstalled.
+  @param  Protocol              The numeric ID of the interface.
+  @param  OldInterface          A pointer to the old interface. NULL can be used if a structure is not
+                                associated with Protocol.
+  @param  NewInterface          A pointer to the new interface.
+
+  @retval EFI_SUCCESS           The protocol interface was reinstalled.
+  @retval EFI_NOT_FOUND         The OldInterface on the handle was not found.
+  @retval EFI_ACCESS_DENIED     The protocol interface could not be reinstalled,
+                                because OldInterface is still being used by a
+                                driver that will not release it.
+  @retval EFI_INVALID_PARAMETER Handle is NULL.
+  @retval EFI_INVALID_PARAMETER Protocol is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE)(
+  IN EFI_HANDLE               Handle,
+  IN EFI_GUID                 *Protocol,
+  IN VOID                     *OldInterface,
+  IN VOID                     *NewInterface
+  );
+
+/**
+  Removes a protocol interface from a device handle. It is recommended that
+  UninstallMultipleProtocolInterfaces() be used in place of
+  UninstallProtocolInterface().
+
+  @param  Handle                The handle on which the interface was installed.
+  @param  Protocol              The numeric ID of the interface.
+  @param  Interface             A pointer to the interface.
+
+  @retval EFI_SUCCESS           The interface was removed.
+  @retval EFI_NOT_FOUND         The interface was not found.
+  @retval EFI_ACCESS_DENIED     The interface was not removed because the interface
+                                is still being used by a driver.
+  @retval EFI_INVALID_PARAMETER Handle is NULL.
+  @retval EFI_INVALID_PARAMETER Protocol is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE)(
+  IN EFI_HANDLE               Handle,
+  IN EFI_GUID                 *Protocol,
+  IN VOID                     *Interface
+  );
+
+/**
+  Removes one or more protocol interfaces into the boot services environment.
+
+  @param  Handle                The handle to remove the protocol interfaces from.
+  @param  ...                   A variable argument list containing pairs of protocol GUIDs and
+                                protocol interfaces.
+
+  @retval EFI_SUCCESS           All the protocol interfaces were removed.
+  @retval EFI_INVALID_PARAMETER One of the protocol interfaces was not previously installed on Handle.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)(
+  IN EFI_HANDLE           Handle,
+  ...
+  );
+
+/**
+  Queries a handle to determine if it supports a specified protocol.
+
+  @param  Handle                The handle being queried.
+  @param  Protocol              The published unique identifier of the protocol.
+  @param  Interface             Supplies the address where a pointer to the corresponding Protocol
+                                Interface is returned.
+
+  @retval EFI_SUCCESS           The interface information for the specified protocol was returned.
+  @retval EFI_UNSUPPORTED       The device does not support the specified protocol.
+  @retval EFI_INVALID_PARAMETER Handle is NULL.
+  @retval EFI_INVALID_PARAMETER Protocol is NULL.
+  @retval EFI_INVALID_PARAMETER Interface is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HANDLE_PROTOCOL)(
+  IN  EFI_HANDLE               Handle,
+  IN  EFI_GUID                 *Protocol,
+  OUT VOID                     **Interface
+  );
+
+#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL  0x00000001
+#define EFI_OPEN_PROTOCOL_GET_PROTOCOL        0x00000002
+#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL       0x00000004
+#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008
+#define EFI_OPEN_PROTOCOL_BY_DRIVER           0x00000010
+#define EFI_OPEN_PROTOCOL_EXCLUSIVE           0x00000020
+
+/**
+  Queries a handle to determine if it supports a specified protocol. If the protocol is supported by the
+  handle, it opens the protocol on behalf of the calling agent.
+
+  @param  Handle                The handle for the protocol interface that is being opened.
+  @param  Protocol              The published unique identifier of the protocol.
+  @param  Interface             Supplies the address where a pointer to the corresponding Protocol
+                                Interface is returned.
+  @param  AgentHandle           The handle of the agent that is opening the protocol interface
+                                specified by Protocol and Interface.
+  @param  ControllerHandle      If the agent that is opening a protocol is a driver that follows the
+                                UEFI Driver Model, then this parameter is the controller handle
+                                that requires the protocol interface. If the agent does not follow
+                                the UEFI Driver Model, then this parameter is optional and may
+                                be NULL.
+  @param  Attributes            The open mode of the protocol interface specified by Handle
+                                and Protocol.
+
+  @retval EFI_SUCCESS           An item was added to the open list for the protocol interface, and the
+                                protocol interface was returned in Interface.
+  @retval EFI_UNSUPPORTED       Handle does not support Protocol.
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+  @retval EFI_ACCESS_DENIED     Required attributes can't be supported in current environment.
+  @retval EFI_ALREADY_STARTED   Item on the open list already has requierd attributes whose agent
+                                handle is the same as AgentHandle.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_OPEN_PROTOCOL)(
+  IN  EFI_HANDLE                Handle,
+  IN  EFI_GUID                  *Protocol,
+  OUT VOID                      **Interface, OPTIONAL
+  IN  EFI_HANDLE                AgentHandle,
+  IN  EFI_HANDLE                ControllerHandle,
+  IN  UINT32                    Attributes
+  );
+
+
+/**
+  Closes a protocol on a handle that was opened using OpenProtocol().
+
+  @param  Handle                The handle for the protocol interface that was previously opened
+                                with OpenProtocol(), and is now being closed.
+  @param  Protocol              The published unique identifier of the protocol.
+  @param  AgentHandle           The handle of the agent that is closing the protocol interface.
+  @param  ControllerHandle      If the agent that opened a protocol is a driver that follows the
+                                UEFI Driver Model, then this parameter is the controller handle
+                                that required the protocol interface.
+
+  @retval EFI_SUCCESS           The protocol instance was closed.
+  @retval EFI_INVALID_PARAMETER 1) Handle is NULL.
+                                2) AgentHandle is NULL.
+                                3) ControllerHandle is not NULL and ControllerHandle is not a valid EFI_HANDLE.
+                                4) Protocol is NULL.
+  @retval EFI_NOT_FOUND         1) Handle does not support the protocol specified by Protocol.
+                                2) The protocol interface specified by Handle and Protocol is not
+                                   currently open by AgentHandle and ControllerHandle.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CLOSE_PROTOCOL)(
+  IN EFI_HANDLE               Handle,
+  IN EFI_GUID                 *Protocol,
+  IN EFI_HANDLE               AgentHandle,
+  IN EFI_HANDLE               ControllerHandle
+  );
+
+///
+/// EFI Oprn Protocol Information Entry
+///
+typedef struct {
+  EFI_HANDLE  AgentHandle;
+  EFI_HANDLE  ControllerHandle;
+  UINT32      Attributes;
+  UINT32      OpenCount;
+} EFI_OPEN_PROTOCOL_INFORMATION_ENTRY;
+
+/**
+  Retrieves the list of agents that currently have a protocol interface opened.
+
+  @param  Handle                The handle for the protocol interface that is being queried.
+  @param  Protocol              The published unique identifier of the protocol.
+  @param  EntryBuffer           A pointer to a buffer of open protocol information in the form of
+                                EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.
+  @param  EntryCount            A pointer to the number of entries in EntryBuffer.
+
+  @retval EFI_SUCCESS           The open protocol information was returned in EntryBuffer, and the
+                                number of entries was returned EntryCount.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to allocate EntryBuffer.
+  @retval EFI_NOT_FOUND         Handle does not support the protocol specified by Protocol.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_OPEN_PROTOCOL_INFORMATION)(
+  IN  EFI_HANDLE                          Handle,
+  IN  EFI_GUID                            *Protocol,
+  OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
+  OUT UINTN                               *EntryCount
+  );
+
+/**
+  Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated
+  from pool.
+
+  @param  Handle                The handle from which to retrieve the list of protocol interface
+                                GUIDs.
+  @param  ProtocolBuffer        A pointer to the list of protocol interface GUID pointers that are
+                                installed on Handle.
+  @param  ProtocolBufferCount   A pointer to the number of GUID pointers present in
+                                ProtocolBuffer.
+
+  @retval EFI_SUCCESS           The list of protocol interface GUIDs installed on Handle was returned in
+                                ProtocolBuffer. The number of protocol interface GUIDs was
+                                returned in ProtocolBufferCount.
+  @retval EFI_OUT_OF_RESOURCES  There is not enough pool memory to store the results.
+  @retval EFI_INVALID_PARAMETER Handle is NULL.
+  @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL.
+  @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PROTOCOLS_PER_HANDLE)(
+  IN  EFI_HANDLE      Handle,
+  OUT EFI_GUID        ***ProtocolBuffer,
+  OUT UINTN           *ProtocolBufferCount
+  );
+
+/**
+  Creates an event that is to be signaled whenever an interface is installed for a specified protocol.
+
+  @param  Protocol              The numeric ID of the protocol for which the event is to be registered.
+  @param  Event                 Event that is to be signaled whenever a protocol interface is registered
+                                for Protocol.
+  @param  Registration          A pointer to a memory location to receive the registration value.
+
+  @retval EFI_SUCCESS           The notification event has been registered.
+  @retval EFI_OUT_OF_RESOURCES  Space for the notification event could not be allocated.
+  @retval EFI_INVALID_PARAMETER Protocol is NULL.
+  @retval EFI_INVALID_PARAMETER Event is NULL.
+  @retval EFI_INVALID_PARAMETER Registration is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY)(
+  IN  EFI_GUID                 *Protocol,
+  IN  EFI_EVENT                Event,
+  OUT VOID                     **Registration
+  );
+
+///
+/// Enumeration of EFI Locate Search Types
+///
+typedef enum {
+  ///
+  /// Retrieve all the handles in the handle database.
+  ///
+  AllHandles,
+  ///
+  /// Retrieve the next handle fron a RegisterProtocolNotify() event.
+  ///
+  ByRegisterNotify,
+  ///
+  /// Retrieve the set of handles from the handle database that support a
+  /// specified protocol.
+  ///
+  ByProtocol
+} EFI_LOCATE_SEARCH_TYPE;
+
+/**
+  Returns an array of handles that support a specified protocol.
+
+  @param  SearchType            Specifies which handle(s) are to be returned.
+  @param  Protocol              Specifies the protocol to search by.
+  @param  SearchKey             Specifies the search key.
+  @param  BufferSize            On input, the size in bytes of Buffer. On output, the size in bytes of
+                                the array returned in Buffer (if the buffer was large enough) or the
+                                size, in bytes, of the buffer needed to obtain the array (if the buffer was
+                                not large enough).
+  @param  Buffer                The buffer in which the array is returned.
+
+  @retval EFI_SUCCESS           The array of handles was returned.
+  @retval EFI_NOT_FOUND         No handles match the search.
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize is too small for the result.
+  @retval EFI_INVALID_PARAMETER SearchType is not a member of EFI_LOCATE_SEARCH_TYPE.
+  @retval EFI_INVALID_PARAMETER SearchType is ByRegisterNotify and SearchKey is NULL.
+  @retval EFI_INVALID_PARAMETER SearchType is ByProtocol and Protocol is NULL.
+  @retval EFI_INVALID_PARAMETER One or more matches are found and BufferSize is NULL.
+  @retval EFI_INVALID_PARAMETER BufferSize is large enough for the result and Buffer is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_HANDLE)(
+  IN     EFI_LOCATE_SEARCH_TYPE   SearchType,
+  IN     EFI_GUID                 *Protocol,    OPTIONAL
+  IN     VOID                     *SearchKey,   OPTIONAL
+  IN OUT UINTN                    *BufferSize,
+  OUT    EFI_HANDLE               *Buffer
+  );
+
+/**
+  Locates the handle to a device on the device path that supports the specified protocol.
+
+  @param  Protocol              Specifies the protocol to search for.
+  @param  DevicePath            On input, a pointer to a pointer to the device path. On output, the device
+                                path pointer is modified to point to the remaining part of the device
+                                path.
+  @param  Device                A pointer to the returned device handle.
+
+  @retval EFI_SUCCESS           The resulting handle was returned.
+  @retval EFI_NOT_FOUND         No handles match the search.
+  @retval EFI_INVALID_PARAMETER Protocol is NULL.
+  @retval EFI_INVALID_PARAMETER DevicePath is NULL.
+  @retval EFI_INVALID_PARAMETER A handle matched the search and Device is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_DEVICE_PATH)(
+  IN     EFI_GUID                         *Protocol,
+  IN OUT EFI_DEVICE_PATH_PROTOCOL         **DevicePath,
+  OUT    EFI_HANDLE                       *Device
+  );
+
+/**
+  Adds, updates, or removes a configuration table entry from the EFI System Table.
+
+  @param  Guid                  A pointer to the GUID for the entry to add, update, or remove.
+  @param  Table                 A pointer to the configuration table for the entry to add, update, or
+                                remove. May be NULL.
+
+  @retval EFI_SUCCESS           The (Guid, Table) pair was added, updated, or removed.
+  @retval EFI_NOT_FOUND         An attempt was made to delete a nonexistent entry.
+  @retval EFI_INVALID_PARAMETER Guid is NULL.
+  @retval EFI_OUT_OF_RESOURCES  There is not enough memory available to complete the operation.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE)(
+  IN EFI_GUID                 *Guid,
+  IN VOID                     *Table
+  );
+
+/**
+  Returns an array of handles that support the requested protocol in a buffer allocated from pool.
+
+  @param  SearchType            Specifies which handle(s) are to be returned.
+  @param  Protocol              Provides the protocol to search by.
+                                This parameter is only valid for a SearchType of ByProtocol.
+  @param  SearchKey             Supplies the search key depending on the SearchType.
+  @param  NoHandles             The number of handles returned in Buffer.
+  @param  Buffer                A pointer to the buffer to return the requested array of handles that
+                                support Protocol.
+
+  @retval EFI_SUCCESS           The array of handles was returned in Buffer, and the number of
+                                handles in Buffer was returned in NoHandles.
+  @retval EFI_NOT_FOUND         No handles match the search.
+  @retval EFI_OUT_OF_RESOURCES  There is not enough pool memory to store the matching results.
+  @retval EFI_INVALID_PARAMETER NoHandles is NULL.
+  @retval EFI_INVALID_PARAMETER Buffer is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_HANDLE_BUFFER)(
+  IN     EFI_LOCATE_SEARCH_TYPE       SearchType,
+  IN     EFI_GUID                     *Protocol,      OPTIONAL
+  IN     VOID                         *SearchKey,     OPTIONAL
+  IN OUT UINTN                        *NoHandles,
+  OUT    EFI_HANDLE                   **Buffer
+  );
+
+/**
+  Returns the first protocol instance that matches the given protocol.
+
+  @param  Protocol              Provides the protocol to search for.
+  @param  Registration          Optional registration key returned from
+                                RegisterProtocolNotify().
+  @param  Interface             On return, a pointer to the first interface that matches Protocol and
+                                Registration.
+
+  @retval EFI_SUCCESS           A protocol instance matching Protocol was found and returned in
+                                Interface.
+  @retval EFI_NOT_FOUND         No protocol instances were found that match Protocol and
+                                Registration.
+  @retval EFI_INVALID_PARAMETER Interface is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_PROTOCOL)(
+  IN  EFI_GUID  *Protocol,
+  IN  VOID      *Registration, OPTIONAL
+  OUT VOID      **Interface
+  );
+
+///
+/// EFI Capsule Block Descriptor
+///
+typedef struct {
+  ///
+  /// Length in bytes of the data pointed to by DataBlock/ContinuationPointer.
+  ///
+  UINT64                  Length;
+  union {
+    ///
+    /// Physical address of the data block. This member of the union is
+    /// used if Length is not equal to zero.
+    ///
+    EFI_PHYSICAL_ADDRESS  DataBlock;
+    ///
+    /// Physical address of another block of
+    /// EFI_CAPSULE_BLOCK_DESCRIPTOR structures. This
+    /// member of the union is used if Length is equal to zero. If
+    /// ContinuationPointer is zero this entry represents the end of the list.
+    ///
+    EFI_PHYSICAL_ADDRESS  ContinuationPointer;
+  } Union;
+} EFI_CAPSULE_BLOCK_DESCRIPTOR;
+
+///
+/// EFI Capsule Header.
+///
+typedef struct {
+  ///
+  /// A GUID that defines the contents of a capsule.
+  ///
+  EFI_GUID          CapsuleGuid;
+  ///
+  /// The size of the capsule header. This may be larger than the size of
+  /// the EFI_CAPSULE_HEADER since CapsuleGuid may imply
+  /// extended header entries
+  ///
+  UINT32            HeaderSize;
+  ///
+  /// Bit-mapped list describing the capsule attributes. The Flag values
+  /// of 0x0000 - 0xFFFF are defined by CapsuleGuid. Flag values
+  /// of 0x10000 - 0xFFFFFFFF are defined by this specification
+  ///
+  UINT32            Flags;
+  ///
+  /// Size in bytes of the capsule.
+  ///
+  UINT32            CapsuleImageSize;
+} EFI_CAPSULE_HEADER;
+
+///
+/// The EFI System Table entry must point to an array of capsules
+/// that contain the same CapsuleGuid value. The array must be
+/// prefixed by a UINT32 that represents the size of the array of capsules.
+///
+typedef struct {
+  ///
+  /// the size of the array of capsules.
+  ///
+  UINT32   CapsuleArrayNumber;
+  ///
+  /// Point to an array of capsules that contain the same CapsuleGuid value.
+  ///
+  VOID*    CapsulePtr[1];
+} EFI_CAPSULE_TABLE;
+
+#define CAPSULE_FLAGS_PERSIST_ACROSS_RESET          0x00010000
+#define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE         0x00020000
+#define CAPSULE_FLAGS_INITIATE_RESET                0x00040000
+
+/**
+  Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended
+  consumption, the firmware may process the capsule immediately. If the payload should persist
+  across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must
+  be passed into ResetSystem() and will cause the capsule to be processed by the firmware as
+  part of the reset process.
+
+  @param  CapsuleHeaderArray    Virtual pointer to an array of virtual pointers to the capsules
+                                being passed into update capsule.
+  @param  CapsuleCount          Number of pointers to EFI_CAPSULE_HEADER in
+                                CaspuleHeaderArray.
+  @param  ScatterGatherList     Physical pointer to a set of
+                                EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the
+                                location in physical memory of a set of capsules.
+
+  @retval EFI_SUCCESS           Valid capsule was passed. If
+                                CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the
+                                capsule has been successfully processed by the firmware.
+  @retval EFI_INVALID_PARAMETER CapsuleSize is NULL, or an incompatible set of flags were
+                                set in the capsule header.
+  @retval EFI_INVALID_PARAMETER CapsuleCount is 0.
+  @retval EFI_DEVICE_ERROR      The capsule update was started, but failed due to a device error.
+  @retval EFI_UNSUPPORTED       The capsule type is not supported on this platform.
+  @retval EFI_OUT_OF_RESOURCES  When ExitBootServices() has been previously called this error indicates the capsule
+                                is compatible with this platform but is not capable of being submitted or processed
+                                in runtime. The caller may resubmit the capsule prior to ExitBootServices().
+  @retval EFI_OUT_OF_RESOURCES  When ExitBootServices() has not been previously called then this error indicates
+                                the capsule is compatible with this platform but there are insufficient resources to process.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UPDATE_CAPSULE)(
+  IN EFI_CAPSULE_HEADER     **CapsuleHeaderArray,
+  IN UINTN                  CapsuleCount,
+  IN EFI_PHYSICAL_ADDRESS   ScatterGatherList   OPTIONAL
+  );
+
+/**
+  Returns if the capsule can be supported via UpdateCapsule().
+
+  @param  CapsuleHeaderArray    Virtual pointer to an array of virtual pointers to the capsules
+                                being passed into update capsule.
+  @param  CapsuleCount          Number of pointers to EFI_CAPSULE_HEADER in
+                                CaspuleHeaderArray.
+  @param  MaxiumCapsuleSize     On output the maximum size that UpdateCapsule() can
+                                support as an argument to UpdateCapsule() via
+                                CapsuleHeaderArray and ScatterGatherList.
+  @param  ResetType             Returns the type of reset required for the capsule update.
+
+  @retval EFI_SUCCESS           Valid answer returned.
+  @retval EFI_UNSUPPORTED       The capsule type is not supported on this platform, and
+                                MaximumCapsuleSize and ResetType are undefined.
+  @retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL.
+  @retval EFI_OUT_OF_RESOURCES  When ExitBootServices() has been previously called this error indicates the capsule
+                                is compatible with this platform but is not capable of being submitted or processed
+                                in runtime. The caller may resubmit the capsule prior to ExitBootServices().
+  @retval EFI_OUT_OF_RESOURCES  When ExitBootServices() has not been previously called then this error indicates
+                                the capsule is compatible with this platform but there are insufficient resources to process.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_QUERY_CAPSULE_CAPABILITIES)(
+  IN  EFI_CAPSULE_HEADER     **CapsuleHeaderArray,
+  IN  UINTN                  CapsuleCount,
+  OUT UINT64                 *MaximumCapsuleSize,
+  OUT EFI_RESET_TYPE         *ResetType
+  );
+
+/**
+  Returns information about the EFI variables.
+
+  @param  Attributes                   Attributes bitmask to specify the type of variables on
+                                       which to return information.
+  @param  MaximumVariableStorageSize   On output the maximum size of the storage space
+                                       available for the EFI variables associated with the
+                                       attributes specified.
+  @param  RemainingVariableStorageSize Returns the remaining size of the storage space
+                                       available for the EFI variables associated with the
+                                       attributes specified.
+  @param  MaximumVariableSize          Returns the maximum size of the individual EFI
+                                       variables associated with the attributes specified.
+
+  @retval EFI_SUCCESS                  Valid answer returned.
+  @retval EFI_INVALID_PARAMETER        An invalid combination of attribute bits was supplied
+  @retval EFI_UNSUPPORTED              The attribute is not supported on this platform, and the
+                                       MaximumVariableStorageSize,
+                                       RemainingVariableStorageSize, MaximumVariableSize
+                                       are undefined.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_QUERY_VARIABLE_INFO)(
+  IN  UINT32            Attributes,
+  OUT UINT64            *MaximumVariableStorageSize,
+  OUT UINT64            *RemainingVariableStorageSize,
+  OUT UINT64            *MaximumVariableSize
+  );
+
+//
+// Firmware should stop at a firmware user interface on next boot
+//
+#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI                    0x0000000000000001
+#define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION             0x0000000000000002
+#define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED  0x0000000000000004
+#define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED            0x0000000000000008
+#define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED     0x0000000000000010
+
+//
+// EFI Runtime Services Table
+//
+#define EFI_SYSTEM_TABLE_SIGNATURE      SIGNATURE_64 ('I','B','I',' ','S','Y','S','T')
+#define EFI_2_40_SYSTEM_TABLE_REVISION  ((2 << 16) | (40))
+#define EFI_2_31_SYSTEM_TABLE_REVISION  ((2 << 16) | (31))
+#define EFI_2_30_SYSTEM_TABLE_REVISION  ((2 << 16) | (30))
+#define EFI_2_20_SYSTEM_TABLE_REVISION  ((2 << 16) | (20))
+#define EFI_2_10_SYSTEM_TABLE_REVISION  ((2 << 16) | (10))
+#define EFI_2_00_SYSTEM_TABLE_REVISION  ((2 << 16) | (00))
+#define EFI_1_10_SYSTEM_TABLE_REVISION  ((1 << 16) | (10))
+#define EFI_1_02_SYSTEM_TABLE_REVISION  ((1 << 16) | (02))
+#define EFI_SYSTEM_TABLE_REVISION       EFI_2_40_SYSTEM_TABLE_REVISION
+#define EFI_SPECIFICATION_VERSION       EFI_SYSTEM_TABLE_REVISION
+
+#define EFI_RUNTIME_SERVICES_SIGNATURE  SIGNATURE_64 ('R','U','N','T','S','E','R','V')
+#define EFI_RUNTIME_SERVICES_REVISION   EFI_SPECIFICATION_VERSION
+
+///
+/// EFI Runtime Services Table.
+///
+typedef struct {
+  ///
+  /// The table header for the EFI Runtime Services Table.
+  ///
+  EFI_TABLE_HEADER                Hdr;
+
+  //
+  // Time Services
+  //
+  EFI_GET_TIME                    GetTime;
+  EFI_SET_TIME                    SetTime;
+  EFI_GET_WAKEUP_TIME             GetWakeupTime;
+  EFI_SET_WAKEUP_TIME             SetWakeupTime;
+
+  //
+  // Virtual Memory Services
+  //
+  EFI_SET_VIRTUAL_ADDRESS_MAP     SetVirtualAddressMap;
+  EFI_CONVERT_POINTER             ConvertPointer;
+
+  //
+  // Variable Services
+  //
+  EFI_GET_VARIABLE                GetVariable;
+  EFI_GET_NEXT_VARIABLE_NAME      GetNextVariableName;
+  EFI_SET_VARIABLE                SetVariable;
+
+  //
+  // Miscellaneous Services
+  //
+  EFI_GET_NEXT_HIGH_MONO_COUNT    GetNextHighMonotonicCount;
+  EFI_RESET_SYSTEM                ResetSystem;
+
+  //
+  // UEFI 2.0 Capsule Services
+  //
+  EFI_UPDATE_CAPSULE              UpdateCapsule;
+  EFI_QUERY_CAPSULE_CAPABILITIES  QueryCapsuleCapabilities;
+
+  //
+  // Miscellaneous UEFI 2.0 Service
+  //
+  EFI_QUERY_VARIABLE_INFO         QueryVariableInfo;
+} EFI_RUNTIME_SERVICES;
+
+
+#define EFI_BOOT_SERVICES_SIGNATURE   SIGNATURE_64 ('B','O','O','T','S','E','R','V')
+#define EFI_BOOT_SERVICES_REVISION    EFI_SPECIFICATION_VERSION
+
+///
+/// EFI Boot Services Table.
+///
+typedef struct {
+  ///
+  /// The table header for the EFI Boot Services Table.
+  ///
+  EFI_TABLE_HEADER                Hdr;
+
+  //
+  // Task Priority Services
+  //
+  EFI_RAISE_TPL                   RaiseTPL;
+  EFI_RESTORE_TPL                 RestoreTPL;
+
+  //
+  // Memory Services
+  //
+  EFI_ALLOCATE_PAGES              AllocatePages;
+  EFI_FREE_PAGES                  FreePages;
+  EFI_GET_MEMORY_MAP              GetMemoryMap;
+  EFI_ALLOCATE_POOL               AllocatePool;
+  EFI_FREE_POOL                   FreePool;
+
+  //
+  // Event & Timer Services
+  //
+  EFI_CREATE_EVENT                  CreateEvent;
+  EFI_SET_TIMER                     SetTimer;
+  EFI_WAIT_FOR_EVENT                WaitForEvent;
+  EFI_SIGNAL_EVENT                  SignalEvent;
+  EFI_CLOSE_EVENT                   CloseEvent;
+  EFI_CHECK_EVENT                   CheckEvent;
+
+  //
+  // Protocol Handler Services
+  //
+  EFI_INSTALL_PROTOCOL_INTERFACE    InstallProtocolInterface;
+  EFI_REINSTALL_PROTOCOL_INTERFACE  ReinstallProtocolInterface;
+  EFI_UNINSTALL_PROTOCOL_INTERFACE  UninstallProtocolInterface;
+  EFI_HANDLE_PROTOCOL               HandleProtocol;
+  VOID                              *Reserved;
+  EFI_REGISTER_PROTOCOL_NOTIFY      RegisterProtocolNotify;
+  EFI_LOCATE_HANDLE                 LocateHandle;
+  EFI_LOCATE_DEVICE_PATH            LocateDevicePath;
+  EFI_INSTALL_CONFIGURATION_TABLE   InstallConfigurationTable;
+
+  //
+  // Image Services
+  //
+  EFI_IMAGE_LOAD                    LoadImage;
+  EFI_IMAGE_START                   StartImage;
+  EFI_EXIT                          Exit;
+  EFI_IMAGE_UNLOAD                  UnloadImage;
+  EFI_EXIT_BOOT_SERVICES            ExitBootServices;
+
+  //
+  // Miscellaneous Services
+  //
+  EFI_GET_NEXT_MONOTONIC_COUNT      GetNextMonotonicCount;
+  EFI_STALL                         Stall;
+  EFI_SET_WATCHDOG_TIMER            SetWatchdogTimer;
+
+  //
+  // DriverSupport Services
+  //
+  EFI_CONNECT_CONTROLLER            ConnectController;
+  EFI_DISCONNECT_CONTROLLER         DisconnectController;
+
+  //
+  // Open and Close Protocol Services
+  //
+  EFI_OPEN_PROTOCOL                 OpenProtocol;
+  EFI_CLOSE_PROTOCOL                CloseProtocol;
+  EFI_OPEN_PROTOCOL_INFORMATION     OpenProtocolInformation;
+
+  //
+  // Library Services
+  //
+  EFI_PROTOCOLS_PER_HANDLE          ProtocolsPerHandle;
+  EFI_LOCATE_HANDLE_BUFFER          LocateHandleBuffer;
+  EFI_LOCATE_PROTOCOL               LocateProtocol;
+  EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES    InstallMultipleProtocolInterfaces;
+  EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES  UninstallMultipleProtocolInterfaces;
+
+  //
+  // 32-bit CRC Services
+  //
+  EFI_CALCULATE_CRC32               CalculateCrc32;
+
+  //
+  // Miscellaneous Services
+  //
+  EFI_COPY_MEM                      CopyMem;
+  EFI_SET_MEM                       SetMem;
+  EFI_CREATE_EVENT_EX               CreateEventEx;
+} EFI_BOOT_SERVICES;
+
+///
+/// Contains a set of GUID/pointer pairs comprised of the ConfigurationTable field in the
+/// EFI System Table.
+///
+typedef struct {
+  ///
+  /// The 128-bit GUID value that uniquely identifies the system configuration table.
+  ///
+  EFI_GUID                          VendorGuid;
+  ///
+  /// A pointer to the table associated with VendorGuid.
+  ///
+  VOID                              *VendorTable;
+} EFI_CONFIGURATION_TABLE;
+
+///
+/// EFI System Table
+///
+typedef struct {
+  ///
+  /// The table header for the EFI System Table.
+  ///
+  EFI_TABLE_HEADER                  Hdr;
+  ///
+  /// A pointer to a null terminated string that identifies the vendor
+  /// that produces the system firmware for the platform.
+  ///
+  CHAR16                            *FirmwareVendor;
+  ///
+  /// A firmware vendor specific value that identifies the revision
+  /// of the system firmware for the platform.
+  ///
+  UINT32                            FirmwareRevision;
+  ///
+  /// The handle for the active console input device. This handle must support
+  /// EFI_SIMPLE_TEXT_INPUT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
+  ///
+  EFI_HANDLE                        ConsoleInHandle;
+  ///
+  /// A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL interface that is
+  /// associated with ConsoleInHandle.
+  ///
+  EFI_SIMPLE_TEXT_INPUT_PROTOCOL    *ConIn;
+  ///
+  /// The handle for the active console output device.
+  ///
+  EFI_HANDLE                        ConsoleOutHandle;
+  ///
+  /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
+  /// that is associated with ConsoleOutHandle.
+  ///
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   *ConOut;
+  ///
+  /// The handle for the active standard error console device.
+  /// This handle must support the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
+  ///
+  EFI_HANDLE                        StandardErrorHandle;
+  ///
+  /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
+  /// that is associated with StandardErrorHandle.
+  ///
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   *StdErr;
+  ///
+  /// A pointer to the EFI Runtime Services Table.
+  ///
+  EFI_RUNTIME_SERVICES              *RuntimeServices;
+  ///
+  /// A pointer to the EFI Boot Services Table.
+  ///
+  EFI_BOOT_SERVICES                 *BootServices;
+  ///
+  /// The number of system configuration tables in the buffer ConfigurationTable.
+  ///
+  UINTN                             NumberOfTableEntries;
+  ///
+  /// A pointer to the system configuration tables.
+  /// The number of entries in the table is NumberOfTableEntries.
+  ///
+  EFI_CONFIGURATION_TABLE           *ConfigurationTable;
+} EFI_SYSTEM_TABLE;
+
+/**
+  This is the declaration of an EFI image entry point. This entry point is
+  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+  both device drivers and bus drivers.
+
+  @param  ImageHandle           The firmware allocated handle for the UEFI image.
+  @param  SystemTable           A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval Others                An unexpected error occurred.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_ENTRY_POINT)(
+  IN  EFI_HANDLE                   ImageHandle,
+  IN  EFI_SYSTEM_TABLE             *SystemTable
+  );
+
+//
+// EFI Load Options Attributes
+//
+#define LOAD_OPTION_ACTIVE            0x00000001
+#define LOAD_OPTION_FORCE_RECONNECT   0x00000002
+#define LOAD_OPTION_HIDDEN            0x00000008
+#define LOAD_OPTION_CATEGORY          0x00001F00
+
+#define LOAD_OPTION_CATEGORY_BOOT     0x00000000
+#define LOAD_OPTION_CATEGORY_APP      0x00000100
+
+#define EFI_BOOT_OPTION_SUPPORT_KEY   0x00000001
+#define EFI_BOOT_OPTION_SUPPORT_APP   0x00000002
+#define EFI_BOOT_OPTION_SUPPORT_COUNT 0x00000300
+
+///
+/// EFI Boot Key Data
+///
+typedef union {
+  struct {
+    ///
+    /// Indicates the revision of the EFI_KEY_OPTION structure. This revision level should be 0.
+    ///
+    UINT32  Revision        : 8;
+    ///
+    /// Either the left or right Shift keys must be pressed (1) or must not be pressed (0).
+    ///
+    UINT32  ShiftPressed    : 1;
+    ///
+    /// Either the left or right Control keys must be pressed (1) or must not be pressed (0).
+    ///
+    UINT32  ControlPressed  : 1;
+    ///
+    /// Either the left or right Alt keys must be pressed (1) or must not be pressed (0).
+    ///
+    UINT32  AltPressed      : 1;
+    ///
+    /// Either the left or right Logo keys must be pressed (1) or must not be pressed (0).
+    ///
+    UINT32  LogoPressed     : 1;
+    ///
+    /// The Menu key must be pressed (1) or must not be pressed (0).
+    ///
+    UINT32  MenuPressed     : 1;
+    ///
+    /// The SysReq key must be pressed (1) or must not be pressed (0).
+    ///
+    UINT32  SysReqPressed    : 1;
+    UINT32  Reserved        : 16;
+    ///
+    /// Specifies the actual number of entries in EFI_KEY_OPTION.Keys, from 0-3. If
+    /// zero, then only the shift state is considered. If more than one, then the boot option will
+    /// only be launched if all of the specified keys are pressed with the same shift state.
+    ///
+    UINT32  InputKeyCount   : 2;
+  } Options;
+  UINT32  PackedValue;
+} EFI_BOOT_KEY_DATA;
+
+///
+/// EFI Key Option.
+///
+#pragma pack(1)
+typedef struct {
+  ///
+  /// Specifies options about how the key will be processed.
+  ///
+  EFI_BOOT_KEY_DATA  KeyData;
+  ///
+  /// The CRC-32 which should match the CRC-32 of the entire EFI_LOAD_OPTION to
+  /// which BootOption refers. If the CRC-32s do not match this value, then this key
+  /// option is ignored.
+  ///
+  UINT32             BootOptionCrc;
+  ///
+  /// The Boot#### option which will be invoked if this key is pressed and the boot option
+  /// is active (LOAD_OPTION_ACTIVE is set).
+  ///
+  UINT16             BootOption;
+  ///
+  /// The key codes to compare against those returned by the
+  /// EFI_SIMPLE_TEXT_INPUT and EFI_SIMPLE_TEXT_INPUT_EX protocols.
+  /// The number of key codes (0-3) is specified by the EFI_KEY_CODE_COUNT field in KeyOptions.
+  ///
+  //EFI_INPUT_KEY      Keys[];
+} EFI_KEY_OPTION;
+#pragma pack()
+
+//
+// EFI File location to boot from on removable media devices
+//
+#define EFI_REMOVABLE_MEDIA_FILE_NAME_IA32    L"\\EFI\\BOOT\\BOOTIA32.EFI"
+#define EFI_REMOVABLE_MEDIA_FILE_NAME_IA64    L"\\EFI\\BOOT\\BOOTIA64.EFI"
+#define EFI_REMOVABLE_MEDIA_FILE_NAME_X64     L"\\EFI\\BOOT\\BOOTX64.EFI"
+#define EFI_REMOVABLE_MEDIA_FILE_NAME_ARM     L"\\EFI\\BOOT\\BOOTARM.EFI"
+#define EFI_REMOVABLE_MEDIA_FILE_NAME_AARCH64 L"\\EFI\\BOOT\\BOOTAA64.EFI"
+
+#if   defined (MDE_CPU_IA32)
+  #define EFI_REMOVABLE_MEDIA_FILE_NAME   EFI_REMOVABLE_MEDIA_FILE_NAME_IA32
+#elif defined (MDE_CPU_IPF)
+  #define EFI_REMOVABLE_MEDIA_FILE_NAME   EFI_REMOVABLE_MEDIA_FILE_NAME_IA64
+#elif defined (MDE_CPU_X64)
+  #define EFI_REMOVABLE_MEDIA_FILE_NAME   EFI_REMOVABLE_MEDIA_FILE_NAME_X64
+#elif defined (MDE_CPU_EBC)
+#elif defined (MDE_CPU_ARM)
+  #define EFI_REMOVABLE_MEDIA_FILE_NAME   EFI_REMOVABLE_MEDIA_FILE_NAME_ARM
+#elif defined (MDE_CPU_AARCH64)
+  #define EFI_REMOVABLE_MEDIA_FILE_NAME   EFI_REMOVABLE_MEDIA_FILE_NAME_AARCH64
+#else
+  #error Unknown Processor Type
+#endif
+
+#include "efi/Uefi/UefiPxe.h"
+#include "efi/Uefi/UefiGpt.h"
+#include "efi/Uefi/UefiInternalFormRepresentation.h"
+
+#endif
diff --git a/wimboot/wimboot-2.7.3/src/efi/X64/ProcessorBind.h b/wimboot/wimboot-2.7.3/src/efi/X64/ProcessorBind.h
new file mode 100644 (file)
index 0000000..9b4c61b
--- /dev/null
@@ -0,0 +1,294 @@
+/** @file
+  Processor or Compiler specific defines and types x64 (Intel 64, AMD64).
+
+  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __PROCESSOR_BIND_H__
+#define __PROCESSOR_BIND_H__
+
+///
+/// Define the processor type so other code can make processor based choices
+///
+#define MDE_CPU_X64
+
+//
+// Make sure we are using the correct packing rules per EFI specification
+//
+#if !defined(__GNUC__)
+#pragma pack()
+#endif
+
+
+#if defined(__INTEL_COMPILER)
+//
+// Disable ICC's remark #869: "Parameter" was never referenced warning.
+// This is legal ANSI C code so we disable the remark that is turned on with -Wall
+//
+#pragma warning ( disable : 869 )
+
+//
+// Disable ICC's remark #1418: external function definition with no prior declaration.
+// This is legal ANSI C code so we disable the remark that is turned on with /W4
+//
+#pragma warning ( disable : 1418 )
+
+//
+// Disable ICC's remark #1419: external declaration in primary source file
+// This is legal ANSI C code so we disable the remark that is turned on with /W4
+//
+#pragma warning ( disable : 1419 )
+
+//
+// Disable ICC's remark #593: "Variable" was set but never used.
+// This is legal ANSI C code so we disable the remark that is turned on with /W4
+//
+#pragma warning ( disable : 593 )
+
+#endif
+
+
+#if defined(_MSC_EXTENSIONS)
+
+//
+// Disable warning that make it impossible to compile at /W4
+// This only works for Microsoft* tools
+//
+
+//
+// Disabling bitfield type checking warnings.
+//
+#pragma warning ( disable : 4214 )
+
+//
+// Disabling the unreferenced formal parameter warnings.
+//
+#pragma warning ( disable : 4100 )
+
+//
+// Disable slightly different base types warning as CHAR8 * can not be set
+// to a constant string.
+//
+#pragma warning ( disable : 4057 )
+
+//
+// ASSERT(FALSE) or while (TRUE) are legal constructes so supress this warning
+//
+#pragma warning ( disable : 4127 )
+
+//
+// This warning is caused by functions defined but not used. For precompiled header only.
+//
+#pragma warning ( disable : 4505 )
+
+//
+// This warning is caused by empty (after preprocessing) source file. For precompiled header only.
+//
+#pragma warning ( disable : 4206 )
+
+#endif
+
+
+#if defined(_MSC_EXTENSIONS)
+  //
+  // use Microsoft C complier dependent integer width types
+  //
+
+  ///
+  /// 8-byte unsigned value
+  ///
+  typedef unsigned __int64    UINT64;
+  ///
+  /// 8-byte signed value
+  ///
+  typedef __int64             INT64;
+  ///
+  /// 4-byte unsigned value
+  ///
+  typedef unsigned __int32    UINT32;
+  ///
+  /// 4-byte signed value
+  ///
+  typedef __int32             INT32;
+  ///
+  /// 2-byte unsigned value
+  ///
+  typedef unsigned short      UINT16;
+  ///
+  /// 2-byte Character.  Unless otherwise specified all strings are stored in the
+  /// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards.
+  ///
+  typedef unsigned short      CHAR16;
+  ///
+  /// 2-byte signed value
+  ///
+  typedef short               INT16;
+  ///
+  /// Logical Boolean.  1-byte value containing 0 for FALSE or a 1 for TRUE.  Other
+  /// values are undefined.
+  ///
+  typedef unsigned char       BOOLEAN;
+  ///
+  /// 1-byte unsigned value
+  ///
+  typedef unsigned char       UINT8;
+  ///
+  /// 1-byte Character
+  ///
+  typedef char                CHAR8;
+  ///
+  /// 1-byte signed value
+  ///
+  typedef signed char         INT8;
+#else
+  ///
+  /// 8-byte unsigned value
+  ///
+  typedef unsigned long long  UINT64;
+  ///
+  /// 8-byte signed value
+  ///
+  typedef long long           INT64;
+  ///
+  /// 4-byte unsigned value
+  ///
+  typedef unsigned int        UINT32;
+  ///
+  /// 4-byte signed value
+  ///
+  typedef int                 INT32;
+  ///
+  /// 2-byte unsigned value
+  ///
+  typedef unsigned short      UINT16;
+  ///
+  /// 2-byte Character.  Unless otherwise specified all strings are stored in the
+  /// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards.
+  ///
+  typedef unsigned short      CHAR16;
+  ///
+  /// 2-byte signed value
+  ///
+  typedef short               INT16;
+  ///
+  /// Logical Boolean.  1-byte value containing 0 for FALSE or a 1 for TRUE.  Other
+  /// values are undefined.
+  ///
+  typedef unsigned char       BOOLEAN;
+  ///
+  /// 1-byte unsigned value
+  ///
+  typedef unsigned char       UINT8;
+  ///
+  /// 1-byte Character
+  ///
+  typedef char                CHAR8;
+  ///
+  /// 1-byte signed value
+  ///
+  typedef signed char         INT8;
+#endif
+
+///
+/// Unsigned value of native width.  (4 bytes on supported 32-bit processor instructions,
+/// 8 bytes on supported 64-bit processor instructions)
+///
+typedef UINT64  UINTN;
+///
+/// Signed value of native width.  (4 bytes on supported 32-bit processor instructions,
+/// 8 bytes on supported 64-bit processor instructions)
+///
+typedef INT64   INTN;
+
+
+//
+// Processor specific defines
+//
+
+///
+/// A value of native width with the highest bit set.
+///
+#define MAX_BIT     0x8000000000000000ULL
+///
+/// A value of native width with the two highest bits set.
+///
+#define MAX_2_BITS  0xC000000000000000ULL
+
+///
+/// Maximum legal x64 address
+///
+#define MAX_ADDRESS   0xFFFFFFFFFFFFFFFFULL
+
+///
+/// Maximum legal x64 INTN and UINTN values.
+///
+#define MAX_INTN   ((INTN)0x7FFFFFFFFFFFFFFFULL)
+#define MAX_UINTN  ((UINTN)0xFFFFFFFFFFFFFFFFULL)
+
+///
+/// The stack alignment required for x64
+///
+#define CPU_STACK_ALIGNMENT   16
+
+//
+// Modifier to ensure that all protocol member functions and EFI intrinsics
+// use the correct C calling convention. All protocol member functions and
+// EFI intrinsics are required to modify their member functions with EFIAPI.
+//
+#ifdef EFIAPI
+  ///
+  /// If EFIAPI is already defined, then we use that definition.
+  ///
+#elif defined(_MSC_EXTENSIONS)
+  ///
+  /// Microsoft* compiler specific method for EFIAPI calling convension
+  ///
+  #define EFIAPI __cdecl
+#elif defined(__GNUC__)
+  ///
+  /// Define the standard calling convention reguardless of optimization level.
+  /// The GCC support assumes a GCC compiler that supports the EFI ABI. The EFI
+  /// ABI is much closer to the x64 Microsoft* ABI than standard x64 (x86-64)
+  /// GCC ABI. Thus a standard x64 (x86-64) GCC compiler can not be used for
+  /// x64. Warning the assembly code in the MDE x64 does not follow the correct
+  /// ABI for the standard x64 (x86-64) GCC.
+  ///
+  #define EFIAPI
+#else
+  ///
+  /// The default for a non Microsoft* or GCC compiler is to assume the EFI ABI
+  /// is the standard.
+  ///
+  #define EFIAPI
+#endif
+
+#if defined(__GNUC__)
+  ///
+  /// For GNU assembly code, .global or .globl can declare global symbols.
+  /// Define this macro to unify the usage.
+  ///
+  #define ASM_GLOBAL .globl
+#endif
+
+/**
+  Return the pointer to the first instruction of a function given a function pointer.
+  On x64 CPU architectures, these two pointer values are the same,
+  so the implementation of this macro is very simple.
+
+  @param  FunctionPointer   A pointer to a function.
+
+  @return The pointer to the first instruction of a function given a function pointer.
+
+**/
+#define FUNCTION_ENTRY_POINT(FunctionPointer) (VOID *)(UINTN)(FunctionPointer)
+
+#endif
+
diff --git a/wimboot/wimboot-2.7.3/src/efi/import.pl b/wimboot/wimboot-2.7.3/src/efi/import.pl
new file mode 100644 (file)
index 0000000..2369ce3
--- /dev/null
@@ -0,0 +1,120 @@
+#!/usr/bin/perl -w
+
+=head1 NAME
+
+import.pl
+
+=head1 SYNOPSIS
+
+import.pl [options] /path/to/edk2/edk2
+
+Options:
+
+    -h,--help          Display brief help message
+    -v,--verbose       Increase verbosity
+    -q,--quiet         Decrease verbosity
+
+=cut
+
+use File::Spec::Functions qw ( :ALL );
+use File::Find;
+use File::Path;
+use Getopt::Long;
+use Pod::Usage;
+use FindBin;
+use strict;
+use warnings;
+
+my $verbosity = 0;
+
+sub try_import_file {
+  my $wimbootdir = shift;
+  my $edktop = shift;
+  my $edkdirs = shift;
+  my $filename = shift;
+
+  # Skip everything except headers
+  return unless $filename =~ /\.h$/;
+
+  # Skip files that are wimboot native headers
+  my $outfile = catfile ( $wimbootdir, $filename );
+  if ( -s $outfile ) {
+    open my $outfh, "<$outfile" or die "Could not open $outfile: $!\n";
+    my $line = <$outfh>;
+    close $outfh;
+    chomp $line;
+    return if $line =~ /^\#ifndef\s+_WIMBOOT_\S+_H$/;
+  }
+
+  # Search for importable header
+  foreach my $edkdir ( @$edkdirs ) {
+    my $infile = catfile ( $edktop, $edkdir, $filename );
+    if ( -e $infile ) {
+      # We have found a matching source file - import it
+      print "$filename <- ".catfile ( $edkdir, $filename )."\n"
+         if $verbosity >= 1;
+      open my $infh, "<$infile" or die "Could not open $infile: $!\n";
+      ( undef, my $outdir, undef ) = splitpath ( $outfile );
+      mkpath ( $outdir );
+      open my $outfh, ">$outfile" or die "Could not open $outfile: $!\n";
+      my @dependencies = ();
+      while ( <$infh> ) {
+       # Strip CR and trailing whitespace
+       s/\r//g;
+       s/\s*$//g;
+       chomp;
+       # Update include lines, and record included files
+       if ( s/^\#include\s+[<\"](\S+)[>\"]/\#include "efi\/$1"/ ) {
+         push @dependencies, $1;
+       }
+       # Write out line
+       print $outfh "$_\n";
+      }
+      close $outfh;
+      close $infh;
+      # Recurse to handle any included files that we don't already have
+      foreach my $dependency ( @dependencies ) {
+       if ( ! -e catfile ( $wimbootdir, $dependency ) ) {
+         print "...following dependency on $dependency\n" if $verbosity >= 1;
+         try_import_file ( $wimbootdir, $edktop, $edkdirs, $dependency );
+       }
+      }
+      return;
+    }
+  }
+  die "$filename has no equivalent in $edktop\n";
+}
+
+# Parse command-line options
+Getopt::Long::Configure ( 'bundling', 'auto_abbrev' );
+GetOptions (
+  'verbose|v+' => sub { $verbosity++; },
+  'quiet|q+' => sub { $verbosity--; },
+  'help|h' => sub { pod2usage ( 1 ); },
+) or die "Could not parse command-line options\n";
+pod2usage ( 1 ) unless @ARGV == 1;
+my $edktop = shift;
+
+# Identify edk import directories
+my $edkdirs = [ "MdePkg/Include", "IntelFrameworkPkg/Include",
+               "MdeModulePkg/Include", "EdkCompatibilityPkg/Foundation" ];
+foreach my $edkdir ( @$edkdirs ) {
+  die "Directory \"$edktop\" does not appear to contain the EFI EDK2 "
+      ."(missing \"$edkdir\")\n" unless -d catdir ( $edktop, $edkdir );
+}
+
+# Identify wimboot EFI includes directory
+my $wimbootdir = $FindBin::Bin;
+die "Directory \"$wimbootdir\" does not contain the wimboot EFI includes\n"
+    unless -e catfile ( $wimbootdir, "../wimboot.h" );
+
+if ( $verbosity >= 1 ) {
+  print "Importing EFI headers into $wimbootdir\nfrom ";
+  print join ( "\n and ", map { catdir ( $edktop, $_ ) } @$edkdirs )."\n";
+}
+
+# Import headers
+find ( { wanted => sub {
+  try_import_file ( $wimbootdir, $edktop, $edkdirs,
+                   abs2rel ( $_, $wimbootdir ) );
+}, no_chdir => 1 }, $wimbootdir );
diff --git a/wimboot/wimboot-2.7.3/src/efiblock.c b/wimboot/wimboot-2.7.3/src/efiblock.c
new file mode 100644 (file)
index 0000000..fd79411
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * EFI block device
+ *
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include "wimboot.h"
+#include "vdisk.h"
+#include "efi.h"
+#include "efipath.h"
+#include "efiblock.h"
+
+/** A block I/O device */
+struct efi_block {
+       /** EFI block I/O protocol */
+       EFI_BLOCK_IO_PROTOCOL block;
+       /** Device path */
+       EFI_DEVICE_PATH_PROTOCOL *path;
+       /** Starting LBA */
+       uint64_t lba;
+       /** Name */
+       const char *name;
+};
+
+/**
+ * Reset block I/O protocol
+ *
+ * @v this             Block I/O protocol
+ * @v extended         Perform extended verification
+ * @ret efirc          EFI status code
+ */
+static EFI_STATUS EFIAPI
+efi_reset_blocks ( EFI_BLOCK_IO_PROTOCOL *this, BOOLEAN extended ) {
+       struct efi_block *block =
+               container_of ( this, struct efi_block, block );
+       void *retaddr = __builtin_return_address ( 0 );
+
+       DBG2 ( "EFI %s %sreset -> %p\n",
+              block->name, ( extended ? "extended " : "" ), retaddr );
+       return 0;
+}
+
+/**
+ * Read blocks
+ *
+ * @v this             Block I/O protocol
+ * @v media            Media ID
+ * @v lba              Starting LBA
+ * @v len              Length of data
+ * @v data             Data buffer
+ * @ret efirc          EFI status code
+ */
+static EFI_STATUS EFIAPI
+efi_read_blocks ( EFI_BLOCK_IO_PROTOCOL *this, UINT32 media, EFI_LBA lba,
+                 UINTN len, VOID *data ) {
+       struct efi_block *block =
+               container_of ( this, struct efi_block, block );
+       void *retaddr = __builtin_return_address ( 0 );
+
+       DBG2 ( "EFI %s read media %08x LBA %#llx to %p+%zx -> %p\n",
+              block->name, media, lba, data, ( ( size_t ) len ), retaddr );
+       vdisk_read ( ( lba + block->lba ), ( len / VDISK_SECTOR_SIZE ), data );
+       return 0;
+}
+
+/**
+ * Write blocks
+ *
+ * @v this             Block I/O protocol
+ * @v media            Media ID
+ * @v lba              Starting LBA
+ * @v len              Length of data
+ * @v data             Data buffer
+ * @ret efirc          EFI status code
+ */
+static EFI_STATUS EFIAPI
+efi_write_blocks ( EFI_BLOCK_IO_PROTOCOL *this __unused,
+                  UINT32 media __unused, EFI_LBA lba __unused,
+                  UINTN len __unused, VOID *data __unused ) {
+       struct efi_block *block =
+               container_of ( this, struct efi_block, block );
+       void *retaddr = __builtin_return_address ( 0 );
+
+       DBG2 ( "EFI %s write media %08x LBA %#llx from %p+%zx -> %p\n",
+              block->name, media, lba, data, ( ( size_t ) len ), retaddr );
+       return EFI_WRITE_PROTECTED;
+}
+
+/**
+ * Flush block operations
+ *
+ * @v this             Block I/O protocol
+ * @ret efirc          EFI status code
+ */
+static EFI_STATUS EFIAPI
+efi_flush_blocks ( EFI_BLOCK_IO_PROTOCOL *this ) {
+       struct efi_block *block =
+               container_of ( this, struct efi_block, block );
+       void *retaddr = __builtin_return_address ( 0 );
+
+       DBG2 ( "EFI %s flush -> %p\n", block->name, retaddr );
+       return 0;
+}
+
+/** GUID used in vendor device path */
+#define EFIBLOCK_GUID {                                                        \
+       0x1322d197, 0x15dc, 0x4a45,                                     \
+       { 0xa6, 0xa4, 0xfa, 0x57, 0x05, 0x4e, 0xa6, 0x14 }              \
+       }
+
+/**
+ * Initialise vendor device path
+ *
+ * @v name             Variable name
+ */
+#define EFIBLOCK_DEVPATH_VENDOR_INIT( name ) {                         \
+       .Header = EFI_DEVPATH_INIT ( name, HARDWARE_DEVICE_PATH,        \
+                                    HW_VENDOR_DP ),                    \
+       .Guid = EFIBLOCK_GUID,                                          \
+       }
+
+/**
+ * Initialise ATA device path
+ *
+ * @v name             Variable name
+ */
+#define EFIBLOCK_DEVPATH_ATA_INIT( name ) {                            \
+       .Header = EFI_DEVPATH_INIT ( name, MESSAGING_DEVICE_PATH,       \
+                                    MSG_ATAPI_DP ),                    \
+       .PrimarySecondary = 0,                                          \
+       .SlaveMaster = 0,                                               \
+       .Lun = 0,                                                       \
+       }
+
+/**
+ * Initialise hard disk device path
+ *
+ * @v name             Variable name
+ */
+#define EFIBLOCK_DEVPATH_HD_INIT( name ) {                             \
+       .Header = EFI_DEVPATH_INIT ( name, MEDIA_DEVICE_PATH,           \
+                                    MEDIA_HARDDRIVE_DP ),              \
+       .PartitionNumber = 1,                                           \
+       .PartitionStart = VDISK_PARTITION_LBA,                          \
+       .PartitionSize = VDISK_PARTITION_COUNT,                         \
+       .Signature[0] = ( ( VDISK_MBR_SIGNATURE >> 0 ) & 0xff ),        \
+       .Signature[1] = ( ( VDISK_MBR_SIGNATURE >> 8 ) & 0xff ),        \
+       .Signature[2] = ( ( VDISK_MBR_SIGNATURE >> 16 ) & 0xff ),       \
+       .Signature[3] = ( ( VDISK_MBR_SIGNATURE >> 24 ) & 0xff ),       \
+       .MBRType = MBR_TYPE_PCAT,                                       \
+       .SignatureType = SIGNATURE_TYPE_MBR,                            \
+       }
+
+/** Virtual disk media */
+static EFI_BLOCK_IO_MEDIA efi_vdisk_media = {
+       .MediaId = VDISK_MBR_SIGNATURE,
+       .MediaPresent = TRUE,
+       .LogicalPartition = FALSE,
+       .ReadOnly = TRUE,
+       .BlockSize = VDISK_SECTOR_SIZE,
+       .LastBlock = ( VDISK_COUNT - 1 ),
+};
+
+/** Virtual disk device path */
+static struct {
+       VENDOR_DEVICE_PATH vendor;
+       ATAPI_DEVICE_PATH ata;
+       EFI_DEVICE_PATH_PROTOCOL end;
+} __attribute__ (( packed )) efi_vdisk_path = {
+       .vendor = EFIBLOCK_DEVPATH_VENDOR_INIT ( efi_vdisk_path.vendor ),
+       .ata = EFIBLOCK_DEVPATH_ATA_INIT ( efi_vdisk_path.ata ),
+       .end = EFI_DEVPATH_END_INIT ( efi_vdisk_path.end ),
+};
+
+/** Virtual disk device */
+static struct efi_block efi_vdisk = {
+       .block = {
+               .Revision = EFI_BLOCK_IO_PROTOCOL_REVISION,
+               .Media = &efi_vdisk_media,
+               .Reset = efi_reset_blocks,
+               .ReadBlocks = efi_read_blocks,
+               .WriteBlocks = efi_write_blocks,
+               .FlushBlocks = efi_flush_blocks,
+       },
+       .path = &efi_vdisk_path.vendor.Header,
+       .lba = 0,
+       .name = "vdisk",
+};
+
+/** Virtual partition media */
+static EFI_BLOCK_IO_MEDIA efi_vpartition_media = {
+       .MediaId = VDISK_MBR_SIGNATURE,
+       .MediaPresent = TRUE,
+       .LogicalPartition = TRUE,
+       .ReadOnly = TRUE,
+       .BlockSize = VDISK_SECTOR_SIZE,
+       .LastBlock = ( VDISK_PARTITION_COUNT - 1 ),
+};
+
+/** Virtual partition device path */
+static struct {
+       VENDOR_DEVICE_PATH vendor;
+       ATAPI_DEVICE_PATH ata;
+       HARDDRIVE_DEVICE_PATH hd;
+       EFI_DEVICE_PATH_PROTOCOL end;
+} __attribute__ (( packed )) efi_vpartition_path = {
+       .vendor = EFIBLOCK_DEVPATH_VENDOR_INIT ( efi_vpartition_path.vendor ),
+       .ata = EFIBLOCK_DEVPATH_ATA_INIT ( efi_vpartition_path.ata ),
+       .hd = EFIBLOCK_DEVPATH_HD_INIT ( efi_vpartition_path.hd ),
+       .end = EFI_DEVPATH_END_INIT ( efi_vpartition_path.end ),
+};
+
+/** Virtual partition device */
+static struct efi_block efi_vpartition = {
+       .block = {
+               .Revision = EFI_BLOCK_IO_PROTOCOL_REVISION,
+               .Media = &efi_vpartition_media,
+               .Reset = efi_reset_blocks,
+               .ReadBlocks = efi_read_blocks,
+               .WriteBlocks = efi_write_blocks,
+               .FlushBlocks = efi_flush_blocks,
+       },
+       .path = &efi_vpartition_path.vendor.Header,
+       .lba = VDISK_PARTITION_LBA,
+       .name = "vpartition",
+};
+
+/**
+ * Install block I/O protocols
+ *
+ * @ret vdisk          New virtual disk handle
+ * @ret vpartition     New virtual partition handle
+ */
+void efi_install ( EFI_HANDLE *vdisk, EFI_HANDLE *vpartition ) {
+       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
+       EFI_STATUS efirc;
+
+       /* Install virtual disk */
+       if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
+               vdisk,
+               &efi_block_io_protocol_guid, &efi_vdisk.block,
+               &efi_device_path_protocol_guid, efi_vdisk.path,
+               NULL ) ) != 0 ) {
+               die ( "Could not install disk block I/O protocols: %#lx\n",
+                     ( ( unsigned long ) efirc ) );
+       }
+
+       /* Install virtual partition */
+       if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
+               vpartition,
+               &efi_block_io_protocol_guid, &efi_vpartition.block,
+               &efi_device_path_protocol_guid, efi_vpartition.path,
+               NULL ) ) != 0 ) {
+               die ( "Could not install partition block I/O protocols: %#lx\n",
+                     ( ( unsigned long ) efirc ) );
+       }
+}
+
+/** Boot image path */
+static struct {
+       VENDOR_DEVICE_PATH vendor;
+       ATAPI_DEVICE_PATH ata;
+       HARDDRIVE_DEVICE_PATH hd;
+       struct {
+               EFI_DEVICE_PATH header;
+               CHAR16 name[ sizeof ( EFI_REMOVABLE_MEDIA_FILE_NAME ) /
+                            sizeof ( CHAR16 ) ];
+       } __attribute__ (( packed )) file;
+       EFI_DEVICE_PATH_PROTOCOL end;
+} __attribute__ (( packed )) efi_bootmgfw_path = {
+       .vendor = EFIBLOCK_DEVPATH_VENDOR_INIT ( efi_bootmgfw_path.vendor ),
+       .ata = EFIBLOCK_DEVPATH_ATA_INIT ( efi_bootmgfw_path.ata ),
+       .hd = EFIBLOCK_DEVPATH_HD_INIT ( efi_bootmgfw_path.hd ),
+       .file = {
+               .header = EFI_DEVPATH_INIT ( efi_bootmgfw_path.file,
+                                            MEDIA_DEVICE_PATH,
+                                            MEDIA_FILEPATH_DP ),
+               .name = EFI_REMOVABLE_MEDIA_FILE_NAME,
+       },
+       .end = EFI_DEVPATH_END_INIT ( efi_bootmgfw_path.end ),
+};
+
+/** Boot image path */
+EFI_DEVICE_PATH_PROTOCOL *bootmgfw_path = &efi_bootmgfw_path.vendor.Header;
diff --git a/wimboot/wimboot-2.7.3/src/efiblock.h b/wimboot/wimboot-2.7.3/src/efiblock.h
new file mode 100644 (file)
index 0000000..cd34fbb
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _EFIBLOCK_H
+#define _EFIBLOCK_H
+
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * EFI block device
+ *
+ */
+
+#include "efi.h"
+#include "efi/Protocol/BlockIo.h"
+#include "efi/Protocol/DevicePath.h"
+
+extern void efi_install ( EFI_HANDLE *vdisk, EFI_HANDLE *vpartition );
+
+extern EFI_DEVICE_PATH_PROTOCOL *bootmgfw_path;
+
+#endif /* _EFIBLOCK_H */
diff --git a/wimboot/wimboot-2.7.3/src/efiboot.c b/wimboot/wimboot-2.7.3/src/efiboot.c
new file mode 100644 (file)
index 0000000..5c800e9
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * EFI boot manager invocation
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "wimboot.h"
+#include "cmdline.h"
+#include "vdisk.h"
+#include "pause.h"
+#include "efi.h"
+#include "efi/Protocol/GraphicsOutput.h"
+#include "efipath.h"
+#include "efiboot.h"
+
+/** Original OpenProtocol() method */
+static EFI_OPEN_PROTOCOL orig_open_protocol;
+
+/**
+ * Intercept OpenProtocol()
+ *
+ * @v handle           EFI handle
+ * @v protocol         Protocol GUID
+ * @v interface                Opened interface
+ * @v agent_handle     Agent handle
+ * @v controller_handle        Controller handle
+ * @v attributes       Attributes
+ * @ret efirc          EFI status code
+ */
+static EFI_STATUS EFIAPI
+efi_open_protocol_wrapper ( EFI_HANDLE handle, EFI_GUID *protocol,
+                           VOID **interface, EFI_HANDLE agent_handle,
+                           EFI_HANDLE controller_handle, UINT32 attributes ) {
+       static unsigned int count;
+       EFI_STATUS efirc;
+
+       /* Open the protocol */
+       if ( ( efirc = orig_open_protocol ( handle, protocol, interface,
+                                           agent_handle, controller_handle,
+                                           attributes ) ) != 0 ) {
+               return efirc;
+       }
+
+       /* Block first attempt by bootmgfw.efi to open
+        * EFI_GRAPHICS_OUTPUT_PROTOCOL.  This forces error messages
+        * to be displayed in text mode (thereby avoiding the totally
+        * blank error screen if the fonts are missing).  We must
+        * allow subsequent attempts to succeed, otherwise the OS will
+        * fail to boot.
+        */
+       if ( ( memcmp ( protocol, &efi_graphics_output_protocol_guid,
+                       sizeof ( *protocol ) ) == 0 ) &&
+            ( count++ == 0 ) && ( ! cmdline_gui ) ) {
+               DBG ( "Forcing text mode output\n" );
+               return EFI_INVALID_PARAMETER;
+       }
+
+       return 0;
+}
+
+/**
+ * Boot from EFI device
+ *
+ * @v file             Virtual file
+ * @v path             Device path
+ * @v device           Device handle
+ */
+void efi_boot ( struct vdisk_file *file, EFI_DEVICE_PATH_PROTOCOL *path,
+               EFI_HANDLE device ) {
+       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
+       union {
+               EFI_LOADED_IMAGE_PROTOCOL *image;
+               void *intf;
+       } loaded;
+       EFI_PHYSICAL_ADDRESS phys;
+       void *data;
+       unsigned int pages;
+       EFI_HANDLE handle;
+       EFI_STATUS efirc;
+
+       /* Allocate memory */
+       pages = ( ( file->len + PAGE_SIZE - 1 ) / PAGE_SIZE );
+       if ( ( efirc = bs->AllocatePages ( AllocateAnyPages,
+                                          EfiBootServicesData, pages,
+                                          &phys ) ) != 0 ) {
+               die ( "Could not allocate %d pages: %#lx\n",
+                     pages, ( ( unsigned long ) efirc ) );
+       }
+       data = ( ( void * ) ( intptr_t ) phys );
+
+
+       /* Read image */
+       file->read ( file, data, 0, file->len );
+       DBG ( "Read %s\n", file->name );
+
+       /* Load image */
+       if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, path, data,
+                                      file->len, &handle ) ) != 0 ) {
+               die ( "Could not load %s: %#lx\n",
+                     file->name, ( ( unsigned long ) efirc ) );
+       }
+       DBG ( "Loaded %s\n", file->name );
+
+       /* Get loaded image protocol */
+       if ( ( efirc = bs->OpenProtocol ( handle,
+                                         &efi_loaded_image_protocol_guid,
+                                         &loaded.intf, efi_image_handle, NULL,
+                                         EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
+               die ( "Could not get loaded image protocol for %s: %#lx\n",
+                     file->name, ( ( unsigned long ) efirc ) );
+       }
+
+       /* Force correct device handle */
+       if ( loaded.image->DeviceHandle != device ) {
+               DBG ( "Forcing correct DeviceHandle (%p->%p)\n",
+                     loaded.image->DeviceHandle, device );
+               loaded.image->DeviceHandle = device;
+       }
+
+       /* Intercept calls to OpenProtocol() */
+       orig_open_protocol =
+               loaded.image->SystemTable->BootServices->OpenProtocol;
+       loaded.image->SystemTable->BootServices->OpenProtocol =
+               efi_open_protocol_wrapper;
+
+       /* Start image */
+       if ( cmdline_pause )
+               pause();
+       if ( ( efirc = bs->StartImage ( handle, NULL, NULL ) ) != 0 ) {
+               die ( "Could not start %s: %#lx\n",
+                     file->name, ( ( unsigned long ) efirc ) );
+       }
+
+       die ( "%s returned\n", file->name );
+}
diff --git a/wimboot/wimboot-2.7.3/src/efiboot.h b/wimboot/wimboot-2.7.3/src/efiboot.h
new file mode 100644 (file)
index 0000000..6671ef1
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _EFIBOOT_H
+#define _EFIBOOT_H
+
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * EFI boot manager invocation
+ *
+ */
+
+#include "efi.h"
+#include "efi/Protocol/DevicePath.h"
+
+struct vdisk_file;
+
+extern void efi_boot ( struct vdisk_file *file, EFI_DEVICE_PATH_PROTOCOL *path,
+                      EFI_HANDLE device );
+
+#endif /* _EFIBOOT_H */
diff --git a/wimboot/wimboot-2.7.3/src/efifile.c b/wimboot/wimboot-2.7.3/src/efifile.c
new file mode 100644 (file)
index 0000000..9335387
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * EFI file system access
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <wchar.h>
+#include "wimboot.h"
+#include "vdisk.h"
+#include "cmdline.h"
+#include "wimpatch.h"
+#include "wimfile.h"
+#include "efi.h"
+#include "efifile.h"
+
+/** bootmgfw.efi path within WIM */
+static const wchar_t bootmgfw_path[] = L"\\Windows\\Boot\\EFI\\bootmgfw.efi";
+
+/** Other paths within WIM */
+static const wchar_t *efi_wim_paths[] = {
+       L"\\Windows\\Boot\\DVD\\EFI\\boot.sdi",
+       L"\\Windows\\Boot\\DVD\\EFI\\BCD",
+       L"\\Windows\\Boot\\Fonts\\segmono_boot.ttf",
+       L"\\Windows\\Boot\\Fonts\\segoen_slboot.ttf",
+       L"\\Windows\\Boot\\Fonts\\segoe_slboot.ttf",
+       L"\\Windows\\Boot\\Fonts\\wgl4_boot.ttf",
+       L"\\sms\\boot\\boot.sdi",
+       NULL
+};
+
+/** bootmgfw.efi file */
+struct vdisk_file *bootmgfw;
+
+/**
+ * Get architecture-specific boot filename
+ *
+ * @ret bootarch       Architecture-specific boot filename
+ */
+static const CHAR16 * efi_bootarch ( void ) {
+       static const CHAR16 bootarch_full[] = EFI_REMOVABLE_MEDIA_FILE_NAME;
+       const CHAR16 *tmp;
+       const CHAR16 *bootarch = bootarch_full;
+
+       for ( tmp = bootarch_full ; *tmp ; tmp++ ) {
+               if ( *tmp == L'\\' )
+                       bootarch = ( tmp + 1 );
+       }
+       return bootarch;
+}
+
+/**
+ * Read from EFI file
+ *
+ * @v vfile            Virtual file
+ * @v data             Data buffer
+ * @v offset           Offset
+ * @v len              Length
+ */
+static void efi_read_file ( struct vdisk_file *vfile, void *data,
+                           size_t offset, size_t len ) {
+#if 0
+       EFI_FILE_PROTOCOL *file = vfile->opaque;
+       UINTN size = len;
+       EFI_STATUS efirc;
+
+       /* Set file position */
+       if ( ( efirc = file->SetPosition ( file, offset ) ) != 0 ) {
+               die ( "Could not set file position: %#lx\n",
+                     ( ( unsigned long ) efirc ) );
+       }
+
+       /* Read from file */
+       if ( ( efirc = file->Read ( file, &size, data ) ) != 0 ) {
+               die ( "Could not read from file: %#lx\n",
+                     ( ( unsigned long ) efirc ) );
+       }
+#endif /* #if 0 */
+
+    (void)vfile;
+
+    pfventoy_file_read((const char *)vfile->opaque, (int)offset, (int)len, data);
+}
+
+/**
+ * Patch BCD file
+ *
+ * @v vfile            Virtual file
+ * @v data             Data buffer
+ * @v offset           Offset
+ * @v len              Length
+ */
+static void efi_patch_bcd ( struct vdisk_file *vfile __unused, void *data,
+                           size_t offset, size_t len ) {
+       static const wchar_t search[] = L".exe";
+       static const wchar_t replace[] = L".efi";
+       size_t i;
+
+       /* Do nothing if BCD patching is disabled */
+       if ( cmdline_rawbcd )
+               return;
+
+       /* Patch any occurrences of ".exe" to ".efi".  In the common
+        * simple cases, this allows the same BCD file to be used for
+        * both BIOS and UEFI systems.
+        */
+       for ( i = 0 ; ( i + sizeof ( search ) ) < len ; i++ ) {
+               if ( wcscasecmp ( ( data + i ), search ) == 0 ) {
+                       memcpy ( ( data + i ), replace, sizeof ( replace ) );
+                       DBG ( "...patched BCD at %#zx: \"%ls\" to \"%ls\"\n",
+                             ( offset + i ), search, replace );
+               }
+       }
+}
+
+/**
+ * Extract files from EFI file system
+ *
+ * @v handle           Device handle
+ */
+void efi_extract ( EFI_HANDLE handle ) {
+       struct vdisk_file *wim = NULL;
+       struct vdisk_file *vfile;
+       CHAR16 wname[64];
+    int i, j, k;
+    char *pos;
+    size_t len = 0;
+
+    (void)handle;
+
+       /* Read root directory */
+    for (i = 0; i < cmdline_vf_num; i++) {
+        pos = strchr(cmdline_vf_path[i], ':');
+
+        *pos = 0;
+        k = (int)strlen(cmdline_vf_path[i]);
+    
+        memset(wname, 0, sizeof(wname));
+        for (j = 0; j < k; j++)
+        {
+            wname[j] = cmdline_vf_path[i][j];
+        }
+
+        len = pfventoy_file_size(pos + 1);
+               vfile = vdisk_add_file (cmdline_vf_path[i], pos + 1, len, efi_read_file);
+
+               /* Check for special-case files */
+               if ( ( wcscasecmp ( wname, efi_bootarch() ) == 0 ) ||
+                    ( wcscasecmp ( wname, L"bootmgfw.efi" ) == 0 ) ) {
+                       DBG ( "...found bootmgfw.efi file %ls\n", wname );
+                       bootmgfw = vfile;
+               } else if ( wcscasecmp ( wname, L"BCD" ) == 0 ) {
+                       DBG ( "...found BCD\n" );
+                       vdisk_patch_file ( vfile, efi_patch_bcd );
+               } else if ( wcscasecmp ( ( wname + ( wcslen ( wname ) - 4 ) ),
+                                        L".wim" ) == 0 ) {
+                       DBG ( "...found WIM file %ls\n", wname );
+                       wim = vfile;
+               }
+       }
+
+       /* Process WIM image */
+       if ( wim ) {
+               vdisk_patch_file ( wim, patch_wim );
+               if ( ( ! bootmgfw ) &&
+                    ( bootmgfw = wim_add_file ( wim, cmdline_index,
+                                                bootmgfw_path,
+                                                efi_bootarch() ) ) ) {
+                       DBG ( "...extracted %ls\n", bootmgfw_path );
+               }
+               wim_add_files ( wim, cmdline_index, efi_wim_paths );
+       }
+
+       /* Check that we have a boot file */
+       if ( ! bootmgfw ) {
+               die ( "FATAL: no %ls or bootmgfw.efi found\n",
+                     efi_bootarch() );
+       }
+}
diff --git a/wimboot/wimboot-2.7.3/src/efifile.h b/wimboot/wimboot-2.7.3/src/efifile.h
new file mode 100644 (file)
index 0000000..885ea5c
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _EFIFILE_H
+#define _EFIFILE_H
+
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * EFI file system access
+ *
+ */
+
+#include "efi.h"
+#include "efi/Protocol/SimpleFileSystem.h"
+#include "efi/Guid/FileInfo.h"
+
+struct vdisk_file;
+
+extern struct vdisk_file *bootmgfw;
+extern void efi_extract ( EFI_HANDLE handle );
+
+#endif /* _EFIFILE_H */
diff --git a/wimboot/wimboot-2.7.3/src/efiguid.c b/wimboot/wimboot-2.7.3/src/efiguid.c
new file mode 100644 (file)
index 0000000..00313fa
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * EFI GUIDs
+ *
+ */
+
+#include "wimboot.h"
+#include "efi.h"
+#include "efi/Protocol/BlockIo.h"
+#include "efi/Protocol/DevicePath.h"
+#include "efi/Protocol/GraphicsOutput.h"
+#include "efi/Protocol/LoadedImage.h"
+#include "efi/Protocol/SimpleFileSystem.h"
+
+/** Block I/O protocol GUID */
+EFI_GUID efi_block_io_protocol_guid
+       = EFI_BLOCK_IO_PROTOCOL_GUID;
+
+/** Device path protocol GUID */
+EFI_GUID efi_device_path_protocol_guid
+       = EFI_DEVICE_PATH_PROTOCOL_GUID;
+
+/** Graphics output protocol GUID */
+EFI_GUID efi_graphics_output_protocol_guid
+       = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+
+/** Loaded image protocol GUID */
+EFI_GUID efi_loaded_image_protocol_guid
+       = EFI_LOADED_IMAGE_PROTOCOL_GUID;
+
+/** Simple file system protocol GUID */
+EFI_GUID efi_simple_file_system_protocol_guid
+       = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
diff --git a/wimboot/wimboot-2.7.3/src/efimain.c b/wimboot/wimboot-2.7.3/src/efimain.c
new file mode 100644 (file)
index 0000000..0faa217
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * EFI entry point
+ *
+ */
+
+#include <stdio.h>
+#include "wimboot.h"
+#include "cmdline.h"
+#include "efi.h"
+#include "efifile.h"
+#include "efiblock.h"
+#include "efiboot.h"
+
+/**
+ * Process command line
+ *
+ * @v loaded           Loaded image protocol
+ */
+static void efi_cmdline ( EFI_LOADED_IMAGE_PROTOCOL *loaded ) {
+       size_t cmdline_len = ( loaded->LoadOptionsSize / sizeof ( wchar_t ) );
+       char cmdline[ cmdline_len + 1 /* NUL */ ];
+       const wchar_t *wcmdline = loaded->LoadOptions;
+
+       /* Convert command line to ASCII */
+       snprintf ( cmdline, sizeof ( cmdline ), "%ls", wcmdline );
+
+       /* Process command line */
+       process_cmdline ( cmdline );
+}
+
+/**
+ * EFI entry point
+ *
+ * @v image_handle     Image handle
+ * @v systab           EFI system table
+ * @ret efirc          EFI status code
+ */
+EFI_STATUS EFIAPI efi_main ( EFI_HANDLE image_handle,
+                            EFI_SYSTEM_TABLE *systab ) {
+       EFI_BOOT_SERVICES *bs;
+       union {
+               EFI_LOADED_IMAGE_PROTOCOL *image;
+               void *interface;
+       } loaded;
+       EFI_HANDLE vdisk = NULL;
+       EFI_HANDLE vpartition = NULL;
+       EFI_STATUS efirc;
+
+       /* Record EFI handle and system table */
+       efi_image_handle = image_handle;
+       efi_systab = systab;
+       bs = systab->BootServices;
+
+       /* Initialise stack cookie */
+       init_cookie();
+
+       /* Print welcome banner */
+    printf ( "\n\nBooting wim file...... (This may take a few minutes, please wait)\n\n");
+//     printf ( "\n\nwimboot " VERSION " -- Windows Imaging Format "
+//              "bootloader -- https://ipxe.org/wimboot\n\n" );
+
+       /* Get loaded image protocol */
+       if ( ( efirc = bs->OpenProtocol ( image_handle,
+                                         &efi_loaded_image_protocol_guid,
+                                         &loaded.interface, image_handle, NULL,
+                                         EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
+               die ( "Could not open loaded image protocol: %#lx\n",
+                     ( ( unsigned long ) efirc ) );
+       }
+
+       /* Process command line */
+       efi_cmdline ( loaded.image );
+
+       /* Extract files from file system */
+       efi_extract ( loaded.image->DeviceHandle );
+
+       /* Install virtual disk */
+       efi_install ( &vdisk, &vpartition );
+
+       /* Invoke boot manager */
+       efi_boot ( bootmgfw, bootmgfw_path, vpartition );
+
+       return 0;
+}
diff --git a/wimboot/wimboot-2.7.3/src/efipath.c b/wimboot/wimboot-2.7.3/src/efipath.c
new file mode 100644 (file)
index 0000000..b4f1c5c
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * EFI device paths
+ *
+ */
+
+#include "wimboot.h"
+#include "efi.h"
+#include "efipath.h"
+
+/**
+ * Find end of device path
+ *
+ * @v path             Path to device
+ * @ret path_end       End of device path
+ */
+EFI_DEVICE_PATH_PROTOCOL * efi_devpath_end ( EFI_DEVICE_PATH_PROTOCOL *path ) {
+
+       while ( path->Type != END_DEVICE_PATH_TYPE ) {
+               path = ( ( ( void * ) path ) +
+                        /* There's this amazing new-fangled thing known as
+                         * a UINT16, but who wants to use one of those? */
+                        ( ( path->Length[1] << 8 ) | path->Length[0] ) );
+       }
+       return path;
+}
diff --git a/wimboot/wimboot-2.7.3/src/efipath.h b/wimboot/wimboot-2.7.3/src/efipath.h
new file mode 100644 (file)
index 0000000..ec7e8c3
--- /dev/null
@@ -0,0 +1,89 @@
+#ifndef _EFIPATH_H
+#define _EFIPATH_H
+
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * EFI device paths
+ *
+ */
+
+#include "efi.h"
+#include "efi/Protocol/DevicePath.h"
+
+/**
+ * Initialise device path
+ *
+ * @v name             Variable name
+ * @v type             Type
+ * @v subtype          Subtype
+ */
+#define EFI_DEVPATH_INIT( name, type, subtype ) {              \
+       .Type = (type),                                         \
+       .SubType = (subtype),                                   \
+       .Length[0] = ( sizeof (name) & 0xff ),                  \
+       .Length[1] = ( sizeof (name) >> 8 ),                    \
+       }
+
+/**
+ * Initialise device path
+ *
+ * @v path             Device path
+ * @v type             Type
+ * @v subtype          Subtype
+ * @v len              Length
+ */
+static inline __attribute__ (( always_inline )) void
+efi_devpath_init ( EFI_DEVICE_PATH_PROTOCOL *path, unsigned int type,
+                  unsigned int subtype, size_t len ) {
+
+       path->Type = type;
+       path->SubType = subtype;
+       path->Length[0] = ( len & 0xff );
+       path->Length[1] = ( len >> 8 );
+}
+
+/**
+ * Initialise device path end
+ *
+ * @v name             Variable name
+ */
+#define EFI_DEVPATH_END_INIT( name )                           \
+       EFI_DEVPATH_INIT ( name, END_DEVICE_PATH_TYPE,          \
+                          END_ENTIRE_DEVICE_PATH_SUBTYPE )
+
+/**
+ * Initialise device path end
+ *
+ * @v path             Device path
+ */
+static inline __attribute__ (( always_inline )) void
+efi_devpath_end_init ( EFI_DEVICE_PATH_PROTOCOL *path ) {
+
+       efi_devpath_init ( path, END_DEVICE_PATH_TYPE,
+                          END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof ( *path ) );
+}
+
+extern EFI_DEVICE_PATH_PROTOCOL *
+efi_devpath_end ( EFI_DEVICE_PATH_PROTOCOL *path );
+
+#endif /* _EFIPATH_H */
diff --git a/wimboot/wimboot-2.7.3/src/efireloc.c b/wimboot/wimboot-2.7.3/src/efireloc.c
new file mode 100644 (file)
index 0000000..4972b15
--- /dev/null
@@ -0,0 +1,556 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * EFI relocations
+ *
+ * Derived from iPXE's elf2efi.c
+ *
+ */
+
+#define PACKAGE "wimboot"
+#define PACKAGE_VERSION VERSION
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <bfd.h>
+#include "efi.h"
+#include "efi/IndustryStandard/PeImage.h"
+#include "wimboot.h"
+
+#define eprintf(...) fprintf ( stderr, __VA_ARGS__ )
+
+/* Maintain compatibility with binutils 2.34 */
+#ifndef bfd_get_section_vma
+#define bfd_get_section_vma(bfd, ptr) bfd_section_vma(ptr)
+#endif
+#ifndef bfd_get_section_flags
+#define bfd_get_section_flags(bfd, ptr) bfd_section_flags(ptr)
+#endif
+
+/** PE header maximum length
+ *
+ * This maximum length is guaranteed by the fact that the PE headers
+ * have to fit entirely before the start of the bzImage header.
+ */
+#define PE_HEADER_LEN 512
+
+/** .reloc section index */
+#define RELOC_SECTION_INDEX 3
+
+/** PE relocations */
+struct pe_relocs {
+       struct pe_relocs *next;
+       unsigned long start_rva;
+       unsigned int used_relocs;
+       unsigned int total_relocs;
+       uint16_t *relocs;
+};
+
+/** Command-line options */
+struct options {
+       /** Verbosity */
+       int verbosity;
+};
+
+/**
+ * Allocate memory
+ *
+ * @v len              Length of memory to allocate
+ * @ret ptr            Pointer to allocated memory
+ */
+static void * xmalloc ( size_t len ) {
+       void *ptr;
+
+       ptr = malloc ( len );
+       if ( ! ptr ) {
+               eprintf ( "Could not allocate %zd bytes\n", len );
+               exit ( 1 );
+       }
+
+       return ptr;
+}
+
+/**
+ * Write to file
+ *
+ * @v fd               File descriptor
+ * @v data             Data
+ * @v len              Length of data
+ */
+static void xwrite ( int fd, const void *data, size_t len ) {
+       ssize_t written;
+
+       written = write ( fd, data, len );
+       if ( written < 0 ) {
+               eprintf ( "Could not write %zd bytes: %s\n",
+                         len, strerror ( errno ) );
+               exit ( 1 );
+       }
+       if ( ( size_t ) written != len ) {
+               eprintf ( "Wrote only %zd of %zd bytes\n", written, len );
+               exit ( 1 );
+       }
+}
+
+/**
+ * Seek to file position
+ *
+ * @v fd               File descriptor
+ * @v offset           Offset
+ * @v whence           Origin
+ */
+static void xlseek ( int fd, off_t offset, int whence ) {
+       off_t pos;
+
+       pos = lseek ( fd, offset, whence );
+       if ( pos < 0 ) {
+               eprintf ( "Could not seek: %s\n", strerror ( errno ) );
+               exit ( 1 );
+       }
+}
+
+/**
+ * Close file
+ *
+ * @v fd               File descriptor
+ */
+static void xclose ( int fd ) {
+
+       if ( close ( fd ) < 0 ) {
+               eprintf ( "Could not close: %s\n", strerror ( errno ) );
+               exit ( 1 );
+       }
+}
+
+/**
+ * Open input BFD file
+ *
+ * @v filename         File name
+ * @ret ibfd           BFD file
+ */
+static bfd * open_input_bfd ( const char *filename ) {
+       bfd *bfd;
+
+       /* Open the file */
+       bfd = bfd_openr ( filename, NULL );
+       if ( ! bfd ) {
+               eprintf ( "Cannot open %s: ", filename );
+               bfd_perror ( NULL );
+               exit ( 1 );
+       }
+
+       /* The call to bfd_check_format() must be present, otherwise
+        * we get a segfault from later BFD calls.
+        */
+       if ( ! bfd_check_format ( bfd, bfd_object ) ) {
+               eprintf ( "%s is not an object file: ", filename );
+               bfd_perror ( NULL );
+               exit ( 1 );
+       }
+
+       return bfd;
+}
+
+/**
+ * Read symbol table
+ *
+ * @v bfd              BFD file
+ */
+static asymbol ** read_symtab ( bfd *bfd ) {
+       long symtab_size;
+       asymbol **symtab;
+       long symcount;
+
+       /* Get symbol table size */
+       symtab_size = bfd_get_symtab_upper_bound ( bfd );
+       if ( symtab_size < 0 ) {
+               bfd_perror ( "Could not get symbol table upper bound" );
+               exit ( 1 );
+       }
+
+       /* Allocate and read symbol table */
+       symtab = xmalloc ( symtab_size );
+       symcount = bfd_canonicalize_symtab ( bfd, symtab );
+       if ( symcount < 0 ) {
+               bfd_perror ( "Cannot read symbol table" );
+               exit ( 1 );
+       }
+
+       return symtab;
+}
+
+/**
+ * Read relocation table
+ *
+ * @v bfd              BFD file
+ * @v symtab           Symbol table
+ * @v section          Section
+ * @v symtab           Symbol table
+ * @ret reltab         Relocation table
+ */
+static arelent ** read_reltab ( bfd *bfd, asymbol **symtab,
+                               asection *section ) {
+       long reltab_size;
+       arelent **reltab;
+       long numrels;
+
+       /* Get relocation table size */
+       reltab_size = bfd_get_reloc_upper_bound ( bfd, section );
+       if ( reltab_size < 0 ) {
+               bfd_perror ( "Could not get relocation table upper bound" );
+               exit ( 1 );
+       }
+
+       /* Allocate and read relocation table */
+       reltab = xmalloc ( reltab_size );
+       numrels = bfd_canonicalize_reloc ( bfd, section, reltab, symtab );
+       if ( numrels < 0 ) {
+               bfd_perror ( "Cannot read relocation table" );
+               exit ( 1 );
+       }
+
+       return reltab;
+}
+
+/**
+ * Generate entry in PE relocation table
+ *
+ * @v pe_reltab                PE relocation table
+ * @v rva              RVA
+ * @v size             Size of relocation entry
+ */
+static void generate_pe_reloc ( struct pe_relocs **pe_reltab,
+                               unsigned long rva, size_t size ) {
+       unsigned long start_rva;
+       uint16_t reloc;
+       struct pe_relocs *pe_rel;
+       uint16_t *relocs;
+
+       /* Construct */
+       start_rva = ( rva & ~0xfff );
+       reloc = ( rva & 0xfff );
+       switch ( size ) {
+       case 8:
+               reloc |= 0xa000;
+               break;
+       case 4:
+               reloc |= 0x3000;
+               break;
+       case 2:
+               reloc |= 0x2000;
+               break;
+       default:
+               eprintf ( "Unsupported relocation size %zd\n", size );
+               exit ( 1 );
+       }
+
+       /* Locate or create PE relocation table */
+       for ( pe_rel = *pe_reltab ; pe_rel ; pe_rel = pe_rel->next ) {
+               if ( pe_rel->start_rva == start_rva )
+                       break;
+       }
+       if ( ! pe_rel ) {
+               pe_rel = xmalloc ( sizeof ( *pe_rel ) );
+               memset ( pe_rel, 0, sizeof ( *pe_rel ) );
+               pe_rel->next = *pe_reltab;
+               *pe_reltab = pe_rel;
+               pe_rel->start_rva = start_rva;
+       }
+
+       /* Expand relocation list if necessary */
+       if ( pe_rel->used_relocs < pe_rel->total_relocs ) {
+               relocs = pe_rel->relocs;
+       } else {
+               pe_rel->total_relocs = ( pe_rel->total_relocs ?
+                                        ( pe_rel->total_relocs * 2 ) : 256 );
+               relocs = xmalloc ( pe_rel->total_relocs *
+                                  sizeof ( pe_rel->relocs[0] ) );
+               memset ( relocs, 0,
+                        pe_rel->total_relocs * sizeof ( pe_rel->relocs[0] ) );
+               memcpy ( relocs, pe_rel->relocs,
+                        pe_rel->used_relocs * sizeof ( pe_rel->relocs[0] ) );
+               free ( pe_rel->relocs );
+               pe_rel->relocs = relocs;
+       }
+
+       /* Store relocation */
+       pe_rel->relocs[ pe_rel->used_relocs++ ] = reloc;
+}
+
+/**
+ * Process relocation record
+ *
+ * @v bfd              BFD file
+ * @v section          Section
+ * @v rel              Relocation entry
+ * @v pe_reltab                PE relocation table to fill in
+ */
+static void process_reloc ( bfd *bfd __unused, asection *section, arelent *rel,
+                           struct pe_relocs **pe_reltab ) {
+       reloc_howto_type *howto = rel->howto;
+       asymbol *sym = *(rel->sym_ptr_ptr);
+       unsigned long offset = ( bfd_get_section_vma ( bfd, section ) +
+                                rel->address - BASE_ADDRESS );
+
+       if ( bfd_is_abs_section ( sym->section ) ) {
+               /* Skip absolute symbols; the symbol value won't
+                * change when the object is loaded.
+                */
+       } else if ( strcmp ( howto->name, "R_X86_64_64" ) == 0 ) {
+               /* Generate an 8-byte PE relocation */
+               generate_pe_reloc ( pe_reltab, offset, 8 );
+       } else if ( ( strcmp ( howto->name, "R_386_32" ) == 0 ) ||
+                   ( strcmp ( howto->name, "R_X86_64_32" ) == 0 ) ||
+                   ( strcmp ( howto->name, "R_X86_64_32S" ) == 0 ) ) {
+               /* Generate a 4-byte PE relocation */
+               generate_pe_reloc ( pe_reltab, offset, 4 );
+       } else if ( ( strcmp ( howto->name, "R_386_16" ) == 0 ) ||
+                   ( strcmp ( howto->name, "R_X86_64_16" ) == 0 ) ) {
+               /* Generate a 2-byte PE relocation */
+               generate_pe_reloc ( pe_reltab, offset, 2 );
+       } else if ( ( strcmp ( howto->name, "R_386_PC32" ) == 0 ) ||
+                   ( strcmp ( howto->name, "R_X86_64_PC32" ) == 0 ) ||
+                   ( strcmp ( howto->name, "R_X86_64_PLT32" ) == 0 ) ) {
+               /* Skip PC-relative relocations; all relative offsets
+                * remain unaltered when the object is loaded.
+                */
+       } else {
+               eprintf ( "Unrecognised relocation type %s\n", howto->name );
+               exit ( 1 );
+       }
+}
+
+/**
+ * Calculate size of binary PE relocation table
+ *
+ * @v fh               File handle
+ * @v pe_reltab                PE relocation table
+ * @ret size           Size of binary table
+ */
+static size_t output_pe_reltab ( int fd, struct pe_relocs *pe_reltab ) {
+       EFI_IMAGE_BASE_RELOCATION header;
+       struct pe_relocs *pe_rel;
+       static uint8_t pad[16];
+       unsigned int num_relocs;
+       size_t size;
+       size_t pad_size;
+       size_t total_size = 0;
+
+       for ( pe_rel = pe_reltab ; pe_rel ; pe_rel = pe_rel->next ) {
+               num_relocs = ( ( pe_rel->used_relocs + 1 ) & ~1 );
+               size = ( sizeof ( header ) +
+                        ( num_relocs * sizeof ( uint16_t ) ) );
+               pad_size = ( ( -size ) & ( sizeof ( pad ) - 1 ) );
+               size += pad_size;
+               header.VirtualAddress = pe_rel->start_rva;
+               header.SizeOfBlock = size;
+               xwrite ( fd, &header, sizeof ( header ) );
+               xwrite ( fd, pe_rel->relocs,
+                        ( num_relocs * sizeof ( uint16_t ) ) );
+               xwrite ( fd, pad, pad_size );
+               total_size += size;
+       }
+
+       return total_size;
+}
+
+/**
+ * Add relocation information
+ *
+ * @v elf_name         ELF file name
+ * @v pe_name          PE file name
+ */
+static void efireloc ( const char *elf_name, const char *pe_name ) {
+       struct pe_relocs *pe_reltab = NULL;
+       int fd;
+       EFI_IMAGE_DOS_HEADER *dos;
+       EFI_IMAGE_OPTIONAL_HEADER_UNION *nt;
+       EFI_IMAGE_DATA_DIRECTORY *data_dir;
+       EFI_IMAGE_SECTION_HEADER *pe_sections;
+       UINT32 *image_size;
+       bfd *bfd;
+       asymbol **symtab;
+       asection *section;
+       arelent **reltab;
+       arelent **rel;
+       size_t reloc_len;
+
+       /* Open the output file */
+       fd = open ( pe_name, O_RDWR );
+       if ( fd < 0 ) {
+               eprintf ( "Could not open %s: %s\n",
+                         pe_name, strerror ( errno ) );
+               exit ( 1 );
+       }
+
+       /* Map the output file header */
+       dos = mmap ( NULL, PE_HEADER_LEN, ( PROT_READ | PROT_WRITE ),
+                    MAP_SHARED, fd, 0 );
+       if ( ! dos ) {
+               eprintf ( "Could not mmap %s: %s\n",
+                         pe_name, strerror ( errno ) );
+               exit ( 1 );
+       }
+
+       /* Locate the modifiable fields within the output file header */
+       nt = ( ( ( void * ) dos ) + dos->e_lfanew );
+       if ( nt->Pe32.FileHeader.Machine == EFI_IMAGE_MACHINE_IA32 ) {
+               image_size = &nt->Pe32.OptionalHeader.SizeOfImage;
+               data_dir = nt->Pe32.OptionalHeader.DataDirectory;
+               pe_sections = ( ( ( void * ) nt ) + sizeof ( nt->Pe32 ) );
+       } else if ( nt->Pe32Plus.FileHeader.Machine == EFI_IMAGE_MACHINE_X64 ) {
+               image_size = &nt->Pe32Plus.OptionalHeader.SizeOfImage;
+               data_dir = nt->Pe32Plus.OptionalHeader.DataDirectory;
+               pe_sections = ( ( ( void * ) nt ) + sizeof ( nt->Pe32Plus ) );
+       } else {
+               eprintf ( "Unrecognised machine type\n" );
+               exit ( 1 );
+       }
+
+       /* Open the input file */
+       bfd = open_input_bfd ( elf_name );
+       symtab = read_symtab ( bfd );
+
+       /* For each input section, create the appropriate relocation records */
+       for ( section = bfd->sections ; section ; section = section->next ) {
+               /* Discard non-allocatable sections */
+               if ( ! ( bfd_get_section_flags ( bfd, section ) & SEC_ALLOC ) )
+                       continue;
+               /* Add relocations from this section */
+               reltab = read_reltab ( bfd, symtab, section );
+               for ( rel = reltab ; *rel ; rel++ )
+                       process_reloc ( bfd, section, *rel, &pe_reltab );
+               free ( reltab );
+       }
+
+       /* Close input file */
+       bfd_close ( bfd );
+
+       /* Generate relocation section */
+       xlseek ( fd, 0, SEEK_END );
+       reloc_len = output_pe_reltab ( fd, pe_reltab );
+
+       /* Modify image header */
+       *image_size += reloc_len;
+       data_dir[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = reloc_len;
+       pe_sections[RELOC_SECTION_INDEX].Misc.VirtualSize = reloc_len;
+       pe_sections[RELOC_SECTION_INDEX].SizeOfRawData = reloc_len;
+
+       /* Unmap output file header */
+       munmap ( dos, PE_HEADER_LEN );
+
+       /* Close output file */
+       xclose ( fd );
+}
+
+/**
+ * Print help
+ *
+ * @v program_name     Program name
+ */
+static void print_help ( const char *program_name ) {
+       eprintf ( "Syntax: %s [-v|-q] infile outfile\n", program_name );
+}
+
+/**
+ * Parse command-line options
+ *
+ * @v argc             Argument count
+ * @v argv             Argument list
+ * @v opts             Options structure to populate
+ */
+static int parse_options ( const int argc, char **argv,
+                          struct options *opts ) {
+       int c;
+
+       while (1) {
+               int option_index = 0;
+               static struct option long_options[] = {
+                       { "help", 0, NULL, 'h' },
+                       { "verbose", 0, NULL, 'v' },
+                       { "quiet", 0, NULL, 'q' },
+                       { 0, 0, 0, 0 }
+               };
+
+               if ( ( c = getopt_long ( argc, argv, "hvq",
+                                        long_options,
+                                        &option_index ) ) == -1 ) {
+                       break;
+               }
+
+               switch ( c ) {
+               case 'v':
+                       opts->verbosity++;
+                       break;
+               case 'q':
+                       if ( opts->verbosity )
+                               opts->verbosity--;
+                       break;
+               case 'h':
+                       print_help ( argv[0] );
+                       exit ( 0 );
+               case '?':
+               default:
+                       exit ( 2 );
+               }
+       }
+       return optind;
+}
+
+/**
+ * Main program
+ *
+ * @v argc             Number of arguments
+ * @v argv             Command-line arguments
+ * @ret rc             Return status code
+ */
+int main ( int argc, char **argv ) {
+       struct options opts = {
+               .verbosity = 0,
+       };
+       int infile_index;
+       const char *infile;
+       const char *outfile;
+
+       /* Initialise libbfd */
+       bfd_init();
+
+       /* Parse command-line arguments */
+       infile_index = parse_options ( argc, argv, &opts );
+       if ( argc != ( infile_index + 2 ) ) {
+               print_help ( argv[0] );
+               exit ( 2 );
+       }
+       infile = argv[infile_index];
+       outfile = argv[infile_index + 1];
+
+       /* Add relocation information */
+       efireloc ( infile, outfile );
+
+       return 0;
+}
diff --git a/wimboot/wimboot-2.7.3/src/errno.h b/wimboot/wimboot-2.7.3/src/errno.h
new file mode 100644 (file)
index 0000000..bcda1cd
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef _ERRNO_H
+#define _ERRNO_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Error numbers
+ *
+ */
+
+#endif /* _ERRNO_H */
diff --git a/wimboot/wimboot-2.7.3/src/huffman.c b/wimboot/wimboot-2.7.3/src/huffman.c
new file mode 100644 (file)
index 0000000..54fb704
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Huffman alphabets
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include "wimboot.h"
+#include "huffman.h"
+
+/**
+ * Transcribe binary value (for debugging)
+ *
+ * @v value            Value
+ * @v bits             Length of value (in bits)
+ * @ret string         Transcribed value
+ */
+static const char * huffman_bin ( unsigned long value, unsigned int bits ) {
+       static char buf[ ( 8 * sizeof ( value ) ) + 1 /* NUL */ ];
+       char *out = buf;
+
+       /* Sanity check */
+       assert ( bits < sizeof ( buf ) );
+
+       /* Transcribe value */
+       while ( bits-- )
+               *(out++) = ( ( value & ( 1 << bits ) ) ? '1' : '0' );
+       *out = '\0';
+
+       return buf;
+}
+
+/**
+ * Dump Huffman alphabet (for debugging)
+ *
+ * @v alphabet         Huffman alphabet
+ */
+static void __attribute__ (( unused ))
+huffman_dump_alphabet ( struct huffman_alphabet *alphabet ) {
+       struct huffman_symbols *sym;
+       unsigned int bits;
+       unsigned int huf;
+       unsigned int i;
+
+       /* Dump symbol table for each utilised length */
+       for ( bits = 1 ; bits <= ( sizeof ( alphabet->huf ) /
+                                  sizeof ( alphabet->huf[0] ) ) ; bits++ ) {
+               sym = &alphabet->huf[ bits - 1 ];
+               if ( sym->freq == 0 )
+                       continue;
+               huf = ( sym->start >> sym->shift );
+               DBG ( "Huffman length %d start \"%s\" freq %d:", bits,
+                     huffman_bin ( huf, sym->bits ), sym->freq );
+               for ( i = 0 ; i < sym->freq ; i++ ) {
+                       DBG ( " %03x", sym->raw[ huf + i ] );
+               }
+               DBG ( "\n" );
+       }
+
+       /* Dump quick lookup table */
+       DBG ( "Huffman quick lookup:" );
+       for ( i = 0 ; i < ( sizeof ( alphabet->lookup ) /
+                           sizeof ( alphabet->lookup[0] ) ) ; i++ ) {
+               DBG ( " %d", ( alphabet->lookup[i] + 1 ) );
+       }
+       DBG ( "\n" );
+}
+
+/**
+ * Construct Huffman alphabet
+ *
+ * @v alphabet         Huffman alphabet
+ * @v lengths          Symbol length table
+ * @v count            Number of symbols
+ * @ret rc             Return status code
+ */
+int huffman_alphabet ( struct huffman_alphabet *alphabet,
+                      uint8_t *lengths, unsigned int count ) {
+       struct huffman_symbols *sym;
+       unsigned int huf;
+       unsigned int cum_freq;
+       unsigned int bits;
+       unsigned int raw;
+       unsigned int adjustment;
+       unsigned int prefix;
+       int empty;
+       int complete;
+
+       /* Clear symbol table */
+       memset ( alphabet->huf, 0, sizeof ( alphabet->huf ) );
+
+       /* Count number of symbols with each Huffman-coded length */
+       empty = 1;
+       for ( raw = 0 ; raw < count ; raw++ ) {
+               bits = lengths[raw];
+               if ( bits ) {
+                       alphabet->huf[ bits - 1 ].freq++;
+                       empty = 0;
+               }
+       }
+
+       /* In the degenerate case of having no symbols (i.e. an unused
+        * alphabet), generate a trivial alphabet with exactly two
+        * single-bit codes.  This allows callers to avoid having to
+        * check for this special case.
+        */
+       if ( empty )
+               alphabet->huf[0].freq = 2;
+
+       /* Populate Huffman-coded symbol table */
+       huf = 0;
+       cum_freq = 0;
+       for ( bits = 1 ; bits <= ( sizeof ( alphabet->huf ) /
+                                  sizeof ( alphabet->huf[0] ) ) ; bits++ ) {
+               sym = &alphabet->huf[ bits - 1 ];
+               sym->bits = bits;
+               sym->shift = ( HUFFMAN_BITS - bits );
+               sym->start = ( huf << sym->shift );
+               sym->raw = &alphabet->raw[cum_freq];
+               huf += sym->freq;
+               if ( huf > ( 1U << bits ) ) {
+                       DBG ( "Huffman alphabet has too many symbols with "
+                             "lengths <=%d\n", bits );
+                       return -1;
+               }
+               huf <<= 1;
+               cum_freq += sym->freq;
+       }
+       complete = ( huf == ( 1U << bits ) );
+
+       /* Populate raw symbol table */
+       for ( raw = 0 ; raw < count ; raw++ ) {
+               bits = lengths[raw];
+               if ( bits ) {
+                       sym = &alphabet->huf[ bits - 1 ];
+                       *(sym->raw++) = raw;
+               }
+       }
+
+       /* Adjust Huffman-coded symbol table raw pointers and populate
+        * quick lookup table.
+        */
+       for ( bits = 1 ; bits <= ( sizeof ( alphabet->huf ) /
+                                  sizeof ( alphabet->huf[0] ) ) ; bits++ ) {
+               sym = &alphabet->huf[ bits - 1 ];
+
+               /* Adjust raw pointer */
+               sym->raw -= sym->freq; /* Reset to first symbol */
+               adjustment = ( sym->start >> sym->shift );
+               sym->raw -= adjustment; /* Adjust for quick indexing */
+
+               /* Populate quick lookup table */
+               for ( prefix = ( sym->start >> HUFFMAN_QL_SHIFT ) ;
+                     prefix < ( 1 << HUFFMAN_QL_BITS ) ; prefix++ ) {
+                       alphabet->lookup[prefix] = ( bits - 1 );
+               }
+       }
+
+       /* Check that there are no invalid codes */
+       if ( ! complete ) {
+               DBG ( "Huffman alphabet is incomplete\n" );
+               return -1;
+       }
+
+       return 0;
+}
+
+/**
+ * Get Huffman symbol set
+ *
+ * @v alphabet         Huffman alphabet
+ * @v huf              Raw input value (normalised to HUFFMAN_BITS bits)
+ * @ret sym            Huffman symbol set
+ */
+struct huffman_symbols * huffman_sym ( struct huffman_alphabet *alphabet,
+                                      unsigned int huf ) {
+       struct huffman_symbols *sym;
+       unsigned int lookup_index;
+
+       /* Find symbol set for this length */
+       lookup_index = ( huf >> HUFFMAN_QL_SHIFT );
+       sym = &alphabet->huf[ alphabet->lookup[ lookup_index ] ];
+       while ( huf < sym->start )
+               sym--;
+       return sym;
+}
diff --git a/wimboot/wimboot-2.7.3/src/huffman.h b/wimboot/wimboot-2.7.3/src/huffman.h
new file mode 100644 (file)
index 0000000..ee38c92
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef _HUFFMAN_H
+#define _HUFFMAN_H
+
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Huffman alphabets
+ *
+ */
+
+#include <stdint.h>
+
+/** Maximum length of a Huffman symbol (in bits) */
+#define HUFFMAN_BITS 16
+
+/** Raw huffman symbol */
+typedef uint16_t huffman_raw_symbol_t;
+
+/** Quick lookup length for a Huffman symbol (in bits)
+ *
+ * This is a policy decision.
+ */
+#define HUFFMAN_QL_BITS 7
+
+/** Quick lookup shift */
+#define HUFFMAN_QL_SHIFT ( HUFFMAN_BITS - HUFFMAN_QL_BITS )
+
+/** A Huffman-coded set of symbols of a given length */
+struct huffman_symbols {
+       /** Length of Huffman-coded symbols (in bits) */
+       uint8_t bits;
+       /** Shift to normalise symbols of this length to HUFFMAN_BITS bits */
+       uint8_t shift;
+       /** Number of Huffman-coded symbols having this length */
+       uint16_t freq;
+       /** First symbol of this length (normalised to HUFFMAN_BITS bits)
+        *
+        * Stored as a 32-bit value to allow the value
+        * (1<<HUFFMAN_BITS ) to be used for empty sets of symbols
+        * longer than the maximum utilised length.
+        */
+       uint32_t start;
+       /** Raw symbols having this length */
+       huffman_raw_symbol_t *raw;
+};
+
+/** A Huffman-coded alphabet */
+struct huffman_alphabet {
+       /** Huffman-coded symbol set for each length */
+       struct huffman_symbols huf[HUFFMAN_BITS];
+       /** Quick lookup table */
+       uint8_t lookup[ 1 << HUFFMAN_QL_BITS ];
+       /** Raw symbols
+        *
+        * Ordered by Huffman-coded symbol length, then by symbol
+        * value.  This field has a variable length.
+        */
+       huffman_raw_symbol_t raw[0];
+};
+
+/**
+ * Get Huffman symbol length
+ *
+ * @v sym              Huffman symbol set
+ * @ret len            Length (in bits)
+ */
+static inline __attribute__ (( always_inline )) unsigned int
+huffman_len ( struct huffman_symbols *sym ) {
+
+       return sym->bits;
+}
+
+/**
+ * Get Huffman symbol value
+ *
+ * @v sym              Huffman symbol set
+ * @v huf              Raw input value (normalised to HUFFMAN_BITS bits)
+ * @ret raw            Raw symbol value
+ */
+static inline __attribute__ (( always_inline )) huffman_raw_symbol_t
+huffman_raw ( struct huffman_symbols *sym, unsigned int huf ) {
+
+       return sym->raw[ huf >> sym->shift ];
+}
+
+extern int huffman_alphabet ( struct huffman_alphabet *alphabet,
+                             uint8_t *lengths, unsigned int count );
+extern struct huffman_symbols *
+huffman_sym ( struct huffman_alphabet *alphabet, unsigned int huf );
+
+#endif /* _HUFFMAN_H */
diff --git a/wimboot/wimboot-2.7.3/src/i386.i b/wimboot/wimboot-2.7.3/src/i386.i
new file mode 100644 (file)
index 0000000..099070d
--- /dev/null
@@ -0,0 +1 @@
+       .code32
diff --git a/wimboot/wimboot-2.7.3/src/int13.c b/wimboot/wimboot-2.7.3/src/int13.c
new file mode 100644 (file)
index 0000000..4538f9f
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * INT 13 emulation
+ *
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include "wimboot.h"
+#include "int13.h"
+#include "vdisk.h"
+
+/** Emulated drive number */
+static int vdisk_drive;
+
+/**
+ * Initialise emulation
+ *
+ * @ret drive          Emulated drive number
+ */
+int initialise_int13 ( void ) {
+
+       /* Determine drive number */
+       vdisk_drive = ( 0x80 | INT13_DRIVE_COUNT++ );
+       DBG ( "Emulating drive %#02x\n", vdisk_drive );
+
+       return vdisk_drive;
+}
+
+/**
+ * INT 13, 08 - Get drive parameters
+ *
+ * @ret ch             Low bits of maximum cylinder number
+ * @ret cl (bits 7:6)  High bits of maximum cylinder number
+ * @ret cl (bits 5:0)  Maximum sector number
+ * @ret dh             Maximum head number
+ * @ret dl             Number of drives
+ * @ret ah             Status code
+ */
+static void int13_get_parameters ( struct bootapp_callback_params *params ) {
+       unsigned int max_cylinder = ( VDISK_CYLINDERS - 1 );
+       unsigned int max_head = ( VDISK_HEADS - 1 );
+       unsigned int max_sector = ( VDISK_SECTORS_PER_TRACK - 0 /* sic */ );
+       unsigned int num_drives;
+       unsigned int min_num_drives;
+
+       /* Calculate number of drives to report */
+       num_drives = INT13_DRIVE_COUNT;
+       min_num_drives = ( ( vdisk_drive & 0x7f ) + 1 );
+       if ( num_drives < min_num_drives )
+               num_drives = min_num_drives;
+
+       /* Fill in drive parameters */
+       params->ch = ( max_cylinder & 0xff );
+       params->cl = ( ( ( max_cylinder >> 8 ) << 6 ) | max_sector );
+       params->dh = max_head;
+       params->dl = num_drives;
+       DBG2 ( "Get parameters: C/H/S = %d/%d/%d, drives = %d\n",
+              ( max_cylinder + 1 ), ( max_head + 1 ), max_sector, num_drives );
+
+       /* Success */
+       params->ah = 0;
+}
+
+/**
+ * INT 13, 15 - Get disk type
+ *
+ * @ret cx:dx          Sector count
+ * @ret ah             Type code
+ */
+static void int13_get_disk_type ( struct bootapp_callback_params *params ) {
+       uint32_t sector_count = VDISK_COUNT;
+       uint8_t drive_type = INT13_DISK_TYPE_HDD;
+
+       /* Fill in disk type */
+       params->cx = ( sector_count >> 16 );
+       params->dx = ( sector_count & 0xffff );
+       params->ah = drive_type;
+       DBG2 ( "Get disk type: sectors = %#08x, type = %d\n",
+              sector_count, drive_type );
+}
+
+/**
+ * INT 13, 41 - Extensions installation check
+ *
+ * @v bx               0x55aa
+ * @ret bx             0xaa55
+ * @ret cx             Extensions API support bitmap
+ * @ret ah             API version
+ */
+static void int13_extension_check ( struct bootapp_callback_params *params ) {
+
+       /* Fill in extension information */
+       params->bx = 0xaa55;
+       params->cx = INT13_EXTENSION_LINEAR;
+       params->ah = INT13_EXTENSION_VER_1_X;
+       DBG2 ( "Extensions installation check\n" );
+}
+
+/**
+ * INT 13, 48 - Get extended parameters
+ *
+ * @v ds:si            Drive parameter table
+ * @ret ah             Status code
+ */
+static void
+int13_get_extended_parameters ( struct bootapp_callback_params *params ) {
+       struct int13_disk_parameters *disk_params;
+
+       /* Fill in extended parameters */
+       disk_params = REAL_PTR ( params->ds, params->si );
+       memset ( disk_params, 0, sizeof ( *disk_params ) );
+       disk_params->bufsize = sizeof ( *disk_params );
+       disk_params->flags = INT13_FL_DMA_TRANSPARENT;
+       disk_params->cylinders = VDISK_CYLINDERS;
+       disk_params->heads = VDISK_HEADS;
+       disk_params->sectors_per_track = VDISK_SECTORS_PER_TRACK;
+       disk_params->sectors = VDISK_COUNT;
+       disk_params->sector_size = VDISK_SECTOR_SIZE;
+       DBG2 ( "Get extended parameters: C/H/S = %d/%d/%d, sectors = %#08llx "
+              "(%d bytes)\n", disk_params->cylinders, disk_params->heads,
+              disk_params->sectors_per_track, disk_params->sectors,
+              disk_params->sector_size );
+
+       /* Success */
+       params->ah = 0;
+}
+
+/**
+ * INT 13, 42 - Extended read
+ *
+ * @v ds:si            Disk address packet
+ * @ret ah             Status code
+ */
+static void int13_extended_read ( struct bootapp_callback_params *params ) {
+       struct int13_disk_address *disk_address;
+       void *data;
+
+       /* Read from emulated disk */
+       disk_address = REAL_PTR ( params->ds, params->si );
+       data = REAL_PTR ( disk_address->buffer.segment,
+                         disk_address->buffer.offset );
+       vdisk_read ( disk_address->lba, disk_address->count, data );
+
+       /* Success */
+       params->ah = 0;
+}
+
+/**
+ * Emulate INT 13 drive
+ *
+ * @v params           Parameters
+ */
+void emulate_int13 ( struct bootapp_callback_params *params ) {
+       int command = params->ah;
+       int drive = params->dl;
+       int min_num_drives;
+       unsigned long eflags;
+
+       if ( drive == vdisk_drive ) {
+
+               /* Emulated drive - handle internally */
+
+               /* Populate eflags with a sensible starting value */
+               __asm__ ( "pushf\n\t"
+                         "pop %0\n\t"
+                         : "=r" ( eflags ) );
+               params->eflags = ( eflags & ~CF );
+
+               /* Handle command */
+               switch ( command ) {
+               case INT13_GET_PARAMETERS:
+                       int13_get_parameters ( params );
+                       break;
+               case INT13_GET_DISK_TYPE:
+                       int13_get_disk_type ( params );
+                       break;
+               case INT13_EXTENSION_CHECK:
+                       int13_extension_check ( params );
+                       break;
+               case INT13_GET_EXTENDED_PARAMETERS:
+                       int13_get_extended_parameters ( params );
+                       break;
+               case INT13_EXTENDED_READ:
+                       int13_extended_read ( params );
+                       break;
+               default:
+                       DBG ( "Unrecognised INT 13,%02x\n", command );
+                       params->eflags |= CF;
+                       break;
+               }
+
+       } else {
+
+               /* Pass through command to underlying INT 13 */
+               call_interrupt ( params );
+
+               /* Modify drive count, if applicable */
+               if ( command == INT13_GET_PARAMETERS ) {
+                       min_num_drives = ( ( vdisk_drive & 0x7f ) + 1 );
+                       if ( params->dl < min_num_drives )
+                               params->dl = min_num_drives;
+               }
+       }
+}
diff --git a/wimboot/wimboot-2.7.3/src/int13.h b/wimboot/wimboot-2.7.3/src/int13.h
new file mode 100644 (file)
index 0000000..e765ffa
--- /dev/null
@@ -0,0 +1,120 @@
+#ifndef _INT13_H
+#define _INT13_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * INT 13 emulation
+ *
+ */
+
+/** Construct a pointer from a real-mode segment:offset address */
+#define REAL_PTR( segment, offset ) \
+       ( ( void * ) ( intptr_t ) ( ( (segment) << 4 ) + offset ) )
+
+/** Get drive parameters */
+#define INT13_GET_PARAMETERS           0x08
+/** Get disk type */
+#define INT13_GET_DISK_TYPE            0x15
+/** Extensions installation check */
+#define INT13_EXTENSION_CHECK          0x41
+/** Extended read */
+#define INT13_EXTENDED_READ            0x42
+/** Get extended drive parameters */
+#define INT13_GET_EXTENDED_PARAMETERS  0x48
+
+/** Operation completed successfully */
+#define INT13_STATUS_SUCCESS           0x00
+/** Invalid function or parameter */
+#define INT13_STATUS_INVALID           0x01
+/** Read error */
+#define INT13_STATUS_READ_ERROR                0x04
+/** Reset failed */
+#define INT13_STATUS_RESET_FAILED      0x05
+/** Write error */
+#define INT13_STATUS_WRITE_ERROR       0xcc
+
+/** No such drive */
+#define INT13_DISK_TYPE_NONE           0x00
+/** Floppy without change-line support */
+#define INT13_DISK_TYPE_FDD            0x01
+/** Floppy with change-line support */
+#define INT13_DISK_TYPE_FDD_CL         0x02
+/** Hard disk */
+#define INT13_DISK_TYPE_HDD            0x03
+
+/** Extended disk access functions supported */
+#define INT13_EXTENSION_LINEAR         0x01
+
+/** INT13 extensions version 1.x */
+#define INT13_EXTENSION_VER_1_X                0x01
+
+/** DMA boundary errors handled transparently */
+#define INT13_FL_DMA_TRANSPARENT       0x01
+
+/** BIOS drive counter */
+#define INT13_DRIVE_COUNT ( *( ( ( uint8_t * ) REAL_PTR ( 0x40, 0x75 ) ) ) )
+
+/** An INT 13 disk address packet */
+struct int13_disk_address {
+       /** Size of the packet, in bytes */
+       uint8_t bufsize;
+       /** Reserved */
+       uint8_t reserved_a;
+       /** Block count */
+       uint8_t count;
+       /** Reserved */
+       uint8_t reserved_b;
+       /** Data buffer */
+       struct segoff buffer;
+       /** Starting block number */
+       uint64_t lba;
+       /** Data buffer (EDD 3.0+ only) */
+       uint64_t buffer_phys;
+       /** Block count (EDD 4.0+ only) */
+       uint32_t long_count;
+       /** Reserved */
+       uint32_t reserved_c;
+} __attribute__ (( packed ));
+
+/** INT 13 disk parameters */
+struct int13_disk_parameters {
+       /** Size of this structure */
+       uint16_t bufsize;
+       /** Flags */
+       uint16_t flags;
+       /** Number of cylinders */
+       uint32_t cylinders;
+       /** Number of heads */
+       uint32_t heads;
+       /** Number of sectors per track */
+       uint32_t sectors_per_track;
+       /** Total number of sectors on drive */
+       uint64_t sectors;
+       /** Bytes per sector */
+       uint16_t sector_size;
+} __attribute__ (( packed ));
+
+extern int initialise_int13 ( void );
+extern void emulate_int13 ( struct bootapp_callback_params *params );
+
+#endif /* _INT13_H */
diff --git a/wimboot/wimboot-2.7.3/src/ipxe/vsprintf.c b/wimboot/wimboot-2.7.3/src/ipxe/vsprintf.c
new file mode 100644 (file)
index 0000000..5cc7231
--- /dev/null
@@ -0,0 +1,466 @@
+/*
+ * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stddef.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+#include <wchar.h>
+#include <ipxe/vsprintf.h>
+
+/** @file */
+
+#define CHAR_LEN       0       /**< "hh" length modifier */
+#define SHORT_LEN      1       /**< "h" length modifier */
+#define INT_LEN                2       /**< no length modifier */
+#define LONG_LEN       3       /**< "l" length modifier */
+#define LONGLONG_LEN   4       /**< "ll" length modifier */
+#define SIZE_T_LEN     5       /**< "z" length modifier */
+
+static uint8_t type_sizes[] = {
+       [CHAR_LEN]      = sizeof ( char ),
+       [SHORT_LEN]     = sizeof ( short ),
+       [INT_LEN]       = sizeof ( int ),
+       [LONG_LEN]      = sizeof ( long ),
+       [LONGLONG_LEN]  = sizeof ( long long ),
+       [SIZE_T_LEN]    = sizeof ( size_t ),
+};
+
+/**
+ * Use lower-case for hexadecimal digits
+ *
+ * Note that this value is set to 0x20 since that makes for very
+ * efficient calculations.  (Bitwise-ORing with @c LCASE converts to a
+ * lower-case character, for example.)
+ */
+#define LCASE 0x20
+
+/**
+ * Use "alternate form"
+ *
+ * For hexadecimal numbers, this means to add a "0x" or "0X" prefix to
+ * the number.
+ */
+#define ALT_FORM 0x02
+
+/**
+ * Use zero padding
+ *
+ * Note that this value is set to 0x10 since that allows the pad
+ * character to be calculated as @c 0x20|(flags&ZPAD)
+ */
+#define ZPAD 0x10
+
+/**
+ * Format a hexadecimal number
+ *
+ * @v end              End of buffer to contain number
+ * @v num              Number to format
+ * @v width            Minimum field width
+ * @v flags            Format flags
+ * @ret ptr            End of buffer
+ *
+ * Fills a buffer in reverse order with a formatted hexadecimal
+ * number.  The number will be zero-padded to the specified width.
+ * Lower-case and "alternate form" (i.e. "0x" prefix) flags may be
+ * set.
+ *
+ * There must be enough space in the buffer to contain the largest
+ * number that this function can format.
+ */
+static char * format_hex ( char *end, unsigned long long num, int width,
+                          int flags ) {
+       char *ptr = end;
+       int case_mod = ( flags & LCASE );
+       int pad = ( ( flags & ZPAD ) | ' ' );
+
+       /* Generate the number */
+       do {
+               *(--ptr) = "0123456789ABCDEF"[ num & 0xf ] | case_mod;
+               num >>= 4;
+       } while ( num );
+
+       /* Pad to width */
+       while ( ( end - ptr ) < width )
+               *(--ptr) = pad;
+
+       /* Add "0x" or "0X" if alternate form specified */
+       if ( flags & ALT_FORM ) {
+               *(--ptr) = 'X' | case_mod;
+               *(--ptr) = '0';
+       }
+
+       return ptr;
+}
+
+/**
+ * Format a decimal number
+ *
+ * @v end              End of buffer to contain number
+ * @v num              Number to format
+ * @v width            Minimum field width
+ * @v flags            Format flags
+ * @ret ptr            End of buffer
+ *
+ * Fills a buffer in reverse order with a formatted decimal number.
+ * The number will be space-padded to the specified width.
+ *
+ * There must be enough space in the buffer to contain the largest
+ * number that this function can format.
+ */
+static char * format_decimal ( char *end, signed long num, int width,
+                              int flags ) {
+       char *ptr = end;
+       int negative = 0;
+       int zpad = ( flags & ZPAD );
+       int pad = ( zpad | ' ' );
+
+       /* Generate the number */
+       if ( num < 0 ) {
+               negative = 1;
+               num = -num;
+       }
+       do {
+               *(--ptr) = '0' + ( num % 10 );
+               num /= 10;
+       } while ( num );
+
+       /* Add "-" if necessary */
+       if ( negative && ( ! zpad ) )
+               *(--ptr) = '-';
+
+       /* Pad to width */
+       while ( ( end - ptr ) < width )
+               *(--ptr) = pad;
+
+       /* Add "-" if necessary */
+       if ( negative && zpad )
+               *ptr = '-';
+
+       return ptr;
+}
+
+/**
+ * Print character via a printf context
+ *
+ * @v ctx              Context
+ * @v c                        Character
+ *
+ * Call's the printf_context::handler() method and increments
+ * printf_context::len.
+ */
+static inline void cputchar ( struct printf_context *ctx, unsigned int c ) {
+       ctx->handler ( ctx, c );
+       ++ctx->len;
+}
+
+/**
+ * Write a formatted string to a printf context
+ *
+ * @v ctx              Context
+ * @v fmt              Format string
+ * @v args             Arguments corresponding to the format string
+ * @ret len            Length of formatted string
+ */
+size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) {
+       int flags;
+       int width;
+       uint8_t *length;
+       char *ptr;
+       char tmp_buf[32]; /* 32 is enough for all numerical formats.
+                          * Insane width fields could overflow this buffer. */
+       wchar_t *wptr;
+
+       /* Initialise context */
+       ctx->len = 0;
+
+       for ( ; *fmt ; fmt++ ) {
+               /* Pass through ordinary characters */
+               if ( *fmt != '%' ) {
+                       cputchar ( ctx, *fmt );
+                       continue;
+               }
+               fmt++;
+               /* Process flag characters */
+               flags = 0;
+               for ( ; ; fmt++ ) {
+                       if ( *fmt == '#' ) {
+                               flags |= ALT_FORM;
+                       } else if ( *fmt == '0' ) {
+                               flags |= ZPAD;
+                       } else {
+                               /* End of flag characters */
+                               break;
+                       }
+               }
+               /* Process field width */
+               width = 0;
+               for ( ; ; fmt++ ) {
+                       if ( ( ( unsigned ) ( *fmt - '0' ) ) < 10 ) {
+                               width = ( width * 10 ) + ( *fmt - '0' );
+                       } else {
+                               break;
+                       }
+               }
+               /* We don't do floating point */
+               /* Process length modifier */
+               length = &type_sizes[INT_LEN];
+               for ( ; ; fmt++ ) {
+                       if ( *fmt == 'h' ) {
+                               length--;
+                       } else if ( *fmt == 'l' ) {
+                               length++;
+                       } else if ( *fmt == 'z' ) {
+                               length = &type_sizes[SIZE_T_LEN];
+                       } else {
+                               break;
+                       }
+               }
+               /* Process conversion specifier */
+               ptr = tmp_buf + sizeof ( tmp_buf ) - 1;
+               *ptr = '\0';
+               wptr = NULL;
+               if ( *fmt == 'c' ) {
+                       if ( length < &type_sizes[LONG_LEN] ) {
+                               cputchar ( ctx, va_arg ( args, unsigned int ) );
+                       } else {
+                               wchar_t wc;
+                               size_t len;
+
+                               wc = va_arg ( args, wint_t );
+                               len = wcrtomb ( tmp_buf, wc, NULL );
+                               tmp_buf[len] = '\0';
+                               ptr = tmp_buf;
+                       }
+               } else if ( *fmt == 's' ) {
+                       if ( length < &type_sizes[LONG_LEN] ) {
+                               ptr = va_arg ( args, char * );
+                       } else {
+                               wptr = va_arg ( args, wchar_t * );
+                       }
+                       if ( ( ptr == NULL ) && ( wptr == NULL ) )
+                               ptr = "<NULL>";
+               } else if ( *fmt == 'p' ) {
+                       intptr_t ptrval;
+
+                       ptrval = ( intptr_t ) va_arg ( args, void * );
+                       ptr = format_hex ( ptr, ptrval, width, 
+                                          ( ALT_FORM | LCASE ) );
+               } else if ( ( *fmt & ~0x20 ) == 'X' ) {
+                       unsigned long long hex;
+
+                       flags |= ( *fmt & 0x20 ); /* LCASE */
+                       if ( *length >= sizeof ( unsigned long long ) ) {
+                               hex = va_arg ( args, unsigned long long );
+                       } else if ( *length >= sizeof ( unsigned long ) ) {
+                               hex = va_arg ( args, unsigned long );
+                       } else {
+                               hex = va_arg ( args, unsigned int );
+                       }
+                       ptr = format_hex ( ptr, hex, width, flags );
+               } else if ( ( *fmt == 'd' ) || ( *fmt == 'i' ) ){
+                       signed long decimal;
+
+                       if ( *length >= sizeof ( signed long ) ) {
+                               decimal = va_arg ( args, signed long );
+                       } else {
+                               decimal = va_arg ( args, signed int );
+                       }
+                       ptr = format_decimal ( ptr, decimal, width, flags );
+               } else {
+                       *(--ptr) = *fmt;
+               }
+               /* Write out conversion result */
+               if ( wptr == NULL ) {
+                       for ( ; *ptr ; ptr++ ) {
+                               cputchar ( ctx, *ptr );
+                       }
+               } else {
+                       for ( ; *wptr ; wptr++ ) {
+                               size_t len = wcrtomb ( tmp_buf, *wptr, NULL );
+                               for ( ptr = tmp_buf ; len-- ; ptr++ ) {
+                                       cputchar ( ctx, *ptr );
+                               }
+                       }
+               }
+       }
+
+       return ctx->len;
+}
+
+/** Context used by vsnprintf() and friends */
+struct sputc_context {
+       struct printf_context ctx;
+       /** Buffer for formatted string (used by printf_sputc()) */
+       char *buf;
+       /** Buffer length (used by printf_sputc()) */
+       size_t max_len; 
+};
+
+/**
+ * Write character to buffer
+ *
+ * @v ctx              Context
+ * @v c                        Character
+ */
+static void printf_sputc ( struct printf_context *ctx, unsigned int c ) {
+       struct sputc_context * sctx =
+               container_of ( ctx, struct sputc_context, ctx );
+
+       if ( ctx->len < sctx->max_len )
+               sctx->buf[ctx->len] = c;
+}
+
+/**
+ * Write a formatted string to a buffer
+ *
+ * @v buf              Buffer into which to write the string
+ * @v size             Size of buffer
+ * @v fmt              Format string
+ * @v args             Arguments corresponding to the format string
+ * @ret len            Length of formatted string
+ *
+ * If the buffer is too small to contain the string, the returned
+ * length is the length that would have been written had enough space
+ * been available.
+ */
+int vsnprintf ( char *buf, size_t size, const char *fmt, va_list args ) {
+       struct sputc_context sctx;
+       size_t len;
+       size_t end;
+
+       /* Hand off to vcprintf */
+       sctx.ctx.handler = printf_sputc;
+       sctx.buf = buf;
+       sctx.max_len = size;
+       len = vcprintf ( &sctx.ctx, fmt, args );
+
+       /* Add trailing NUL */
+       if ( size ) {
+               end = size - 1;
+               if ( len < end )
+                       end = len;
+               buf[end] = '\0';
+       }
+
+       return len;
+}
+
+/**
+ * Write a formatted string to a buffer
+ *
+ * @v buf              Buffer into which to write the string
+ * @v size             Size of buffer
+ * @v fmt              Format string
+ * @v ...              Arguments corresponding to the format string
+ * @ret len            Length of formatted string
+ */
+int snprintf ( char *buf, size_t size, const char *fmt, ... ) {
+       va_list args;
+       int i;
+
+       va_start ( args, fmt );
+       i = vsnprintf ( buf, size, fmt, args );
+       va_end ( args );
+       return i;
+}
+
+/**
+ * Version of vsnprintf() that accepts a signed buffer size
+ *
+ * @v buf              Buffer into which to write the string
+ * @v size             Size of buffer
+ * @v fmt              Format string
+ * @v args             Arguments corresponding to the format string
+ * @ret len            Length of formatted string
+ */
+int vssnprintf ( char *buf, ssize_t ssize, const char *fmt, va_list args ) {
+
+       /* Treat negative buffer size as zero buffer size */
+       if ( ssize < 0 )
+               ssize = 0;
+
+       /* Hand off to vsnprintf */
+       return vsnprintf ( buf, ssize, fmt, args );
+}
+
+/**
+ * Version of vsnprintf() that accepts a signed buffer size
+ *
+ * @v buf              Buffer into which to write the string
+ * @v size             Size of buffer
+ * @v fmt              Format string
+ * @v ...              Arguments corresponding to the format string
+ * @ret len            Length of formatted string
+ */
+int ssnprintf ( char *buf, ssize_t ssize, const char *fmt, ... ) {
+       va_list args;
+       int len;
+
+       /* Hand off to vssnprintf */
+       va_start ( args, fmt );
+       len = vssnprintf ( buf, ssize, fmt, args );
+       va_end ( args );
+       return len;
+}
+
+/**
+ * Write character to console
+ *
+ * @v ctx              Context
+ * @v c                        Character
+ */
+static void printf_putchar ( struct printf_context *ctx __unused,
+                            unsigned int c ) {
+       putchar ( c );
+}
+
+/**
+ * Write a formatted string to the console
+ *
+ * @v fmt              Format string
+ * @v args             Arguments corresponding to the format string
+ * @ret len            Length of formatted string
+ */
+int vprintf ( const char *fmt, va_list args ) {
+       struct printf_context ctx;
+
+       /* Hand off to vcprintf */
+       ctx.handler = printf_putchar;   
+       return vcprintf ( &ctx, fmt, args );    
+}
+
+/**
+ * Write a formatted string to the console.
+ *
+ * @v fmt              Format string
+ * @v ...              Arguments corresponding to the format string
+ * @ret        len             Length of formatted string
+ */
+int printf ( const char *fmt, ... ) {
+       va_list args;
+       int i;
+
+       va_start ( args, fmt );
+       i = vprintf ( fmt, args );
+       va_end ( args );
+       return i;
+}
diff --git a/wimboot/wimboot-2.7.3/src/ipxe/vsprintf.h b/wimboot/wimboot-2.7.3/src/ipxe/vsprintf.h
new file mode 100644 (file)
index 0000000..c48c97a
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef _IPXE_VSPRINTF_H
+#define _IPXE_VSPRINTF_H
+
+/** @file
+ *
+ * printf() and friends
+ *
+ * Etherboot's printf() functions understand the following subset of
+ * the standard C printf()'s format specifiers:
+ *
+ *     - Flag characters
+ *             - '#'           - Alternate form (i.e. "0x" prefix)
+ *             - '0'           - Zero-pad
+ *     - Field widths
+ *     - Length modifiers
+ *             - 'hh'          - Signed / unsigned char
+ *             - 'h'           - Signed / unsigned short
+ *             - 'l'           - Signed / unsigned long
+ *             - 'll'          - Signed / unsigned long long
+ *             - 'z'           - Signed / unsigned size_t
+ *     - Conversion specifiers
+ *             - 'd'           - Signed decimal
+ *             - 'x','X'       - Unsigned hexadecimal
+ *             - 'c'           - Character
+ *             - 's'           - String
+ *             - 'p'           - Pointer
+ *
+ * Hexadecimal numbers are always zero-padded to the specified field
+ * width (if any); decimal numbers are always space-padded.  Decimal
+ * long longs are not supported.
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+/**
+ * A printf context
+ *
+ * Contexts are used in order to be able to share code between
+ * vprintf() and vsnprintf(), without requiring the allocation of a
+ * buffer for vprintf().
+ */
+struct printf_context {
+       /**
+        * Character handler
+        *
+        * @v ctx       Context
+        * @v c         Character
+        *
+        * This method is called for each character written to the
+        * formatted string.
+        */
+       void ( * handler ) ( struct printf_context *ctx, unsigned int c );
+       /** Length of formatted string
+        *
+        * When handler() is called, @len will be set to the number of
+        * characters written so far (i.e. zero for the first call to
+        * handler()).
+        */
+       size_t len;
+};
+
+extern size_t vcprintf ( struct printf_context *ctx, const char *fmt,
+                        va_list args );
+extern int vssnprintf ( char *buf, ssize_t ssize, const char *fmt,
+                       va_list args );
+extern int __attribute__ (( format ( printf, 3, 4 ) ))
+ssnprintf ( char *buf, ssize_t ssize, const char *fmt, ... );
+
+#endif /* _IPXE_VSPRINTF_H */
diff --git a/wimboot/wimboot-2.7.3/src/lznt1.c b/wimboot/wimboot-2.7.3/src/lznt1.c
new file mode 100644 (file)
index 0000000..9695ee4
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * LZNT1 decompression
+ *
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include "wimboot.h"
+#include "lznt1.h"
+
+/**
+ * Decompress LZNT1-compressed data block
+ *
+ * @v data             Compressed data
+ * @v limit            Length of compressed data up to end of block
+ * @v offset           Starting offset within compressed data
+ * @v block            Decompression buffer for this block, or NULL
+ * @ret out_len                Length of decompressed block, or negative error
+ */
+static ssize_t lznt1_block ( const void *data, size_t limit, size_t offset,
+                            void *block ) {
+       const uint16_t *tuple;
+       const uint8_t *copy_src;
+       uint8_t *copy_dest = block;
+       size_t copy_len;
+       size_t block_out_len = 0;
+       unsigned int split = 12;
+       unsigned int next_threshold = 16;
+       unsigned int tag_bit = 0;
+       unsigned int tag = 0;
+
+       while ( offset != limit ) {
+
+               /* Extract tag */
+               if ( tag_bit == 0 ) {
+                       tag = *( ( uint8_t * ) ( data + offset ) );
+                       offset++;
+                       if ( offset == limit )
+                               break;
+               }
+
+               /* Calculate copy source and length */
+               if ( tag & 1 ) {
+
+                       /* Compressed value */
+                       if ( offset + sizeof ( *tuple ) > limit ) {
+                               DBG ( "LZNT1 compressed value overrun at "
+                                     "%#zx\n", offset );
+                               return -1;
+                       }
+                       tuple = ( data + offset );
+                       offset += sizeof ( *tuple );
+                       copy_len = LZNT1_VALUE_LEN ( *tuple, split );
+                       block_out_len += copy_len;
+                       if ( copy_dest ) {
+                               copy_src = ( copy_dest -
+                                            LZNT1_VALUE_OFFSET ( *tuple,
+                                                                 split ) );
+                               while ( copy_len-- )
+                                       *(copy_dest++) = *(copy_src++);
+                       }
+
+               } else {
+
+                       /* Uncompressed value */
+                       copy_src = ( data + offset );
+                       if ( copy_dest )
+                               *(copy_dest++) = *copy_src;
+                       offset++;
+                       block_out_len++;
+               }
+
+               /* Update split, if applicable */
+               while ( block_out_len > next_threshold ) {
+                       split--;
+                       next_threshold <<= 1;
+               }
+
+               /* Move to next value */
+               tag >>= 1;
+               tag_bit = ( ( tag_bit + 1 ) % 8 );
+       }
+
+       return block_out_len;
+}
+
+/**
+ * Decompress LZNT1-compressed data
+ *
+ * @v data             Compressed data
+ * @v len              Length of compressed data
+ * @v buf              Decompression buffer, or NULL
+ * @ret out_len                Length of decompressed data, or negative error
+ */
+ssize_t lznt1_decompress ( const void *data, size_t len, void *buf ) {
+       const uint16_t *header;
+       const uint8_t *end;
+       size_t offset = 0;
+       ssize_t out_len = 0;
+       size_t block_len;
+       size_t limit;
+       void *block;
+       ssize_t block_out_len;
+
+       while ( offset != len ) {
+
+               /* Check for end marker */
+               if ( ( offset + sizeof ( *end ) ) == len ) {
+                       end = ( data + offset );
+                       if ( *end == 0 )
+                               break;
+               }
+
+               /* Extract block header */
+               if ( ( offset + sizeof ( *header ) ) > len ) {
+                       DBG ( "LZNT1 block header overrun at %#zx\n", offset );
+                       return -1;
+               }
+               header = ( data + offset );
+               offset += sizeof ( *header );
+
+               /* Process block */
+               block_len = LZNT1_BLOCK_LEN ( *header );
+               if ( LZNT1_BLOCK_COMPRESSED ( *header ) ) {
+
+                       /* Compressed block */
+                       DBG2 ( "LZNT1 compressed block %#zx+%#zx\n",
+                              offset, block_len );
+                       limit = ( offset + block_len );
+                       block = ( buf ? ( buf + out_len ) : NULL );
+                       block_out_len = lznt1_block ( data, limit, offset,
+                                                     block );
+                       if ( block_out_len < 0 )
+                               return block_out_len;
+                       offset += block_len;
+                       out_len += block_out_len;
+
+               } else {
+
+                       /* Uncompressed block */
+                       if ( ( offset + block_len ) > len ) {
+                               DBG ( "LZNT1 uncompressed block overrun at "
+                                     "%#zx+%#zx\n", offset, block_len );
+                               return -1;
+                       }
+                       DBG2 ( "LZNT1 uncompressed block %#zx+%#zx\n",
+                              offset, block_len );
+                       if ( buf ) {
+                               memcpy ( ( buf + out_len ), ( data + offset ),
+                                        block_len );
+                       }
+                       offset += block_len;
+                       out_len += block_len;
+               }
+       }
+
+       return out_len;
+}
diff --git a/wimboot/wimboot-2.7.3/src/lznt1.h b/wimboot/wimboot-2.7.3/src/lznt1.h
new file mode 100644 (file)
index 0000000..d78da55
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _LZNT1_H
+#define _LZNT1_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * LZNT1 decompression
+ *
+ */
+
+#include <stdint.h>
+
+/** Extract LZNT1 block length */
+#define LZNT1_BLOCK_LEN( header ) ( ( (header) & 0x0fff ) + 1 )
+
+/** Determine if LZNT1 block is compressed */
+#define LZNT1_BLOCK_COMPRESSED( header ) ( (header) & 0x8000 )
+
+/** Extract LZNT1 compressed value length */
+#define LZNT1_VALUE_LEN( tuple, split ) \
+       ( ( (tuple) & ( ( 1 << (split) ) - 1 ) ) + 3 )
+
+/** Extract LZNT1 compressed value offset */
+#define LZNT1_VALUE_OFFSET( tuple, split ) ( ( (tuple) >> split ) + 1 )
+
+extern ssize_t lznt1_decompress ( const void *data, size_t len, void *buf );
+
+#endif /* _LZNT1_H */
diff --git a/wimboot/wimboot-2.7.3/src/lzx.c b/wimboot/wimboot-2.7.3/src/lzx.c
new file mode 100644 (file)
index 0000000..15d0a55
--- /dev/null
@@ -0,0 +1,670 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * LZX decompression
+ *
+ * This algorithm is derived jointly from the document "[MS-PATCH]:
+ * LZX DELTA Compression and Decompression", available from
+ *
+ *     http://msdn.microsoft.com/en-us/library/cc483133.aspx
+ *
+ * and from the file lzx-decompress.c in the wimlib source code.
+ *
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include "wimboot.h"
+#include "huffman.h"
+#include "lzx.h"
+
+/** Base positions, indexed by position slot */
+static unsigned int lzx_position_base[LZX_POSITION_SLOTS];
+
+/**
+ * Attempt to accumulate bits from LZX bitstream
+ *
+ * @v lzx              Decompressor
+ * @v bits             Number of bits to accumulate
+ * @v norm_value       Accumulated value (normalised to 16 bits)
+ *
+ * Note that there may not be sufficient accumulated bits in the
+ * bitstream; callers must check that sufficient bits are available
+ * before using the value.
+ */
+static int lzx_accumulate ( struct lzx *lzx, unsigned int bits ) {
+       const uint16_t *src16;
+
+       /* Accumulate more bits if required */
+       if ( ( lzx->bits < bits ) &&
+            ( lzx->input.offset < lzx->input.len ) ) {
+               src16 = ( ( void * ) lzx->input.data + lzx->input.offset );
+               lzx->input.offset += sizeof ( *src16 );
+               lzx->accumulator |= ( *src16 << ( 16 - lzx->bits ) );
+               lzx->bits += 16;
+       }
+
+       return ( lzx->accumulator >> 16 );
+}
+
+/**
+ * Consume accumulated bits from LZX bitstream
+ *
+ * @v lzx              Decompressor
+ * @v bits             Number of bits to consume
+ * @ret rc             Return status code
+ */
+static int lzx_consume ( struct lzx *lzx, unsigned int bits ) {
+
+       /* Fail if insufficient bits are available */
+       if ( lzx->bits < bits ) {
+               DBG ( "LZX input overrun in %#zx/%#zx out %#zx)\n",
+                     lzx->input.offset, lzx->input.len, lzx->output.offset );
+               return -1;
+       }
+
+       /* Consume bits */
+       lzx->accumulator <<= bits;
+       lzx->bits -= bits;
+
+       return 0;
+}
+
+/**
+ * Get bits from LZX bitstream
+ *
+ * @v lzx              Decompressor
+ * @v bits             Number of bits to fetch
+ * @ret value          Value, or negative error
+ */
+static int lzx_getbits ( struct lzx *lzx, unsigned int bits ) {
+       int norm_value;
+       int rc;
+
+       /* Accumulate more bits if required */
+       norm_value = lzx_accumulate ( lzx, bits );
+
+       /* Consume bits */
+       if ( ( rc = lzx_consume ( lzx, bits ) ) != 0 )
+               return rc;
+
+       return ( norm_value >> ( 16 - bits ) );
+}
+
+/**
+ * Align LZX bitstream for byte access
+ *
+ * @v lzx              Decompressor
+ * @v bits             Minimum number of padding bits
+ * @ret rc             Return status code
+ */
+static int lzx_align ( struct lzx *lzx, unsigned int bits ) {
+       int pad;
+
+       /* Get padding bits */
+       pad = lzx_getbits ( lzx, bits );
+       if ( pad < 0 )
+               return pad;
+
+       /* Consume all accumulated bits */
+       lzx_consume ( lzx, lzx->bits );
+
+       return 0;
+}
+
+/**
+ * Get bytes from LZX bitstream
+ *
+ * @v lzx              Decompressor
+ * @v data             Data buffer, or NULL
+ * @v len              Length of data buffer
+ * @ret rc             Return status code
+ */
+static int lzx_getbytes ( struct lzx *lzx, void *data, size_t len ) {
+
+       /* Sanity check */
+       if ( ( lzx->input.offset + len ) > lzx->input.len ) {
+               DBG ( "LZX input overrun in %#zx/%#zx out %#zx)\n",
+                     lzx->input.offset, lzx->input.len, lzx->output.offset );
+               return -1;
+       }
+
+       /* Copy data */
+       if ( data )
+               memcpy ( data, ( lzx->input.data + lzx->input.offset ), len );
+       lzx->input.offset += len;
+
+       return 0;
+}
+
+/**
+ * Decode LZX Huffman-coded symbol
+ *
+ * @v lzx              Decompressor
+ * @v alphabet         Huffman alphabet
+ * @ret raw            Raw symbol, or negative error
+ */
+static int lzx_decode ( struct lzx *lzx, struct huffman_alphabet *alphabet ) {
+       struct huffman_symbols *sym;
+       int huf;
+       int rc;
+
+       /* Accumulate sufficient bits */
+       huf = lzx_accumulate ( lzx, HUFFMAN_BITS );
+       if ( huf < 0 )
+               return huf;
+
+       /* Decode symbol */
+       sym = huffman_sym ( alphabet, huf );
+
+       /* Consume bits */
+       if ( ( rc = lzx_consume ( lzx, huffman_len ( sym ) ) ) != 0 )
+               return rc;
+
+       return huffman_raw ( sym, huf );
+}
+
+/**
+ * Generate Huffman alphabet from raw length table
+ *
+ * @v lzx              Decompressor
+ * @v count            Number of symbols
+ * @v bits             Length of each length (in bits)
+ * @v lengths          Lengths table to fill in
+ * @v alphabet         Huffman alphabet to fill in
+ * @ret rc             Return status code
+ */
+static int lzx_raw_alphabet ( struct lzx *lzx, unsigned int count,
+                             unsigned int bits, uint8_t *lengths,
+                             struct huffman_alphabet *alphabet ) {
+       unsigned int i;
+       int len;
+       int rc;
+
+       /* Read lengths */
+       for ( i = 0 ; i < count ; i++ ) {
+               len = lzx_getbits ( lzx, bits );
+               if ( len < 0 )
+                       return len;
+               lengths[i] = len;
+       }
+
+       /* Generate Huffman alphabet */
+       if ( ( rc = huffman_alphabet ( alphabet, lengths, count ) ) != 0 )
+               return rc;
+
+       return 0;
+}
+
+/**
+ * Generate pretree
+ *
+ * @v lzx              Decompressor
+ * @v count            Number of symbols
+ * @v lengths          Lengths table to fill in
+ * @ret rc             Return status code
+ */
+static int lzx_pretree ( struct lzx *lzx, unsigned int count,
+                        uint8_t *lengths ) {
+       unsigned int i;
+       unsigned int length;
+       int dup = 0;
+       int code;
+       int rc;
+
+       /* Generate pretree alphabet */
+       if ( ( rc =  lzx_raw_alphabet ( lzx, LZX_PRETREE_CODES,
+                                       LZX_PRETREE_BITS, lzx->pretree_lengths,
+                                       &lzx->pretree ) ) != 0 )
+               return rc;
+
+       /* Read lengths */
+       for ( i = 0 ; i < count ; i++ ) {
+
+               if ( dup ) {
+
+                       /* Duplicate previous length */
+                       lengths[i] = lengths[ i - 1 ];
+                       dup--;
+
+               } else {
+
+                       /* Get next code */
+                       code = lzx_decode ( lzx, &lzx->pretree );
+                       if ( code < 0 )
+                               return code;
+
+                       /* Interpret code */
+                       if ( code <= 16 ) {
+                               length = ( ( lengths[i] - code + 17 ) % 17 );
+                       } else if ( code == 17 ) {
+                               length = 0;
+                               dup = lzx_getbits ( lzx, 4 );
+                               if ( dup < 0 )
+                                       return dup;
+                               dup += 3;
+                       } else if ( code == 18 ) {
+                               length = 0;
+                               dup = lzx_getbits ( lzx, 5 );
+                               if ( dup < 0 )
+                                       return dup;
+                               dup += 19;
+                       } else if ( code == 19 ) {
+                               length = 0;
+                               dup = lzx_getbits ( lzx, 1 );
+                               if ( dup < 0 )
+                                       return dup;
+                               dup += 3;
+                               code = lzx_decode ( lzx, &lzx->pretree );
+                               if ( code < 0 )
+                                       return code;
+                               length = ( ( lengths[i] - code + 17 ) % 17 );
+                       } else {
+                               DBG ( "Unrecognised pretree code %d\n", code );
+                               return -1;
+                       }
+                       lengths[i] = length;
+               }
+       }
+
+       /* Sanity check */
+       if ( dup ) {
+               DBG ( "Pretree duplicate overrun\n" );
+               return -1;
+       }
+
+       return 0;
+}
+
+/**
+ * Generate aligned offset Huffman alphabet
+ *
+ * @v lzx              Decompressor
+ * @ret rc             Return status code
+ */
+static int lzx_alignoffset_alphabet ( struct lzx *lzx ) {
+       int rc;
+
+       /* Generate aligned offset alphabet */
+       if ( ( rc = lzx_raw_alphabet ( lzx, LZX_ALIGNOFFSET_CODES,
+                                      LZX_ALIGNOFFSET_BITS,
+                                      lzx->alignoffset_lengths,
+                                      &lzx->alignoffset ) ) != 0 )
+               return rc;
+
+       return 0;
+}
+
+/**
+ * Generate main Huffman alphabet
+ *
+ * @v lzx              Decompressor
+ * @ret rc             Return status code
+ */
+static int lzx_main_alphabet ( struct lzx *lzx ) {
+       int rc;
+
+       /* Generate literal symbols pretree */
+       if ( ( rc = lzx_pretree ( lzx, LZX_MAIN_LIT_CODES,
+                                 lzx->main_lengths.literals ) ) != 0 ) {
+               DBG ( "Could not construct main literal pretree\n" );
+               return rc;
+       }
+
+       /* Generate remaining symbols pretree */
+       if ( ( rc = lzx_pretree ( lzx, ( LZX_MAIN_CODES - LZX_MAIN_LIT_CODES ),
+                                 lzx->main_lengths.remainder ) ) != 0 ) {
+               DBG ( "Could not construct main remainder pretree\n" );
+               return rc;
+       }
+
+       /* Generate Huffman alphabet */
+       if ( ( rc = huffman_alphabet ( &lzx->main, lzx->main_lengths.literals,
+                                      LZX_MAIN_CODES ) ) != 0 ) {
+               DBG ( "Could not generate main alphabet\n" );
+               return rc;
+       }
+
+       return 0;
+}
+
+/**
+ * Generate length Huffman alphabet
+ *
+ * @v lzx              Decompressor
+ * @ret rc             Return status code
+ */
+static int lzx_length_alphabet ( struct lzx *lzx ) {
+       int rc;
+
+       /* Generate pretree */
+       if ( ( rc = lzx_pretree ( lzx, LZX_LENGTH_CODES,
+                                 lzx->length_lengths ) ) != 0 ) {
+               DBG ( "Could not generate length pretree\n" );
+               return rc;
+       }
+
+       /* Generate Huffman alphabet */
+       if ( ( rc = huffman_alphabet ( &lzx->length, lzx->length_lengths,
+                                      LZX_LENGTH_CODES ) ) != 0 ) {
+               DBG ( "Could not generate length alphabet\n" );
+               return rc;
+       }
+
+       return 0;
+}
+
+/**
+ * Process LZX block header
+ *
+ * @v lzx              Decompressor
+ * @ret rc             Return status code
+ */
+static int lzx_block_header ( struct lzx *lzx ) {
+       size_t block_len;
+       int block_type;
+       int default_len;
+       int len_high;
+       int len_low;
+       int rc;
+
+       /* Get block type */
+       block_type = lzx_getbits ( lzx, LZX_BLOCK_TYPE_BITS );
+       if ( block_type < 0 )
+               return block_type;
+       lzx->block_type = block_type;
+
+       /* Check block length */
+       default_len = lzx_getbits ( lzx, 1 );
+       if ( default_len < 0 )
+               return default_len;
+       if ( default_len ) {
+               block_len = LZX_DEFAULT_BLOCK_LEN;
+       } else {
+               len_high = lzx_getbits ( lzx, 8 );
+               if ( len_high < 0 )
+                       return len_high;
+               len_low = lzx_getbits ( lzx, 8 );
+               if ( len_low < 0 )
+                       return len_low;
+               block_len = ( ( len_high << 8 ) | len_low );
+       }
+       lzx->output.threshold = ( lzx->output.offset + block_len );
+
+       /* Handle block type */
+       switch ( block_type ) {
+       case LZX_BLOCK_ALIGNOFFSET :
+               /* Generated aligned offset alphabet */
+               if ( ( rc = lzx_alignoffset_alphabet ( lzx ) ) != 0 )
+                       return rc;
+               /* Fall through */
+       case LZX_BLOCK_VERBATIM :
+               /* Generate main alphabet */
+               if ( ( rc = lzx_main_alphabet ( lzx ) ) != 0 )
+                       return rc;
+               /* Generate lengths alphabet */
+               if ( ( rc = lzx_length_alphabet ( lzx ) ) != 0 )
+                       return rc;
+               break;
+       case LZX_BLOCK_UNCOMPRESSED :
+               /* Align input stream */
+               if ( ( rc = lzx_align ( lzx, 1 ) ) != 0 )
+                       return rc;
+               /* Read new repeated offsets */
+               if ( ( rc = lzx_getbytes ( lzx, &lzx->repeated_offset,
+                                          sizeof ( lzx->repeated_offset )))!=0)
+                       return rc;
+               break;
+       default:
+               DBG ( "Unrecognised block type %d\n", block_type );
+               return -1;
+       }
+
+       return 0;
+}
+
+/**
+ * Process uncompressed data
+ *
+ * @v lzx              Decompressor
+ * @ret rc             Return status code
+ */
+static int lzx_uncompressed ( struct lzx *lzx ) {
+       void *data;
+       size_t len;
+       int rc;
+
+       /* Copy bytes */
+       data = ( lzx->output.data ?
+                ( lzx->output.data + lzx->output.offset ) : NULL );
+       len = ( lzx->output.threshold - lzx->output.offset );
+       if ( ( rc = lzx_getbytes ( lzx, data, len ) ) != 0 )
+               return rc;
+
+       /* Align input stream */
+       if ( len % 2 )
+               lzx->input.offset++;
+
+       return 0;
+}
+
+/**
+ * Process an LZX token
+ *
+ * @v lzx              Decompressor
+ * @ret rc             Return status code
+ *
+ * Variable names are chosen to match the LZX specification
+ * pseudo-code.
+ */
+static int lzx_token ( struct lzx *lzx ) {
+       unsigned int length_header;
+       unsigned int position_slot;
+       unsigned int offset_bits;
+       unsigned int i;
+       size_t match_offset;
+       size_t match_length;
+       int verbatim_bits;
+       int aligned_bits;
+       int main;
+       int length;
+       uint8_t *copy;
+
+       /* Get main symelse*/
+       main = lzx_decode ( lzx, &lzx->main );
+       if ( main < 0 )
+               return main;
+
+       /* Check for literals */
+       if ( main < LZX_MAIN_LIT_CODES ) {
+               if ( lzx->output.data )
+                       lzx->output.data[lzx->output.offset] = main;
+               lzx->output.offset++;
+               return 0;
+       }
+       main -= LZX_MAIN_LIT_CODES;
+
+       /* Calculate the match length */
+       length_header = ( main & 7 );
+       if ( length_header == 7 ) {
+               length = lzx_decode ( lzx, &lzx->length );
+               if ( length < 0 )
+                       return length;
+       } else {
+               length = 0;
+       }
+       match_length = ( length_header + 2 + length );
+
+       /* Calculate the position slot */
+       position_slot = ( main >> 3 );
+       if ( position_slot < LZX_REPEATED_OFFSETS ) {
+
+               /* Repeated offset */
+               match_offset = lzx->repeated_offset[position_slot];
+               lzx->repeated_offset[position_slot] = lzx->repeated_offset[0];
+               lzx->repeated_offset[0] = match_offset;
+
+       } else {
+
+               /* Non-repeated offset */
+               offset_bits = lzx_footer_bits ( position_slot );
+               if ( ( lzx->block_type == LZX_BLOCK_ALIGNOFFSET ) &&
+                    ( offset_bits >= 3 ) ) {
+                       verbatim_bits = lzx_getbits ( lzx, ( offset_bits - 3 ));
+                       if ( verbatim_bits < 0 )
+                               return verbatim_bits;
+                       verbatim_bits <<= 3;
+                       aligned_bits = lzx_decode ( lzx, &lzx->alignoffset );
+                       if ( aligned_bits < 0 )
+                               return aligned_bits;
+               } else {
+                       verbatim_bits = lzx_getbits ( lzx, offset_bits );
+                       if ( verbatim_bits < 0 )
+                               return verbatim_bits;
+                       aligned_bits = 0;
+               }
+               match_offset = ( lzx_position_base[position_slot] +
+                                verbatim_bits + aligned_bits - 2 );
+
+               /* Update repeated offset list */
+               for ( i = ( LZX_REPEATED_OFFSETS - 1 ) ; i > 0 ; i-- )
+                       lzx->repeated_offset[i] = lzx->repeated_offset[ i - 1 ];
+               lzx->repeated_offset[0] = match_offset;
+       }
+
+       /* Copy data */
+       if ( match_offset > lzx->output.offset ) {
+               DBG ( "LZX match underrun out %#zx offset %#zx len %#zx\n",
+                     lzx->output.offset, match_offset, match_length );
+               return -1;
+       }
+       if ( lzx->output.data ) {
+               copy = &lzx->output.data[lzx->output.offset];
+               for ( i = 0 ; i < match_length ; i++ )
+                       copy[i] = copy[ i - match_offset ];
+       }
+       lzx->output.offset += match_length;
+
+       return 0;
+}
+
+/**
+ * Translate E8 jump addresses
+ *
+ * @v lzx              Decompressor
+ */
+static void lzx_translate_jumps ( struct lzx *lzx ) {
+       size_t offset;
+       int32_t *target;
+
+       /* Sanity check */
+       if ( lzx->output.offset < 10 )
+               return;
+
+       /* Scan for jump instructions */
+       for ( offset = 0 ; offset < ( lzx->output.offset - 10 ) ; offset++ ) {
+
+               /* Check for jump instruction */
+               if ( lzx->output.data[offset] != 0xe8 )
+                       continue;
+
+               /* Translate jump target */
+               target = ( ( int32_t * ) &lzx->output.data[ offset + 1 ] );
+               if ( *target >= 0 ) {
+                       if ( *target < LZX_WIM_MAGIC_FILESIZE )
+                               *target -= offset;
+               } else {
+                       if ( *target >= -( ( int32_t ) offset ) )
+                               *target += LZX_WIM_MAGIC_FILESIZE;
+               }
+               offset += sizeof ( *target );
+       }
+}
+
+/**
+ * Decompress LZX-compressed data
+ *
+ * @v data             Compressed data
+ * @v len              Length of compressed data
+ * @v buf              Decompression buffer, or NULL
+ * @ret out_len                Length of decompressed data, or negative error
+ */
+ssize_t lzx_decompress ( const void *data, size_t len, void *buf ) {
+       struct lzx lzx;
+       unsigned int i;
+       int rc;
+
+       /* Sanity check */
+       if ( len % 2 ) {
+               DBG ( "LZX cannot handle odd-length input data\n" );
+               return -1;
+       }
+
+       /* Initialise global state, if required */
+       if ( ! lzx_position_base[ LZX_POSITION_SLOTS - 1 ] ) {
+               for ( i = 1 ; i < LZX_POSITION_SLOTS ; i++ ) {
+                       lzx_position_base[i] =
+                               ( lzx_position_base[i-1] +
+                                 ( 1 << lzx_footer_bits ( i - 1 ) ) );
+               }
+       }
+
+       /* Initialise decompressor */
+       memset ( &lzx, 0, sizeof ( lzx ) );
+       lzx.input.data = data;
+       lzx.input.len = len;
+       lzx.output.data = buf;
+       for ( i = 0 ; i < LZX_REPEATED_OFFSETS ; i++ )
+               lzx.repeated_offset[i] = 1;
+
+       /* Process blocks */
+       while ( lzx.input.offset < lzx.input.len ) {
+
+               /* Process block header */
+               if ( ( rc = lzx_block_header ( &lzx ) ) != 0 )
+                       return rc;
+
+               /* Process block contents */
+               if ( lzx.block_type == LZX_BLOCK_UNCOMPRESSED ) {
+
+                       /* Copy uncompressed data */
+                       if ( ( rc = lzx_uncompressed ( &lzx ) ) != 0 )
+                               return rc;
+
+               } else {
+
+                       /* Process token stream */
+                       while ( lzx.output.offset < lzx.output.threshold ) {
+                               if ( ( rc = lzx_token ( &lzx ) ) != 0 )
+                                       return rc;
+                       }
+               }
+       }
+
+       /* Postprocess to undo E8 jump compression */
+       if ( lzx.output.data )
+               lzx_translate_jumps ( &lzx );
+
+       return lzx.output.offset;
+}
diff --git a/wimboot/wimboot-2.7.3/src/lzx.h b/wimboot/wimboot-2.7.3/src/lzx.h
new file mode 100644 (file)
index 0000000..9913f12
--- /dev/null
@@ -0,0 +1,180 @@
+#ifndef _LZX_H
+#define _LZX_H
+
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * LZX decompression
+ *
+ */
+
+#include <stdint.h>
+#include "huffman.h"
+
+/** Number of aligned offset codes */
+#define LZX_ALIGNOFFSET_CODES 8
+
+/** Aligned offset code length (in bits) */
+#define LZX_ALIGNOFFSET_BITS 3
+
+/** Number of pretree codes */
+#define LZX_PRETREE_CODES 20
+
+/** Pretree code length (in bits) */
+#define LZX_PRETREE_BITS 4
+
+/** Number of literal main codes */
+#define LZX_MAIN_LIT_CODES 256
+
+/** Number of position slots */
+#define LZX_POSITION_SLOTS 30
+
+/** Number of main codes */
+#define LZX_MAIN_CODES ( LZX_MAIN_LIT_CODES + ( 8 * LZX_POSITION_SLOTS ) )
+
+/** Number of length codes */
+#define LZX_LENGTH_CODES 249
+
+/** Block type length (in bits) */
+#define LZX_BLOCK_TYPE_BITS 3
+
+/** Default block length */
+#define LZX_DEFAULT_BLOCK_LEN 32768
+
+/** Number of repeated offsets */
+#define LZX_REPEATED_OFFSETS 3
+
+/** Don't ask */
+#define LZX_WIM_MAGIC_FILESIZE 12000000
+
+/** Block types */
+enum lzx_block_type {
+       /** Verbatim block */
+       LZX_BLOCK_VERBATIM = 1,
+       /** Aligned offset block */
+       LZX_BLOCK_ALIGNOFFSET = 2,
+       /** Uncompressed block */
+       LZX_BLOCK_UNCOMPRESSED = 3,
+};
+
+/** An LZX input stream */
+struct lzx_input_stream {
+       /** Data */
+       const uint8_t *data;
+       /** Length */
+       size_t len;
+       /** Offset within stream */
+       size_t offset;
+};
+
+/** An LZX output stream */
+struct lzx_output_stream {
+       /** Data, or NULL */
+       uint8_t *data;
+       /** Offset within stream */
+       size_t offset;
+       /** End of current block within stream */
+       size_t threshold;
+};
+
+/** LZX decompressor */
+struct lzx {
+       /** Input stream */
+       struct lzx_input_stream input;
+       /** Output stream */
+       struct lzx_output_stream output;
+       /** Accumulator */
+       uint32_t accumulator;
+       /** Number of bits in accumulator */
+       unsigned int bits;
+       /** Block type */
+       enum lzx_block_type block_type;
+       /** Repeated offsets */
+       unsigned int repeated_offset[LZX_REPEATED_OFFSETS];
+
+       /** Aligned offset Huffman alphabet */
+       struct huffman_alphabet alignoffset;
+       /** Aligned offset raw symbols
+        *
+        * Must immediately follow the aligned offset Huffman
+        * alphabet.
+        */
+       huffman_raw_symbol_t alignoffset_raw[LZX_ALIGNOFFSET_CODES];
+       /** Aligned offset code lengths */
+       uint8_t alignoffset_lengths[LZX_ALIGNOFFSET_CODES];
+
+       /** Pretree Huffman alphabet */
+       struct huffman_alphabet pretree;
+       /** Pretree raw symbols
+        *
+        * Must immediately follow the pretree Huffman alphabet.
+        */
+       huffman_raw_symbol_t pretree_raw[LZX_PRETREE_CODES];
+       /** Preetree code lengths */
+       uint8_t pretree_lengths[LZX_PRETREE_CODES];
+
+       /** Main Huffman alphabet */
+       struct huffman_alphabet main;
+       /** Main raw symbols
+        *
+        * Must immediately follow the main Huffman alphabet.
+        */
+       huffman_raw_symbol_t main_raw[LZX_MAIN_CODES];
+       /** Main code lengths */
+       struct {
+               /** Literals */
+               uint8_t literals[LZX_MAIN_LIT_CODES];
+               /** Remaining symbols */
+               uint8_t remainder[ LZX_MAIN_CODES - LZX_MAIN_LIT_CODES ];
+       } __attribute__ (( packed )) main_lengths;
+
+       /** Length Huffman alphabet */
+       struct huffman_alphabet length;
+       /** Length raw symbols
+        *
+        * Must immediately follow the length Huffman alphabet.
+        */
+       huffman_raw_symbol_t length_raw[LZX_LENGTH_CODES];
+       /** Length code lengths */
+       uint8_t length_lengths[LZX_LENGTH_CODES];
+};
+
+/**
+ * Calculate number of footer bits for a given position slot
+ *
+ * @v position_slot    Position slot
+ * @ret footer_bits    Number of footer bits
+ */
+static inline unsigned int lzx_footer_bits ( unsigned int position_slot ) {
+
+       if ( position_slot < 2 ) {
+               return 0;
+       } else if ( position_slot < 38 ) {
+               return ( ( position_slot / 2 ) - 1 );
+       } else {
+               return 17;
+       }
+}
+
+extern ssize_t lzx_decompress ( const void *data, size_t len, void *buf );
+
+#endif /* _LZX_H */
diff --git a/wimboot/wimboot-2.7.3/src/main.c b/wimboot/wimboot-2.7.3/src/main.c
new file mode 100644 (file)
index 0000000..f0ff381
--- /dev/null
@@ -0,0 +1,515 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Main entry point
+ *
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include "wimboot.h"
+#include "peloader.h"
+#include "int13.h"
+#include "vdisk.h"
+#include "cpio.h"
+#include "lznt1.h"
+#include "xca.h"
+#include "cmdline.h"
+#include "wimpatch.h"
+#include "wimfile.h"
+#include "pause.h"
+#include "paging.h"
+#include "memmap.h"
+
+/** Start of our image (defined by linker) */
+extern char _start[];
+
+/** End of our image (defined by linker) */
+extern char _end[];
+
+/** Command line */
+char *cmdline;
+
+/** initrd */
+void *initrd;
+
+/** Length of initrd */
+size_t initrd_len;
+
+/** bootmgr.exe path within WIM */
+static const wchar_t bootmgr_path[] = L"\\Windows\\Boot\\PXE\\bootmgr.exe";
+
+/** Other paths within WIM */
+static const wchar_t *wim_paths[] = {
+       L"\\Windows\\Boot\\DVD\\PCAT\\boot.sdi",
+       L"\\Windows\\Boot\\DVD\\PCAT\\BCD",
+       L"\\Windows\\Boot\\Fonts\\segmono_boot.ttf",
+       L"\\Windows\\Boot\\Fonts\\segoen_slboot.ttf",
+       L"\\Windows\\Boot\\Fonts\\segoe_slboot.ttf",
+       L"\\Windows\\Boot\\Fonts\\wgl4_boot.ttf",
+       L"\\sms\\boot\\boot.sdi",
+       NULL
+};
+
+/** bootmgr.exe file */
+static struct vdisk_file *bootmgr;
+
+/** WIM image file */
+static struct vdisk_file *bootwim;
+
+/** Minimal length of embedded bootmgr.exe */
+#define BOOTMGR_MIN_LEN 16384
+
+/** 1MB memory threshold */
+#define ADDR_1MB 0x00100000
+
+/** 2GB memory threshold */
+#define ADDR_2GB 0x80000000
+
+/** Memory regions */
+enum {
+       WIMBOOT_REGION = 0,
+       PE_REGION,
+       INITRD_REGION,
+       NUM_REGIONS
+};
+
+/**
+ * Wrap interrupt callback
+ *
+ * @v params           Parameters
+ */
+static void call_interrupt_wrapper ( struct bootapp_callback_params *params ) {
+       struct paging_state state;
+       uint16_t *attributes;
+
+       /* Handle/modify/pass-through interrupt as required */
+       if ( params->vector.interrupt == 0x13 ) {
+
+               /* Enable paging */
+               enable_paging ( &state );
+
+               /* Intercept INT 13 calls for the emulated drive */
+               emulate_int13 ( params );
+
+               /* Disable paging */
+               disable_paging ( &state );
+
+       } else if ( ( params->vector.interrupt == 0x10 ) &&
+                   ( params->ax == 0x4f01 ) &&
+                   ( ! cmdline_gui ) ) {
+
+               /* Mark all VESA video modes as unsupported */
+               attributes = REAL_PTR ( params->es, params->di );
+               call_interrupt ( params );
+               *attributes &= ~0x0001;
+
+       } else {
+
+               /* Pass through interrupt */
+               call_interrupt ( params );
+       }
+}
+
+/** Real-mode callback functions */
+static struct bootapp_callback_functions callback_fns = {
+       .call_interrupt = call_interrupt_wrapper,
+       .call_real = call_real,
+};
+
+/** Real-mode callbacks */
+static struct bootapp_callback callback = {
+       .fns = &callback_fns,
+};
+
+/** Boot application descriptor set */
+static struct {
+       /** Boot application descriptor */
+       struct bootapp_descriptor bootapp;
+       /** Boot application memory descriptor */
+       struct bootapp_memory_descriptor memory;
+       /** Boot application memory descriptor regions */
+       struct bootapp_memory_region regions[NUM_REGIONS];
+       /** Boot application entry descriptor */
+       struct bootapp_entry_descriptor entry;
+       struct bootapp_entry_wtf1_descriptor wtf1;
+       struct bootapp_entry_wtf2_descriptor wtf2;
+       struct bootapp_entry_wtf3_descriptor wtf3;
+       struct bootapp_entry_wtf3_descriptor wtf3_copy;
+       /** Boot application callback descriptor */
+       struct bootapp_callback_descriptor callback;
+       /** Boot application pointless descriptor */
+       struct bootapp_pointless_descriptor pointless;
+} __attribute__ (( packed )) bootapps = {
+       .bootapp = {
+               .signature = BOOTAPP_SIGNATURE,
+               .version = BOOTAPP_VERSION,
+               .len = sizeof ( bootapps ),
+               .arch = BOOTAPP_ARCH_I386,
+               .memory = offsetof ( typeof ( bootapps ), memory ),
+               .entry = offsetof ( typeof ( bootapps ), entry ),
+               .xxx = offsetof ( typeof ( bootapps ), wtf3_copy ),
+               .callback = offsetof ( typeof ( bootapps ), callback ),
+               .pointless = offsetof ( typeof ( bootapps ), pointless ),
+       },
+       .memory = {
+               .version = BOOTAPP_MEMORY_VERSION,
+               .len = sizeof ( bootapps.memory ),
+               .num_regions = NUM_REGIONS,
+               .region_len = sizeof ( bootapps.regions[0] ),
+               .reserved_len = sizeof ( bootapps.regions[0].reserved ),
+       },
+       .entry = {
+               .signature = BOOTAPP_ENTRY_SIGNATURE,
+               .flags = BOOTAPP_ENTRY_FLAGS,
+       },
+       .wtf1 = {
+               .flags = 0x11000001,
+               .len = sizeof ( bootapps.wtf1 ),
+               .extra_len = ( sizeof ( bootapps.wtf2 ) +
+                              sizeof ( bootapps.wtf3 ) ),
+       },
+       .wtf3 = {
+               .flags = 0x00000006,
+               .len = sizeof ( bootapps.wtf3 ),
+               .boot_partition_offset = ( VDISK_VBR_LBA * VDISK_SECTOR_SIZE ),
+               .xxx = 0x01,
+               .mbr_signature = VDISK_MBR_SIGNATURE,
+       },
+       .wtf3_copy = {
+               .flags = 0x00000006,
+               .len = sizeof ( bootapps.wtf3 ),
+               .boot_partition_offset = ( VDISK_VBR_LBA * VDISK_SECTOR_SIZE ),
+               .xxx = 0x01,
+               .mbr_signature = VDISK_MBR_SIGNATURE,
+       },
+       .callback = {
+               .callback = &callback,
+       },
+       .pointless = {
+               .version = BOOTAPP_POINTLESS_VERSION,
+       },
+};
+
+/**
+ * Test if a paragraph is empty
+ *
+ * @v pgh              Paragraph
+ * @ret is_empty       Paragraph is empty (all zeroes)
+ */
+static int is_empty_pgh ( const void *pgh ) {
+       const uint32_t *dwords = pgh;
+
+       return ( ( dwords[0] | dwords[1] | dwords[2] | dwords[3] ) == 0 );
+}
+
+/**
+ * Read from file
+ *
+ * @v file             Virtual file
+ * @v data             Data buffer
+ * @v offset           Offset
+ * @v len              Length
+ */
+static void read_file ( struct vdisk_file *file, void *data, size_t offset,
+                       size_t len ) {
+
+       memcpy ( data, ( file->opaque + offset ), len );
+}
+
+/**
+ * Add embedded bootmgr.exe extracted from bootmgr
+ *
+ * @v data             File data
+ * @v len              Length
+ * @ret file           Virtual file, or NULL
+ *
+ * bootmgr.exe is awkward to obtain, since it is not available as a
+ * standalone file on the installation media, or on an installed
+ * system, or in a Windows PE image as created by WAIK or WADK.  It
+ * can be extracted from a typical boot.wim image using ImageX, but
+ * this requires installation of the WAIK/WADK/wimlib.
+ *
+ * A compressed version of bootmgr.exe is contained within bootmgr,
+ * which is trivial to obtain.
+ */
+static struct vdisk_file * add_bootmgr ( const void *data, size_t len ) {
+       const uint8_t *compressed;
+       size_t offset;
+       size_t compressed_len;
+       ssize_t ( * decompress ) ( const void *data, size_t len, void *buf );
+       ssize_t decompressed_len;
+       size_t padded_len;
+
+       /* Look for an embedded compressed bootmgr.exe on an
+        * eight-byte boundary.
+        */
+       for ( offset = BOOTMGR_MIN_LEN ; offset < ( len - BOOTMGR_MIN_LEN ) ;
+             offset += 0x08 ) {
+
+               /* Initialise checks */
+               decompress = NULL;
+               compressed = ( data + offset );
+               compressed_len = ( len - offset );
+
+               /* Check for an embedded LZNT1-compressed bootmgr.exe.
+                * Since there is no way for LZNT1 to compress the
+                * initial "MZ" bytes of bootmgr.exe, we look for this
+                * signature starting three bytes after a paragraph
+                * boundary, with a preceding tag byte indicating that
+                * these two bytes would indeed be uncompressed.
+                */
+               if ( ( ( offset & 0x0f ) == 0x00 ) &&
+                    ( ( compressed[0x02] & 0x03 ) == 0x00 ) &&
+                    ( compressed[0x03] == 'M' ) &&
+                    ( compressed[0x04] == 'Z' ) ) {
+                       DBG ( "...checking for LZNT1-compressed bootmgr.exe at "
+                             "+%#zx\n", offset );
+                       decompress = lznt1_decompress;
+               }
+
+               /* Check for an embedded XCA-compressed bootmgr.exe.
+                * The bytes 0x00, 'M', and 'Z' will always be
+                * present, and so the corresponding symbols must have
+                * a non-zero Huffman length.  The embedded image
+                * tends to have a large block of zeroes immediately
+                * beforehand, which we check for.  It's implausible
+                * that the compressed data could contain substantial
+                * runs of zeroes, so we check for that too, in order
+                * to eliminate some common false positive matches.
+                */
+               if ( ( ( compressed[0x00] & 0x0f ) != 0x00 ) &&
+                    ( ( compressed[0x26] & 0xf0 ) != 0x00 ) &&
+                    ( ( compressed[0x2d] & 0x0f ) != 0x00 ) &&
+                    ( is_empty_pgh ( compressed - 0x10 ) ) &&
+                    ( ! is_empty_pgh ( ( compressed + 0x400 ) ) ) &&
+                    ( ! is_empty_pgh ( ( compressed + 0x800 ) ) ) &&
+                    ( ! is_empty_pgh ( ( compressed + 0xc00 ) ) ) ) {
+                       DBG ( "...checking for XCA-compressed bootmgr.exe at "
+                             "+%#zx\n", offset );
+                       decompress = xca_decompress;
+               }
+
+               /* If we have not found a possible bootmgr.exe, skip
+                * to the next offset.
+                */
+               if ( ! decompress )
+                       continue;
+
+               /* Find length of decompressed image */
+               decompressed_len = decompress ( compressed, compressed_len,
+                                               NULL );
+               if ( decompressed_len < 0 ) {
+                       /* May be a false positive signature match */
+                       continue;
+               }
+
+               /* Prepend decompressed image to initrd */
+               DBG ( "...extracting embedded bootmgr.exe\n" );
+               padded_len = ( ( decompressed_len + PAGE_SIZE - 1 ) &
+                              ~( PAGE_SIZE - 1 ) );
+               initrd -= padded_len;
+               initrd_len += padded_len;
+               decompress ( compressed, compressed_len, initrd );
+
+               /* Add decompressed image */
+               return vdisk_add_file ( "bootmgr.exe", initrd,
+                                       decompressed_len, read_file );
+       }
+
+       DBG ( "...no embedded bootmgr.exe found\n" );
+       return NULL;
+}
+
+/**
+ * File handler
+ *
+ * @v name             File name
+ * @v data             File data
+ * @v len              Length
+ * @ret rc             Return status code
+ */
+static int add_file ( const char *name, void *data, size_t len ) {
+       struct vdisk_file *file;
+
+       /* Store file */
+       file = vdisk_add_file ( name, data, len, read_file );
+
+       /* Check for special-case files */
+       if ( strcasecmp ( name, "bootmgr.exe" ) == 0 ) {
+               DBG ( "...found bootmgr.exe\n" );
+               bootmgr = file;
+       } else if ( strcasecmp ( name, "bootmgr" ) == 0 ) {
+               DBG ( "...found bootmgr\n" );
+               if ( ( ! bootmgr ) &&
+                    ( bootmgr = add_bootmgr ( data, len ) ) ) {
+                       DBG ( "...extracted bootmgr.exe\n" );
+               }
+       } else if ( strcasecmp ( ( name + strlen ( name ) - 4 ),
+                                ".wim" ) == 0 ) {
+               DBG ( "...found WIM file %s\n", name );
+               bootwim = file;
+       }
+
+       return 0;
+}
+
+/**
+ * Relocate data between 1MB and 2GB if possible
+ *
+ * @v data             Start of data
+ * @v len              Length of data
+ * @ret start          Start address
+ */
+static void * relocate_memory_low ( void *data, size_t len ) {
+       struct e820_entry *e820 = NULL;
+       uint64_t end;
+       intptr_t start;
+
+       /* Read system memory map */
+       while ( ( e820 = memmap_next ( e820 ) ) != NULL ) {
+
+               /* Find highest compatible placement within this region */
+               end = ( e820->start + e820->len );
+               start = ( ( end > ADDR_2GB ) ? ADDR_2GB : end );
+               if ( start < len )
+                       continue;
+               start -= len;
+               start &= ~( PAGE_SIZE - 1 );
+               if ( start < e820->start )
+                       continue;
+               if ( start < ADDR_1MB )
+                       continue;
+
+               /* Relocate to this region */
+               memmove ( ( void * ) start, data, len );
+               return ( ( void * ) start );
+       }
+
+       /* Leave at original location */
+       return data;
+}
+
+/**
+ * Main entry point
+ *
+ */
+int main ( void ) {
+       size_t padded_len;
+       void *raw_pe;
+       struct loaded_pe pe;
+       struct paging_state state;
+       uint64_t initrd_phys;
+
+       /* Initialise stack cookie */
+       init_cookie();
+
+       /* Print welcome banner */
+    printf ( "\n\nBooting wim file...... (This may take a few minutes, please wait)\n\n");
+       //printf ( "\n\nwimboot " VERSION " -- Windows Imaging Format "
+       //       "bootloader -- https://ipxe.org/wimboot\n\n" );
+
+       /* Process command line */
+       process_cmdline ( cmdline );
+
+       /* Initialise paging */
+       init_paging();
+
+       /* Enable paging */
+       enable_paging ( &state );
+
+       /* Relocate initrd below 2GB if possible, to avoid collisions */
+       DBG ( "Found initrd at [%p,%p)\n", initrd, ( initrd + initrd_len ) );
+       initrd = relocate_memory_low ( initrd, initrd_len );
+       DBG ( "Placing initrd at [%p,%p)\n", initrd, ( initrd + initrd_len ) );
+
+       /* Extract files from initrd */
+       if ( cpio_extract ( initrd, initrd_len, add_file ) != 0 )
+               die ( "FATAL: could not extract initrd files\n" );
+
+       /* Process WIM image */
+       if ( bootwim ) {
+               vdisk_patch_file ( bootwim, patch_wim );
+               if ( ( ! bootmgr ) &&
+                    ( bootmgr = wim_add_file ( bootwim, cmdline_index,
+                                               bootmgr_path,
+                                               L"bootmgr.exe" ) ) ) {
+                       DBG ( "...extracted bootmgr.exe\n" );
+               }
+               wim_add_files ( bootwim, cmdline_index, wim_paths );
+       }
+
+       /* Add INT 13 drive */
+       callback.drive = initialise_int13();
+
+       /* Read bootmgr.exe into memory */
+       if ( ! bootmgr )
+               die ( "FATAL: no bootmgr.exe\n" );
+       if ( bootmgr->read == read_file ) {
+               raw_pe = bootmgr->opaque;
+       } else {
+               padded_len = ( ( bootmgr->len + PAGE_SIZE - 1 ) &
+                              ~( PAGE_SIZE -1 ) );
+               raw_pe = ( initrd - padded_len );
+               bootmgr->read ( bootmgr, raw_pe, 0, bootmgr->len );
+       }
+
+       /* Load bootmgr.exe into memory */
+       if ( load_pe ( raw_pe, bootmgr->len, &pe ) != 0 )
+               die ( "FATAL: Could not load bootmgr.exe\n" );
+
+       /* Relocate initrd above 4GB if possible, to free up 32-bit memory */
+       initrd_phys = relocate_memory_high ( initrd, initrd_len );
+       DBG ( "Placing initrd at physical [%#llx,%#llx)\n",
+             initrd_phys, ( initrd_phys + initrd_len ) );
+
+       /* Complete boot application descriptor set */
+       bootapps.bootapp.pe_base = pe.base;
+       bootapps.bootapp.pe_len = pe.len;
+       bootapps.regions[WIMBOOT_REGION].start_page = page_start ( _start );
+       bootapps.regions[WIMBOOT_REGION].num_pages = page_len ( _start, _end );
+       bootapps.regions[PE_REGION].start_page = page_start ( pe.base );
+       bootapps.regions[PE_REGION].num_pages =
+               page_len ( pe.base, ( pe.base + pe.len ) );
+       bootapps.regions[INITRD_REGION].start_page =
+               ( initrd_phys / PAGE_SIZE );
+       bootapps.regions[INITRD_REGION].num_pages =
+               page_len ( initrd, initrd + initrd_len );
+
+       /* Omit initrd region descriptor if located above 4GB */
+       if ( initrd_phys >= ADDR_4GB )
+               bootapps.memory.num_regions--;
+
+       /* Disable paging */
+       disable_paging ( &state );
+
+       /* Jump to PE image */
+       DBG ( "Entering bootmgr.exe with parameters at %p\n", &bootapps );
+       if ( cmdline_pause )
+               pause();
+       pe.entry ( &bootapps.bootapp );
+       die ( "FATAL: bootmgr.exe returned\n" );
+}
diff --git a/wimboot/wimboot-2.7.3/src/memmap.c b/wimboot/wimboot-2.7.3/src/memmap.c
new file mode 100644 (file)
index 0000000..e7ef8a9
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Memory map
+ *
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include "wimboot.h"
+#include "memmap.h"
+
+/** Buffer for INT 15,e820 calls */
+static struct e820_entry e820_buf __attribute__ (( section ( ".bss16" ) ));
+
+/** Continuation value for next INT 15,e820 call */
+static uint32_t e820_ebx;
+
+/**
+ * Get system memory map entry
+ *
+ * @v prev             Previous system memory map entry, or NULL at start
+ * @v next             Next system memory map entry, or NULL at end
+ */
+struct e820_entry * memmap_next ( struct e820_entry *prev ) {
+       struct bootapp_callback_params params;
+
+       /* Reset buffer and continuation value if restarting */
+       if ( ! prev ) {
+               memset ( &e820_buf, 0, sizeof ( e820_buf ) );
+               e820_ebx = 0;
+       } else if ( e820_ebx == 0 ) {
+               /* Reach the end */
+               return NULL;
+       }
+
+       /* Read system memory map */
+       memset ( &params, 0, sizeof ( params ) );
+       do {
+
+               /* Call INT 15,e820 */
+               params.vector.interrupt = 0x15;
+               params.eax = 0xe820;
+               params.ebx = e820_ebx;
+               params.ecx = sizeof ( e820_buf );
+               params.edx = E820_SMAP;
+               params.es = BASE_SEG;
+               params.edi = ( ( ( void * ) &e820_buf ) -
+                              ( ( void * ) BASE_ADDRESS ) );
+               call_interrupt ( &params );
+
+               /* Record continuation value */
+               e820_ebx = params.ebx;
+
+               /* Check result */
+               if ( params.eflags & CF ) {
+                       DBG ( "INT 15,e820 failed: error %02x\n", params.ah );
+                       break;
+               }
+               if ( params.eax != E820_SMAP ) {
+                       DBG ( "INT 15,e820 invalid SMAP signature %08x\n",
+                             params.eax );
+                       break;
+               }
+               DBG2 ( "INT 15,e820 region [%llx,%llx) type %d\n",
+                      e820_buf.start, ( e820_buf.start + e820_buf.len ),
+                      e820_buf.type );
+
+               /* Skip non-RAM regions */
+               if ( e820_buf.type != E820_TYPE_RAM )
+                       continue;
+               if ( params.ecx > offsetof ( typeof ( e820_buf ), attrs ) ) {
+                       if ( ! ( e820_buf.attrs & E820_ATTR_ENABLED ) )
+                               continue;
+                       if ( e820_buf.attrs & E820_ATTR_NONVOLATILE )
+                               continue;
+               }
+
+               /* Return this region */
+               return &e820_buf;
+
+       } while ( e820_ebx != 0 );
+
+       return NULL;
+}
diff --git a/wimboot/wimboot-2.7.3/src/memmap.h b/wimboot/wimboot-2.7.3/src/memmap.h
new file mode 100644 (file)
index 0000000..30ecb8e
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef _MEMMAP_H
+#define _MEMMAP_H
+
+/*
+ * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Memory map
+ *
+ */
+
+#include <stdint.h>
+
+/** Magic value for INT 15,e820 calls */
+#define E820_SMAP 0x534d4150
+
+/** An INT 15,e820 memory map entry */
+struct e820_entry {
+       /** Start of region */
+       uint64_t start;
+       /** Length of region */
+       uint64_t len;
+       /** Type of region */
+       uint32_t type;
+       /** Extended attributes (optional) */
+       uint32_t attrs;
+} __attribute__ (( packed ));
+
+/** Normal RAM */
+#define E820_TYPE_RAM 1
+
+/** Region is enabled (if extended attributes are present) */
+#define E820_ATTR_ENABLED 0x00000001UL
+
+/** Region is non-volatile memory (if extended attributes are present) */
+#define E820_ATTR_NONVOLATILE 0x00000002UL
+
+extern struct e820_entry * memmap_next ( struct e820_entry *prev );
+
+#endif /* _MEMMAP_H */
diff --git a/wimboot/wimboot-2.7.3/src/paging.c b/wimboot/wimboot-2.7.3/src/paging.c
new file mode 100644 (file)
index 0000000..ba043af
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Paging
+ *
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "wimboot.h"
+#include "memmap.h"
+#include "paging.h"
+
+/** Virtual address used as a 2MB window during relocation */
+#define COPY_WINDOW 0x200000
+
+/** Paging is available */
+int paging;
+
+/** Page directory pointer table */
+static uint64_t pdpt[4] __attribute__ (( aligned ( PAGE_SIZE ) ));
+
+/** Page directories */
+static uint64_t pd[2048] __attribute__ (( aligned ( PAGE_SIZE ) ));
+
+/**
+ * Check that paging can be supported
+ *
+ * @ret supported      Paging can be supported on this CPU
+ */
+static int paging_supported ( void ) {
+       uint32_t eax;
+       uint32_t ebx;
+       uint32_t ecx;
+       uint32_t edx;
+
+       /* Get CPU features */
+       __asm__ ( "cpuid"
+                 : "=a" ( eax ), "=b" ( ebx ), "=c" ( ecx ), "=d" ( edx )
+                 : "0" ( CPUID_FEATURES ) );
+
+       return ( edx & CPUID_FEATURE_EDX_PAE );
+}
+
+/**
+ * Map 2MB page directory entry containing address
+ *
+ * @v vaddr            Virtual address
+ * @v paddr            Physical address
+ */
+static void map_page ( uint32_t vaddr, uint64_t paddr ) {
+       char *byte = ( ( char * ) ( intptr_t ) vaddr );
+       unsigned int index;
+
+       /* Sanity checks */
+       assert ( ( vaddr & ( PAGE_SIZE_2MB - 1 ) ) == 0 );
+       assert ( ( paddr & ( PAGE_SIZE_2MB - 1 ) ) == 0 );
+
+       /* Populate page directory entry */
+       index = ( vaddr / PAGE_SIZE_2MB );
+       pd[index] = ( paddr | PG_P | PG_RW | PG_US | PG_PS );
+
+       /* Invalidate TLB */
+       __asm__ __volatile__ ( "invlpg %0" : : "m" ( *byte ) );
+}
+
+/**
+ * Initialise paging
+ *
+ */
+void init_paging ( void ) {
+       uint32_t addr;
+       unsigned int i;
+
+       /* Do nothing if paging is disabled */
+       if ( cmdline_linear ) {
+               DBG ( "Paging disabled\n" );
+               return;
+       }
+
+       /* Check for PAE */
+       if ( ! paging_supported() ) {
+               DBG ( "Paging not possible on this CPU\n" );
+               return;
+       }
+
+       /* Initialise page directory entries */
+       addr = 0;
+       do {
+               map_page ( addr, addr );
+               addr += PAGE_SIZE_2MB;
+       } while ( addr );
+
+       /* Initialise page directory pointer table */
+       for ( i = 0 ; i < ( sizeof ( pdpt ) / sizeof ( pdpt[0] ) ) ; i++ ) {
+               addr = ( ( intptr_t ) &pd[ i * PAGE_SIZE / sizeof ( pd[0] ) ] );
+               pdpt[i] = ( addr | PG_P );
+       }
+
+       /* Mark paging as available */
+       paging = 1;
+}
+
+/**
+ * Enable paging
+ *
+ * @v state            Saved paging state to fill in
+ */
+void enable_paging ( struct paging_state *state ) {
+       unsigned long cr0;
+       unsigned long cr3;
+       unsigned long cr4;
+
+       /* Do nothing if paging is unavailable */
+       if ( ! paging )
+               return;
+
+       /* Save paging state */
+       __asm__ __volatile__ ( "mov %%cr0, %0\n\t"
+                              "mov %%cr3, %1\n\t"
+                              "mov %%cr4, %2\n\t"
+                              : "=r" ( cr0 ), "=r" ( cr3 ), "=r" ( cr4 ) );
+       state->cr0 = cr0;
+       state->cr3 = cr3;
+       state->cr4 = cr4;
+
+       /* Disable any existing paging */
+       __asm__ __volatile__ ( "mov %0, %%cr0" : : "r" ( cr0 & ~CR0_PG ) );
+
+       /* Enable PAE */
+       __asm__ __volatile__ ( "mov %0, %%cr4" : : "r" ( cr4 | CR4_PAE ) );
+
+       /* Load page directory pointer table */
+       __asm__ __volatile__ ( "mov %0, %%cr3" : : "r" ( pdpt ) );
+
+       /* Enable paging */
+       __asm__ __volatile__ ( "mov %0, %%cr0" : : "r" ( cr0 | CR0_PG ) );
+}
+
+/**
+ * Disable paging
+ *
+ * @v state            Previously saved paging state
+ */
+void disable_paging ( struct paging_state *state ) {
+       unsigned long cr0 = state->cr0;
+       unsigned long cr3 = state->cr3;
+       unsigned long cr4 = state->cr4;
+
+       /* Do nothing if paging is unavailable */
+       if ( ! paging )
+               return;
+
+       /* Disable paging */
+       __asm__ __volatile__ ( "mov %0, %%cr0" : : "r" ( cr0 & ~CR0_PG ) );
+
+       /* Restore saved paging state */
+       __asm__ __volatile__ ( "mov %2, %%cr4\n\t"
+                              "mov %1, %%cr3\n\t"
+                              "mov %0, %%cr0\n\t"
+                              : : "r" ( cr0 ), "r" ( cr3 ), "r" ( cr4 ) );
+}
+
+/**
+ * Relocate data out of 32-bit address space, if possible
+ *
+ * @v data             Start of data
+ * @v len              Length of data
+ * @ret start          Physical start address
+ */
+uint64_t relocate_memory_high ( void *data, size_t len ) {
+       intptr_t end = ( ( ( intptr_t ) data ) + len );
+       struct e820_entry *e820 = NULL;
+       uint64_t start;
+       uint64_t dest;
+       size_t offset;
+       size_t frag_len;
+
+       /* Do nothing if paging is unavailable */
+       if ( ! paging )
+               return ( ( intptr_t ) data );
+
+       /* Read system memory map */
+       while ( ( e820 = memmap_next ( e820 ) ) != NULL ) {
+
+               /* Find highest compatible placement within this region */
+               start = ( e820->start + e820->len );
+               if ( start < ADDR_4GB )
+                       continue;
+               start = ( ( ( start - end ) & ~( PAGE_SIZE_2MB - 1 ) ) + end );
+               start -= len;
+               if ( start < e820->start )
+                       continue;
+               if ( start < ADDR_4GB )
+                       continue;
+
+               /* Relocate to this region */
+               dest = start;
+               while ( len ) {
+
+                       /* Calculate length within this 2MB page */
+                       offset = ( ( ( intptr_t ) data ) &
+                                  ( PAGE_SIZE_2MB - 1 ) );
+                       frag_len = ( PAGE_SIZE_2MB - offset );
+                       if ( frag_len > len )
+                               frag_len = len;
+
+                       /* Map copy window to destination */
+                       map_page ( COPY_WINDOW,
+                                  ( dest & ~( PAGE_SIZE_2MB - 1 ) ) );
+
+                       /* Copy data through copy window */
+                       memcpy ( ( ( ( void * ) COPY_WINDOW ) + offset ),
+                                data, frag_len );
+
+                       /* Map original page to destination */
+                       map_page ( ( ( ( intptr_t ) data ) - offset ),
+                                  ( dest & ~( PAGE_SIZE_2MB - 1 ) ) );
+
+                       /* Move to next 2MB page */
+                       data += frag_len;
+                       dest += frag_len;
+                       len -= frag_len;
+               }
+
+               /* Remap copy window */
+               map_page ( COPY_WINDOW, COPY_WINDOW );
+
+               return start;
+       }
+
+       /* Leave at original location */
+       return ( ( intptr_t ) data );
+}
diff --git a/wimboot/wimboot-2.7.3/src/paging.h b/wimboot/wimboot-2.7.3/src/paging.h
new file mode 100644 (file)
index 0000000..8dbcfb7
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef _PAGING_H
+#define _PAGING_H
+
+/*
+ * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Paging
+ *
+ */
+
+#include <stddef.h>
+
+/** Get CPU features */
+#define CPUID_FEATURES 0x00000001
+
+/** CPU supports PAE */
+#define CPUID_FEATURE_EDX_PAE 0x00000040
+
+/* CR0: paging */
+#define CR0_PG 0x80000000
+
+/* CR4: physical address extensions */
+#define CR4_PAE 0x00000020
+
+/* Page: present */
+#define PG_P 0x01
+
+/* Page: read/write */
+#define PG_RW 0x02
+
+/* Page: user/supervisor */
+#define PG_US 0x04
+
+/* Page: page size */
+#define PG_PS 0x80
+
+/** 2MB page size */
+#define PAGE_SIZE_2MB 0x200000
+
+/** 32-bit address space size */
+#define ADDR_4GB 0x100000000ULL
+
+/** Saved paging state */
+struct paging_state {
+       /** Control register 0 */
+       unsigned long cr0;
+       /** Control register 3 */
+       unsigned long cr3;
+       /** Control register 4 */
+       unsigned long cr4;
+};
+
+extern int paging;
+
+extern void init_paging ( void );
+extern void enable_paging ( struct paging_state *state );
+extern void disable_paging ( struct paging_state *state );
+extern uint64_t relocate_memory_high ( void *start, size_t len );
+
+#endif /* _PAGING_H */
diff --git a/wimboot/wimboot-2.7.3/src/pause.c b/wimboot/wimboot-2.7.3/src/pause.c
new file mode 100644 (file)
index 0000000..72c50f0
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Diagnostic pause
+ *
+ */
+
+#include <stdio.h>
+#include "wimboot.h"
+#include "cmdline.h"
+#include "pause.h"
+
+/**
+ * Pause before booting
+ *
+ */
+void pause ( void ) {
+
+       /* Wait for keypress, prompting unless inhibited */
+       if ( cmdline_pause_quiet ) {
+               getchar();
+       } else {
+               printf ( "Press any key to continue booting..." );
+               getchar();
+               printf ( "\n" );
+       }
+}
diff --git a/wimboot/wimboot-2.7.3/src/pause.h b/wimboot/wimboot-2.7.3/src/pause.h
new file mode 100644 (file)
index 0000000..4fe364b
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _PAUSE_H
+#define _PAUSE_H
+
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Diagnostic pause
+ *
+ */
+
+extern void pause ( void );
+
+#endif /* _PAUSE_H */
diff --git a/wimboot/wimboot-2.7.3/src/peloader.c b/wimboot/wimboot-2.7.3/src/peloader.c
new file mode 100644 (file)
index 0000000..7576933
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * PE image loader
+ *
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include "wimboot.h"
+#include "peloader.h"
+
+/**
+ * Load PE image into memory
+ *
+ * @v data             PE image
+ * @v len              Length of PE image
+ * @v pe               Loaded PE structure to fill in
+ * @ret rc             Return status code
+ */
+int load_pe ( const void *data, size_t len, struct loaded_pe *pe ) {
+       const struct mz_header *mzhdr;
+       size_t pehdr_offset;
+       const struct pe_header *pehdr;
+       size_t opthdr_offset;
+       const struct pe_optional_header *opthdr;
+       size_t section_offset;
+       const struct coff_section *section;
+       char name[ sizeof ( section->name ) + 1 /* NUL */ ];
+       unsigned int i;
+       void *section_base;
+       size_t filesz;
+       size_t memsz;
+       void *end;
+       void *raw_base;
+
+       DBG2 ( "Loading PE executable...\n" );
+
+       /* Parse PE header */
+       mzhdr = data;
+       if ( mzhdr->magic != MZ_HEADER_MAGIC ) {
+               DBG ( "Bad MZ magic %04x\n", mzhdr->magic );
+               return -1;
+       }
+       pehdr_offset = mzhdr->lfanew;
+       if ( pehdr_offset > len ) {
+               DBG ( "PE header outside file\n" );
+               return -1;
+       }
+       pehdr = ( data + pehdr_offset );
+       if ( pehdr->magic != PE_HEADER_MAGIC ) {
+               DBG ( "Bad PE magic %08x\n", pehdr->magic );
+               return -1;
+       }
+       opthdr_offset = ( pehdr_offset + sizeof ( *pehdr ) );
+       opthdr = ( data + opthdr_offset );
+       pe->base = ( ( void * ) ( intptr_t ) ( opthdr->base ) );
+       section_offset = ( opthdr_offset + pehdr->coff.opthdr_len );
+       section = ( data + section_offset );
+
+       /* Load header into memory */
+       DBG2 ( "...headers to %p+%#x\n", pe->base, opthdr->header_len );
+       memcpy ( pe->base, data, opthdr->header_len );
+       end = ( pe->base + opthdr->header_len );
+
+       /* Load each section into memory */
+       for ( i = 0 ; i < pehdr->coff.num_sections ; i++, section++ ) {
+               memset ( name, 0, sizeof ( name ) );
+               memcpy ( name, section->name, sizeof ( section->name ) );
+               section_base = ( pe->base + section->virtual );
+               filesz = section->raw_len;
+               memsz = section->misc.virtual_len;
+               DBG2 ( "...from %#05x to %p+%#zx/%#zx (%s)\n",
+                      section->raw, section_base, filesz, memsz, name );
+               memset ( section_base, 0, memsz );
+               memcpy ( section_base, ( data + section->raw ), filesz );
+               if ( end < ( section_base + memsz ) )
+                       end = ( section_base + memsz );
+       }
+       pe->len = ( ( ( end - pe->base ) + opthdr->section_align - 1 )
+                   & ~( opthdr->section_align - 1 ) );
+
+       /* Load copy of raw image into memory immediately after loaded
+        * sections.  This seems to be used for verification of X.509
+        * signatures.
+        */
+       raw_base = ( pe->base + pe->len );
+       memcpy ( raw_base, data, len );
+       pe->len += len;
+       DBG2 ( "...raw copy to %p+%#zx\n", raw_base, len );
+
+       /* Extract entry point */
+       pe->entry = ( pe->base + opthdr->entry );
+       DBG2 ( "...entry point %p\n", pe->entry );
+
+       return 0;
+}
diff --git a/wimboot/wimboot-2.7.3/src/peloader.h b/wimboot/wimboot-2.7.3/src/peloader.h
new file mode 100644 (file)
index 0000000..08a3057
--- /dev/null
@@ -0,0 +1,195 @@
+#ifndef _PELOADER_H
+#define _PELOADER_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * PE image loader
+ *
+ */
+
+#include <stdint.h>
+#include "wimboot.h"
+
+/** DOS MZ header */
+struct mz_header {
+       /** Magic number */
+       uint16_t magic;
+       /** Bytes on last page of file */
+       uint16_t cblp;
+       /** Pages in file */
+       uint16_t cp;
+       /** Relocations */
+       uint16_t crlc;
+       /** Size of header in paragraphs */
+       uint16_t cparhdr;
+       /** Minimum extra paragraphs needed */
+       uint16_t minalloc;
+       /** Maximum extra paragraphs needed */
+       uint16_t maxalloc;
+       /** Initial (relative) SS value */
+       uint16_t ss;
+       /** Initial SP value */
+       uint16_t sp;
+       /** Checksum */
+       uint16_t csum;
+       /** Initial IP value */
+       uint16_t ip;
+       /** Initial (relative) CS value */
+       uint16_t cs;
+       /** File address of relocation table */
+       uint16_t lfarlc;
+       /** Overlay number */
+       uint16_t ovno;
+       /** Reserved words */
+       uint16_t res[4];
+       /** OEM identifier (for oeminfo) */
+       uint16_t oemid;
+       /** OEM information; oemid specific */
+       uint16_t oeminfo;
+       /** Reserved words */
+       uint16_t res2[10];
+       /** File address of new exe header */
+       uint32_t lfanew;
+} __attribute__ (( packed ));
+
+/** MZ header magic */
+#define MZ_HEADER_MAGIC 0x5a4d
+
+/** COFF file header */
+struct coff_header {
+       /** Magic number */
+       uint16_t magic;
+       /** Number of sections */
+       uint16_t num_sections;
+       /** Timestamp (seconds since the Epoch) */
+       uint32_t timestamp;
+       /** Offset to symbol table */
+       uint32_t symtab;
+       /** Number of symbol table entries */
+       uint32_t num_syms;
+       /** Length of optional header */
+       uint16_t opthdr_len;
+       /** Flags */
+       uint16_t flags;
+} __attribute__ (( packed ));
+
+/** COFF section */
+struct coff_section {
+       /** Section name */
+       char name[8];
+       /** Physical address or virtual length */
+       union {
+               /** Physical address */
+               uint32_t physical;
+               /** Virtual length */
+               uint32_t virtual_len;
+       } misc;
+       /** Virtual address */
+       uint32_t virtual;
+       /** Length of raw data */
+       uint32_t raw_len;
+       /** Offset to raw data */
+       uint32_t raw;
+       /** Offset to relocations */
+       uint32_t relocations;
+       /** Offset to line numbers */
+       uint32_t line_numbers;
+       /** Number of relocations */
+       uint16_t num_relocations;
+       /** Number of line numbers */
+       uint16_t num_line_numbers;
+       /** Flags */
+       uint32_t flags;
+} __attribute__ (( packed ));
+
+/** PE file header */
+struct pe_header {
+       /** Magic number */
+       uint32_t magic;
+       /** COFF header */
+       struct coff_header coff;
+} __attribute__ (( packed ));
+
+/** PE header magic */
+#define PE_HEADER_MAGIC 0x00004550
+
+/** PE optional header */
+struct pe_optional_header {
+       /** Magic number */
+       uint16_t magic;
+       /** Major linker version */
+       uint8_t linker_major;
+       /** Minor linker version */
+       uint8_t linker_minor;
+       /** Length of code */
+       uint32_t text_len;
+       /** Length of initialised data */
+       uint32_t data_len;
+       /** Length of uninitialised data */
+       uint32_t bss_len;
+       /** Entry point */
+       uint32_t entry;
+       /** Base of code */
+       uint32_t text;
+       /** Base of data */
+       uint32_t data;
+       /** Image base address */
+       uint32_t base;
+       /** Section alignment */
+       uint32_t section_align;
+       /** File alignment */
+       uint32_t file_align;
+       /** Major operating system version */
+       uint16_t os_major;
+       /** Minor operating system version */
+       uint16_t os_minor;
+       /** Major image version */
+       uint16_t image_major;
+       /** Minor image version */
+       uint16_t image_minor;
+       /** Major subsystem version */
+       uint16_t subsystem_major;
+       /** Minor subsystem version */
+       uint16_t subsystem_minor;
+       /** Win32 version */
+       uint32_t win32_version;
+       /** Size of image */
+       uint32_t len;
+       /** Size of headers */
+       uint32_t header_len;
+       /* Plus extra fields that we don't care about */
+} __attribute__ (( packed ));
+
+/** A loaded PE image */
+struct loaded_pe {
+       /** Base address */
+       void *base;
+       /** Length */
+       size_t len;
+       /** Entry point */
+       void ( * entry ) ( struct bootapp_descriptor *bootapp );
+};
+
+extern int load_pe ( const void *data, size_t len, struct loaded_pe *pe );
+
+#endif /* _PELOADER_H */
diff --git a/wimboot/wimboot-2.7.3/src/rotate.h b/wimboot/wimboot-2.7.3/src/rotate.h
new file mode 100644 (file)
index 0000000..7f08755
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef _ROTATE_H
+#define _ROTATE_H
+
+/** @file
+ *
+ * Bit operations
+ */
+
+#include <stdint.h>
+
+static inline __attribute__ (( always_inline )) uint8_t
+rol8 ( uint8_t data, unsigned int rotation ) {
+        return ( ( data << rotation ) | ( data >> ( 8 - rotation ) ) );
+}
+
+static inline __attribute__ (( always_inline )) uint8_t
+ror8 ( uint8_t data, unsigned int rotation ) {
+        return ( ( data >> rotation ) | ( data << ( 8 - rotation ) ) );
+}
+
+static inline __attribute__ (( always_inline )) uint16_t
+rol16 ( uint16_t data, unsigned int rotation ) {
+        return ( ( data << rotation ) | ( data >> ( 16 - rotation ) ) );
+}
+
+static inline __attribute__ (( always_inline )) uint16_t
+ror16 ( uint16_t data, unsigned int rotation ) {
+        return ( ( data >> rotation ) | ( data << ( 16 - rotation ) ) );
+}
+
+static inline __attribute__ (( always_inline )) uint32_t
+rol32 ( uint32_t data, unsigned int rotation ) {
+        return ( ( data << rotation ) | ( data >> ( 32 - rotation ) ) );
+}
+
+static inline __attribute__ (( always_inline )) uint32_t
+ror32 ( uint32_t data, unsigned int rotation ) {
+        return ( ( data >> rotation ) | ( data << ( 32 - rotation ) ) );
+}
+
+static inline __attribute__ (( always_inline )) uint64_t
+rol64 ( uint64_t data, unsigned int rotation ) {
+        return ( ( data << rotation ) | ( data >> ( 64 - rotation ) ) );
+}
+
+static inline __attribute__ (( always_inline )) uint64_t
+ror64 ( uint64_t data, unsigned int rotation ) {
+        return ( ( data >> rotation ) | ( data << ( 64 - rotation ) ) );
+}
+
+#endif /* _ROTATE_H */
diff --git a/wimboot/wimboot-2.7.3/src/script.lds b/wimboot/wimboot-2.7.3/src/script.lds
new file mode 100644 (file)
index 0000000..64643bd
--- /dev/null
@@ -0,0 +1,116 @@
+SECTIONS {
+
+       /* Align sections to keep PE tools happy */
+       alignment = 16;
+
+       /* Virtual addresses start at 0x20000 */
+       . = 0x20000;
+       _start = .;
+
+       /* bzImage prefix */
+       _prefix_pos = 0;
+       .prefix : AT ( _prefix_pos ) {
+               _prefix = .;
+               *(.prefix)
+               *(.prefix.*)
+               . = ALIGN ( alignment );
+               _eprefix = .;
+       }
+       _prefix_len = ABSOLUTE ( _eprefix ) - ABSOLUTE ( _prefix );
+
+       /* Real-mode uninitialised data section */
+       .bss16 ( NOLOAD ) : {
+               _bss16 = .;
+               *(.stack16)
+               *(.stack16.*)
+               *(.bss16)
+               *(.bss16.*)
+               . = ALIGN ( alignment );
+               _ebss16 = .;
+       }
+       _bss16_len = ABSOLUTE ( _ebss16 ) - ABSOLUTE ( _bss16 );
+
+       /* Payload section */
+       _payload_pos = ( _prefix_pos + _prefix_len );
+       .payload : AT ( _payload_pos ) {
+               _payload = .;
+               /* Portions that must be accessible in 16-bit modes */
+               _text16 = .;
+               *(.text16)
+               *(.text16.*)
+               _etext16 = .;
+               _data16 = .;
+               *(.rodata16)
+               *(.rodata16.*)
+               *(.data16)
+               *(.data16.*)
+               _edata16 = .;
+               /* Portions that need not be accessible in 16-bit modes */
+               _text = .;
+               *(.text)
+               *(.text.*)
+               _etext = .;
+               _data = .;
+               *(.rodata)
+               *(.rodata.*)
+               *(.data)
+               *(.data.*)
+               . = ALIGN ( alignment );
+               _edata = .;
+               _epayload = .;
+       }
+       _text16_len = ABSOLUTE ( _etext16 ) - ABSOLUTE ( _text16 );
+       _data16_len = ABSOLUTE ( _edata16 ) - ABSOLUTE ( _data16 );
+       _text_len = ABSOLUTE ( _etext ) - ABSOLUTE ( _text );
+       _data_len = ABSOLUTE ( _edata ) - ABSOLUTE ( _data );
+       _payload_len = ABSOLUTE ( _epayload ) - ABSOLUTE ( _payload );
+
+       /* bootmgr.exe hardcodes the address 0x30000 for use as a
+        * buffer accessible by real-mode code.  We can't fit our
+        * .text, .data, and .bss below this region, so explicitly
+        * place the .bss higher in memory.
+        */
+       _forbidden_start = 0x30000;
+       _forbidden_end = 0x40000;
+
+       /* Uninitialised data section */
+       .bss ( NOLOAD ) : {
+               _bss = .;
+               ASSERT ( ABSOLUTE ( . ) <= ABSOLUTE ( _forbidden_start ),
+                        "Binary is too large" );
+               . = ABSOLUTE ( _forbidden_end );
+               *(.bss)
+               *(.bss.*)
+               *(COMMON)
+               *(.stack)
+               *(.stack.*)
+               . = ALIGN ( alignment );
+               _ebss = .;
+       }
+       _bss_len = ABSOLUTE ( _ebss ) - ABSOLUTE ( _bss );
+
+       /* Relocations section */
+       _reloc_pos = ( _payload_pos + _payload_len );
+       _reloc = .;
+
+       _end = .;
+
+       _text_total_len = ( _text_len + _text16_len );
+       _data_total_len = ( _data_len + _data16_len );
+       _bss_total_len = ( _bss_len + _bss16_len );
+
+       /* Symbols required by i386.x86_64 objects */
+       __i386__start = _start;
+       __i386__end = _end;
+
+       /DISCARD/ : {
+               *(.comment)
+               *(.comment.*)
+               *(.note)
+               *(.note.*)
+               *(.eh_frame)
+               *(.eh_frame.*)
+               *(.rel)
+               *(.rel.*)
+       }
+}
diff --git a/wimboot/wimboot-2.7.3/src/sha1.c b/wimboot/wimboot-2.7.3/src/sha1.c
new file mode 100644 (file)
index 0000000..fc5c061
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+/**
+ * @file
+ *
+ * SHA-1 algorithm
+ *
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <byteswap.h>
+#include <assert.h>
+#include "rotate.h"
+#include "sha1.h"
+
+/** SHA-1 variables */
+struct sha1_variables {
+       /* This layout matches that of struct sha1_digest_data,
+        * allowing for efficient endianness-conversion,
+        */
+       uint32_t a;
+       uint32_t b;
+       uint32_t c;
+       uint32_t d;
+       uint32_t e;
+       uint32_t w[80];
+} __attribute__ (( packed ));
+
+/**
+ * f(a,b,c,d) for steps 0 to 19
+ *
+ * @v v                SHA-1 variables
+ * @ret f      f(a,b,c,d)
+ */
+static uint32_t sha1_f_0_19 ( struct sha1_variables *v ) {
+       return ( ( v->b & v->c ) | ( (~v->b) & v->d ) );
+}
+
+/**
+ * f(a,b,c,d) for steps 20 to 39 and 60 to 79
+ *
+ * @v v                SHA-1 variables
+ * @ret f      f(a,b,c,d)
+ */
+static uint32_t sha1_f_20_39_60_79 ( struct sha1_variables *v ) {
+       return ( v->b ^ v->c ^ v->d );
+}
+
+/**
+ * f(a,b,c,d) for steps 40 to 59
+ *
+ * @v v                SHA-1 variables
+ * @ret f      f(a,b,c,d)
+ */
+static uint32_t sha1_f_40_59 ( struct sha1_variables *v ) {
+       return ( ( v->b & v->c ) | ( v->b & v->d ) | ( v->c & v->d ) );
+}
+
+/** An SHA-1 step function */
+struct sha1_step {
+       /**
+        * Calculate f(a,b,c,d)
+        *
+        * @v v         SHA-1 variables
+        * @ret f       f(a,b,c,d)
+        */
+       uint32_t ( * f ) ( struct sha1_variables *v );
+       /** Constant k */
+       uint32_t k;
+};
+
+/** SHA-1 steps */
+static struct sha1_step sha1_steps[4] = {
+       /** 0 to 19 */
+       { .f = sha1_f_0_19,             .k = 0x5a827999 },
+       /** 20 to 39 */
+       { .f = sha1_f_20_39_60_79,      .k = 0x6ed9eba1 },
+       /** 40 to 59 */
+       { .f = sha1_f_40_59,            .k = 0x8f1bbcdc },
+       /** 60 to 79 */
+       { .f = sha1_f_20_39_60_79,      .k = 0xca62c1d6 },
+};
+
+/**
+ * Initialise SHA-1 algorithm
+ *
+ * @v ctx              SHA-1 context
+ */
+void sha1_init ( void *ctx ) {
+       struct sha1_context *context = ctx;
+
+       context->ddd.dd.digest.h[0] = cpu_to_be32 ( 0x67452301 );
+       context->ddd.dd.digest.h[1] = cpu_to_be32 ( 0xefcdab89 );
+       context->ddd.dd.digest.h[2] = cpu_to_be32 ( 0x98badcfe );
+       context->ddd.dd.digest.h[3] = cpu_to_be32 ( 0x10325476 );
+       context->ddd.dd.digest.h[4] = cpu_to_be32 ( 0xc3d2e1f0 );
+       context->len = 0;
+}
+
+/**
+ * Calculate SHA-1 digest of accumulated data
+ *
+ * @v context          SHA-1 context
+ */
+static void sha1_digest ( struct sha1_context *context ) {
+        union {
+               union sha1_digest_data_dwords ddd;
+               struct sha1_variables v;
+       } u;
+       uint32_t *a = &u.v.a;
+       uint32_t *b = &u.v.b;
+       uint32_t *c = &u.v.c;
+       uint32_t *d = &u.v.d;
+       uint32_t *e = &u.v.e;
+       uint32_t *w = u.v.w;
+       uint32_t f;
+       uint32_t k;
+       uint32_t temp;
+       struct sha1_step *step;
+       unsigned int i;
+
+       /* Convert h[0..4] to host-endian, and initialise a, b, c, d,
+        * e, and w[0..15]
+        */
+       for ( i = 0 ; i < ( sizeof ( u.ddd.dword ) /
+                           sizeof ( u.ddd.dword[0] ) ) ; i++ ) {
+               be32_to_cpus ( &context->ddd.dword[i] );
+               u.ddd.dword[i] = context->ddd.dword[i];
+       }
+
+       /* Initialise w[16..79] */
+       for ( i = 16 ; i < 80 ; i++ )
+               w[i] = rol32 ( ( w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16] ), 1 );
+
+       /* Main loop */
+       for ( i = 0 ; i < 80 ; i++ ) {
+               step = &sha1_steps[ i / 20 ];
+               f = step->f ( &u.v );
+               k = step->k;
+               temp = ( rol32 ( *a, 5 ) + f + *e + k + w[i] );
+               *e = *d;
+               *d = *c;
+               *c = rol32 ( *b, 30 );
+               *b = *a;
+               *a = temp;
+       }
+
+       /* Add chunk to hash and convert back to big-endian */
+       for ( i = 0 ; i < 5 ; i++ ) {
+               context->ddd.dd.digest.h[i] =
+                       cpu_to_be32 ( context->ddd.dd.digest.h[i] +
+                                     u.ddd.dd.digest.h[i] );
+       }
+}
+
+/**
+ * Accumulate data with SHA-1 algorithm
+ *
+ * @v ctx              SHA-1 context
+ * @v data             Data
+ * @v len              Length of data
+ */
+void sha1_update ( void *ctx, const void *data, size_t len ) {
+       struct sha1_context *context = ctx;
+       const uint8_t *byte = data;
+       size_t offset;
+
+       /* Accumulate data a byte at a time, performing the digest
+        * whenever we fill the data buffer
+        */
+       while ( len-- ) {
+               offset = ( context->len % sizeof ( context->ddd.dd.data ) );
+               context->ddd.dd.data.byte[offset] = *(byte++);
+               context->len++;
+               if ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 )
+                       sha1_digest ( context );
+       }
+}
+
+/**
+ * Generate SHA-1 digest
+ *
+ * @v ctx              SHA-1 context
+ * @v out              Output buffer
+ */
+void sha1_final ( void *ctx, void *out ) {
+       struct sha1_context *context = ctx;
+       uint64_t len_bits;
+       uint8_t pad;
+
+       /* Record length before pre-processing */
+       len_bits = cpu_to_be64 ( ( ( uint64_t ) context->len ) * 8 );
+
+       /* Pad with a single "1" bit followed by as many "0" bits as required */
+       pad = 0x80;
+       do {
+               sha1_update ( ctx, &pad, sizeof ( pad ) );
+               pad = 0x00;
+       } while ( ( context->len % sizeof ( context->ddd.dd.data ) ) !=
+                 offsetof ( typeof ( context->ddd.dd.data ), final.len ) );
+
+       /* Append length (in bits) */
+       sha1_update ( ctx, &len_bits, sizeof ( len_bits ) );
+       assert ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 );
+
+       /* Copy out final digest */
+       memcpy ( out, &context->ddd.dd.digest,
+                sizeof ( context->ddd.dd.digest ) );
+}
diff --git a/wimboot/wimboot-2.7.3/src/sha1.h b/wimboot/wimboot-2.7.3/src/sha1.h
new file mode 100644 (file)
index 0000000..af52274
--- /dev/null
@@ -0,0 +1,72 @@
+#ifndef _SHA1_H
+#define _SHA1_H
+
+/** @file
+ *
+ * SHA-1 algorithm
+ *
+ */
+
+#include <stdint.h>
+
+/** An SHA-1 digest */
+struct sha1_digest {
+       /** Hash output */
+       uint32_t h[5];
+};
+
+/** An SHA-1 data block */
+union sha1_block {
+       /** Raw bytes */
+       uint8_t byte[64];
+       /** Raw dwords */
+       uint32_t dword[16];
+       /** Final block structure */
+       struct {
+               /** Padding */
+               uint8_t pad[56];
+               /** Length in bits */
+               uint64_t len;
+       } final;
+};
+
+/** SHA-1 digest and data block
+ *
+ * The order of fields within this structure is designed to minimise
+ * code size.
+ */
+struct sha1_digest_data {
+       /** Digest of data already processed */
+       struct sha1_digest digest;
+       /** Accumulated data */
+       union sha1_block data;
+} __attribute__ (( packed ));
+
+/** SHA-1 digest and data block */
+union sha1_digest_data_dwords {
+       /** Digest and data block */
+       struct sha1_digest_data dd;
+       /** Raw dwords */
+       uint32_t dword[ sizeof ( struct sha1_digest_data ) /
+                       sizeof ( uint32_t ) ];
+};
+
+/** An SHA-1 context */
+struct sha1_context {
+       /** Amount of accumulated data */
+       size_t len;
+       /** Digest and accumulated data */
+       union sha1_digest_data_dwords ddd;
+} __attribute__ (( packed ));
+
+/** SHA-1 context size */
+#define SHA1_CTX_SIZE sizeof ( struct sha1_context )
+
+/** SHA-1 digest size */
+#define SHA1_DIGEST_SIZE sizeof ( struct sha1_digest )
+
+extern void sha1_init ( void *ctx );
+extern void sha1_update ( void *ctx, const void *data, size_t len );
+extern void sha1_final ( void *ctx, void *out );
+
+#endif /* _SHA1_H */
diff --git a/wimboot/wimboot-2.7.3/src/stdarg.h b/wimboot/wimboot-2.7.3/src/stdarg.h
new file mode 100644 (file)
index 0000000..80c5a00
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _STDARG_H
+#define _STDARG_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Standard arguments
+ *
+ */
+
+typedef __builtin_va_list va_list;
+#define va_start( ap, last ) __builtin_va_start ( ap, last )
+#define va_arg( ap, type ) __builtin_va_arg ( ap, type )
+#define va_end( ap ) __builtin_va_end ( ap )
+#define va_copy( dest, src ) __builtin_va_copy ( dest, src )
+
+#endif /* _STDARG_H */
diff --git a/wimboot/wimboot-2.7.3/src/stddef.h b/wimboot/wimboot-2.7.3/src/stddef.h
new file mode 100644 (file)
index 0000000..d1f8edb
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Standard definitions
+ *
+ */
+
+#include <stdint.h>
+
+#define NULL ( ( void * ) 0 )
+
+#define offsetof( type, member ) ( ( size_t ) &( ( type * ) NULL )->member )
+
+#define container_of( ptr, type, member ) ( {                          \
+       const typeof ( ( ( type * ) NULL )->member ) *__mptr = (ptr);   \
+       ( type * ) ( ( void * ) __mptr - offsetof ( type, member ) ); } )
+
+#endif /* _STDDEF_H */
diff --git a/wimboot/wimboot-2.7.3/src/stdint.h b/wimboot/wimboot-2.7.3/src/stdint.h
new file mode 100644 (file)
index 0000000..297994b
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef _STDINT_H
+#define _STDINT_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Standard integer types
+ *
+ */
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed int int32_t;
+typedef signed long long int64_t;
+
+typedef unsigned long intptr_t;
+
+typedef __SIZE_TYPE__ size_t;
+typedef signed long ssize_t;
+
+typedef __WCHAR_TYPE__ wchar_t;
+typedef __WINT_TYPE__ wint_t;
+
+#endif /* _STDINT_H */
diff --git a/wimboot/wimboot-2.7.3/src/stdio.c b/wimboot/wimboot-2.7.3/src/stdio.c
new file mode 100644 (file)
index 0000000..c119bd3
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Standard Input/Output
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "bootapp.h"
+#include "wimboot.h"
+#include "efi.h"
+
+/**
+ * Print character to console
+ *
+ * @v character                Character to print
+ */
+int putchar ( int character ) {
+       EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *conout;
+       struct bootapp_callback_params params;
+       wchar_t wbuf[2];
+
+       /* Convert LF to CR,LF */
+       if ( character == '\n' )
+               putchar ( '\r' );
+
+       /* Print character to bochs debug port */
+       __asm__ __volatile__ ( "outb %b0, $0xe9"
+                              : : "a" ( character ) );
+
+       /* Print character to EFI/BIOS console as applicable */
+       if ( efi_systab ) {
+               conout = efi_systab->ConOut;
+               wbuf[0] = character;
+               wbuf[1] = 0;
+               conout->OutputString ( conout, wbuf );
+       } else {
+               memset ( &params, 0, sizeof ( params ) );
+               params.vector.interrupt = 0x10;
+               params.eax = ( 0x0e00 | character );
+               params.ebx = 0x0007;
+               call_interrupt ( &params );
+       }
+
+       return 0;
+}
+
+/**
+ * Get character from console
+ *
+ * @ret character      Character
+ */
+int getchar ( void ) {
+       EFI_BOOT_SERVICES *bs;
+       EFI_SIMPLE_TEXT_INPUT_PROTOCOL *conin;
+       EFI_INPUT_KEY key;
+       UINTN index;
+       struct bootapp_callback_params params;
+       int character;
+
+       /* Get character */
+       if ( efi_systab ) {
+               bs = efi_systab->BootServices;
+               conin = efi_systab->ConIn;
+               bs->WaitForEvent ( 1, &conin->WaitForKey, &index );
+               conin->ReadKeyStroke ( conin, &key );
+               character = key.UnicodeChar;
+       } else {
+               memset ( &params, 0, sizeof ( params ) );
+               params.vector.interrupt = 0x16;
+               call_interrupt ( &params );
+               character = params.al;
+       }
+
+       return character;
+}
diff --git a/wimboot/wimboot-2.7.3/src/stdio.h b/wimboot/wimboot-2.7.3/src/stdio.h
new file mode 100644 (file)
index 0000000..72cd452
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef _STDIO_H
+#define _STDIO_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Standard Input/Output
+ *
+ */
+
+#include <stdint.h>
+#include <stdarg.h>
+
+extern int putchar ( int character );
+extern int getchar ( void );
+
+extern int __attribute__ (( format ( printf, 1, 2 ) ))
+printf ( const char *fmt, ... );
+
+extern int __attribute__ (( format ( printf, 3, 4 ) ))
+snprintf ( char *buf, size_t size, const char *fmt, ... );
+
+extern int vprintf ( const char *fmt, va_list args );
+
+extern int vsnprintf ( char *buf, size_t size, const char *fmt, va_list args );
+
+#endif /* _STDIO_H */
diff --git a/wimboot/wimboot-2.7.3/src/stdlib.h b/wimboot/wimboot-2.7.3/src/stdlib.h
new file mode 100644 (file)
index 0000000..64cb91a
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _STDLIB_H
+#define _STDLIB_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Standard library
+ *
+ */
+
+extern unsigned long strtoul ( const char *nptr, char **endptr, int base );
+
+#endif /* _STDLIB_H */
diff --git a/wimboot/wimboot-2.7.3/src/string.c b/wimboot/wimboot-2.7.3/src/string.c
new file mode 100644 (file)
index 0000000..6c0aaf7
--- /dev/null
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * String functions
+ *
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include "ctype.h"
+#include "wctype.h"
+
+/**
+ * Copy memory area
+ *
+ * @v dest             Destination address
+ * @v src              Source address
+ * @v len              Length
+ * @ret dest           Destination address
+ */
+void * memcpy ( void *dest, const void *src, size_t len ) {
+       void *edi = dest;
+       const void *esi = src;
+       int discard_ecx;
+
+       /* Perform dword-based copy for bulk, then byte-based for remainder */
+       __asm__ __volatile__ ( "rep movsl"
+                              : "=&D" ( edi ), "=&S" ( esi ),
+                                "=&c" ( discard_ecx )
+                              : "0" ( edi ), "1" ( esi ), "2" ( len >> 2 )
+                              : "memory" );
+       __asm__ __volatile__ ( "rep movsb"
+                              : "=&D" ( edi ), "=&S" ( esi ),
+                                "=&c" ( discard_ecx )
+                              : "0" ( edi ), "1" ( esi ), "2" ( len & 3 )
+                              : "memory" );
+       return dest;
+}
+
+/**
+ * Copy memory area backwards
+ *
+ * @v dest             Destination address
+ * @v src              Source address
+ * @v len              Length
+ * @ret dest           Destination address
+ */
+static void * memcpy_reverse ( void *dest, const void *src, size_t len ) {
+       void *edi = ( dest + len - 1 );
+       const void *esi = ( src + len - 1 );
+       int discard_ecx;
+
+       /* Assume memmove() is not performance-critical, and perform a
+        * bytewise copy for simplicity.
+        *
+        * Disable interrupts to avoid known problems on platforms
+        * that assume the direction flag always remains cleared.
+        */
+       __asm__ __volatile__ ( "pushf\n\t"
+                              "cli\n\t"
+                              "std\n\t"
+                              "rep movsb\n\t"
+                              "popf\n\t"
+                              : "=&D" ( edi ), "=&S" ( esi ),
+                                "=&c" ( discard_ecx )
+                              : "0" ( edi ), "1" ( esi ),
+                                "2" ( len )
+                              : "memory" );
+       return dest;
+}
+
+/**
+ * Copy (possibly overlapping) memory area
+ *
+ * @v dest             Destination address
+ * @v src              Source address
+ * @v len              Length
+ * @ret dest           Destination address
+ */
+void * memmove ( void *dest, const void *src, size_t len ) {
+
+       if ( dest <= src ) {
+               return memcpy ( dest, src, len );
+       } else {
+               return memcpy_reverse ( dest, src, len );
+       }
+}
+
+/**
+ * Set memory area
+ *
+ * @v dest             Destination address
+ * @v src              Source address
+ * @v len              Length
+ * @ret dest           Destination address
+ */
+void * memset ( void *dest, int c, size_t len ) {
+       void *edi = dest;
+       int eax = c;
+       int discard_ecx;
+
+       /* Expand byte to whole dword */
+       eax |= ( eax << 8 );
+       eax |= ( eax << 16 );
+
+       /* Perform dword-based set for bulk, then byte-based for remainder */
+       __asm__ __volatile__ ( "rep stosl"
+                              : "=&D" ( edi ), "=&a" ( eax ),
+                                "=&c" ( discard_ecx )
+                              : "0" ( edi ), "1" ( eax ), "2" ( len >> 2 )
+                              : "memory" );
+       __asm__ __volatile__ ( "rep stosb"
+                              : "=&D" ( edi ), "=&a" ( eax ),
+                                "=&c" ( discard_ecx )
+                              : "0" ( edi ), "1" ( eax ), "2" ( len & 3 )
+                              : "memory" );
+       return dest;
+}
+
+/**
+ * Compare memory areas
+ *
+ * @v src1             First source area
+ * @v src2             Second source area
+ * @v len              Length
+ * @ret diff           Difference
+ */
+int memcmp ( const void *src1, const void *src2, size_t len ) {
+       const uint8_t *bytes1 = src1;
+       const uint8_t *bytes2 = src2;
+       int diff;
+
+       while ( len-- ) {
+               if ( ( diff = ( *(bytes1++) - *(bytes2++) ) ) )
+                       return diff;
+       }
+       return 0;
+}
+
+/**
+ * Compare two strings
+ *
+ * @v str1             First string
+ * @v str2             Second string
+ * @ret diff           Difference
+ */
+int strcmp ( const char *str1, const char *str2 ) {
+       int c1;
+       int c2;
+
+       do {
+               c1 = *(str1++);
+               c2 = *(str2++);
+       } while ( ( c1 != '\0' ) && ( c1 == c2 ) );
+
+       return ( c1 - c2 );
+}
+
+/**
+ * Compare two strings, case-insensitively
+ *
+ * @v str1             First string
+ * @v str2             Second string
+ * @ret diff           Difference
+ */
+int strcasecmp ( const char *str1, const char *str2 ) {
+       int c1;
+       int c2;
+
+       do {
+               c1 = toupper ( *(str1++) );
+               c2 = toupper ( *(str2++) );
+       } while ( ( c1 != '\0' ) && ( c1 == c2 ) );
+
+       return ( c1 - c2 );
+}
+
+/**
+ * Compare two wide-character strings, case-insensitively
+ *
+ * @v str1             First string
+ * @v str2             Second string
+ * @ret diff           Difference
+ */
+int wcscasecmp ( const wchar_t *str1, const wchar_t *str2 ) {
+       int c1;
+       int c2;
+
+       do {
+               c1 = towupper ( *(str1++) );
+               c2 = towupper ( *(str2++) );
+       } while ( ( c1 != L'\0' ) && ( c1 == c2 ) );
+
+       return ( c1 - c2 );
+}
+
+/**
+ * Get length of string
+ *
+ * @v str              String
+ * @ret len            Length
+ */
+size_t strlen ( const char *str ) {
+       size_t len = 0;
+
+       while ( *(str++) )
+               len++;
+       return len;
+}
+
+/**
+ * Get length of wide-character string
+ *
+ * @v str              String
+ * @ret len            Length (in characters)
+ */
+size_t wcslen ( const wchar_t *str ) {
+       size_t len = 0;
+
+       while ( *(str++) )
+               len++;
+       return len;
+}
+
+/**
+ * Find character in wide-character string
+ *
+ * @v str              String
+ * @v c                        Wide character
+ * @ret first          First occurrence of wide character in string, or NULL
+ */
+wchar_t * wcschr ( const wchar_t *str, wchar_t c ) {
+
+       for ( ; *str ; str++ ) {
+               if ( *str == c )
+                       return ( ( wchar_t * )str );
+       }
+       return NULL;
+}
+
+char *strchr(const char *str, char c) {
+    for ( ; *str ; str++ ) {
+               if ( *str == c )
+                       return ( ( char * )str );
+       }
+       return NULL;
+}
+
+/**
+ * Check to see if character is a space
+ *
+ * @v c                 Character
+ * @ret isspace         Character is a space
+ */
+int isspace ( int c ) {
+        switch ( c ) {
+        case ' ' :
+        case '\f' :
+        case '\n' :
+        case '\r' :
+        case '\t' :
+        case '\v' :
+                return 1;
+        default:
+                return 0;
+        }
+}
+
+/**
+ * Convert a string to an unsigned integer
+ *
+ * @v nptr             String
+ * @v endptr           End pointer to fill in (or NULL)
+ * @v base             Numeric base
+ * @ret val            Value
+ */
+unsigned long strtoul ( const char *nptr, char **endptr, int base ) {
+       unsigned long val = 0;
+       int negate = 0;
+       unsigned int digit;
+
+       /* Skip any leading whitespace */
+       while ( isspace ( *nptr ) )
+               nptr++;
+
+       /* Parse sign, if present */
+       if ( *nptr == '+' ) {
+               nptr++;
+       } else if ( *nptr == '-' ) {
+               nptr++;
+               negate = 1;
+       }
+
+       /* Parse base */
+       if ( base == 0 ) {
+
+               /* Default to decimal */
+               base = 10;
+
+               /* Check for octal or hexadecimal markers */
+               if ( *nptr == '0' ) {
+                       nptr++;
+                       base = 8;
+                       if ( ( *nptr | 0x20 ) == 'x' ) {
+                               nptr++;
+                               base = 16;
+                       }
+               }
+       }
+
+       /* Parse digits */
+       for ( ; ; nptr++ ) {
+               digit = *nptr;
+               if ( digit >= 'a' ) {
+                       digit = ( digit - 'a' + 10 );
+               } else if ( digit >= 'A' ) {
+                       digit = ( digit - 'A' + 10 );
+               } else if ( digit <= '9' ) {
+                       digit = ( digit - '0' );
+               }
+               if ( digit >= ( unsigned int ) base )
+                       break;
+               val = ( ( val * base ) + digit );
+       }
+
+       /* Record end marker, if applicable */
+       if ( endptr )
+               *endptr = ( ( char * ) nptr );
+
+       /* Return value */
+       return ( negate ? -val : val );
+}
diff --git a/wimboot/wimboot-2.7.3/src/string.h b/wimboot/wimboot-2.7.3/src/string.h
new file mode 100644 (file)
index 0000000..b48d9bc
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _STRING_H
+#define _STRING_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * String operations
+ *
+ */
+
+#include <stdint.h>
+
+extern void * memcpy ( void *dest, const void *src, size_t len );
+extern void * memmove ( void *dest, const void *src, size_t len );
+extern void * memset ( void *dest, int c, size_t len );
+extern int memcmp ( const void *src1, const void *src2, size_t len );
+extern int strcmp ( const char *str1, const char *str2 );
+extern size_t strlen ( const char *str );
+
+#endif /* _STRING_H */
diff --git a/wimboot/wimboot-2.7.3/src/strings.h b/wimboot/wimboot-2.7.3/src/strings.h
new file mode 100644 (file)
index 0000000..9a59b79
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _STRINGS_H
+#define _STRINGS_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * String operations
+ *
+ */
+
+extern int strcasecmp ( const char *str1, const char *str2 );
+
+#endif /* _STRINGS_H */
diff --git a/wimboot/wimboot-2.7.3/src/vdisk.c b/wimboot/wimboot-2.7.3/src/vdisk.c
new file mode 100644 (file)
index 0000000..7885a5b
--- /dev/null
@@ -0,0 +1,665 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Virtual disk
+ *
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include "ctype.h"
+#include "wimboot.h"
+#include "vdisk.h"
+
+/** Virtual files */
+struct vdisk_file vdisk_files[VDISK_MAX_FILES];
+
+/**
+ * Read from virtual Master Boot Record
+ *
+ * @v lba              Starting LBA
+ * @v count            Number of blocks to read
+ * @v data             Data buffer
+ */
+static void vdisk_mbr ( uint64_t lba __unused, unsigned int count __unused,
+                       void *data ) {
+       struct vdisk_mbr *mbr = data;
+
+       /* Construct MBR */
+       memset ( mbr, 0, sizeof ( *mbr ) );
+       mbr->partitions[0].bootable = VDISK_MBR_BOOTABLE;
+       mbr->partitions[0].type = VDISK_MBR_TYPE_FAT32;
+       mbr->partitions[0].start = VDISK_PARTITION_LBA;
+       mbr->partitions[0].length = VDISK_PARTITION_COUNT;
+       mbr->signature = VDISK_MBR_SIGNATURE;
+       mbr->magic = VDISK_MBR_MAGIC;
+}
+
+/**
+ * Read from virtual Volume Boot Record
+ *
+ * @v lba              Starting LBA
+ * @v count            Number of blocks to read
+ * @v data             Data buffer
+ */
+static void vdisk_vbr ( uint64_t lba __unused, unsigned int count __unused,
+                       void *data ) {
+       struct vdisk_vbr *vbr = data;
+
+       /* Construct VBR */
+       memset ( vbr, 0, sizeof ( *vbr ) );
+       vbr->jump[0] = VDISK_VBR_JUMP_WTF_MS;
+       memcpy ( vbr->oemid, VDISK_VBR_OEMID, sizeof ( vbr->oemid ) );
+       vbr->bytes_per_sector = VDISK_SECTOR_SIZE;
+       vbr->sectors_per_cluster = VDISK_CLUSTER_COUNT;
+       vbr->reserved_sectors = VDISK_RESERVED_COUNT;
+       vbr->fats = 1;
+       vbr->media = VDISK_VBR_MEDIA;
+       vbr->sectors_per_track = VDISK_SECTORS_PER_TRACK;
+       vbr->heads = VDISK_HEADS;
+       vbr->hidden_sectors = VDISK_VBR_LBA;
+       vbr->sectors = VDISK_PARTITION_COUNT;
+       vbr->sectors_per_fat = VDISK_SECTORS_PER_FAT;
+       vbr->root = VDISK_ROOT_CLUSTER;
+       vbr->fsinfo = VDISK_FSINFO_SECTOR;
+       vbr->backup = VDISK_BACKUP_VBR_SECTOR;
+       vbr->signature = VDISK_VBR_SIGNATURE;
+       vbr->serial = VDISK_VBR_SERIAL;
+       memcpy ( vbr->label, VDISK_VBR_LABEL, sizeof ( vbr->label ) );
+       memcpy ( vbr->system, VDISK_VBR_SYSTEM, sizeof ( vbr->system ) );
+       vbr->magic = VDISK_VBR_MAGIC;
+}
+
+/**
+ * Read from virtual FSInfo
+ *
+ * @v lba              Starting LBA
+ * @v count            Number of blocks to read
+ * @v data             Data buffer
+ */
+static void vdisk_fsinfo ( uint64_t lba __unused, unsigned int count __unused,
+                          void *data ) {
+       struct vdisk_fsinfo *fsinfo = data;
+
+       /* Construct FSInfo */
+       memset ( fsinfo, 0, sizeof ( *fsinfo ) );
+       fsinfo->magic1 = VDISK_FSINFO_MAGIC1;
+       fsinfo->magic2 = VDISK_FSINFO_MAGIC2;
+       fsinfo->next_free = VDISK_FSINFO_NEXT_FREE;
+       fsinfo->magic3 = VDISK_FSINFO_MAGIC3;
+}
+
+/**
+ * Read from virtual FAT
+ *
+ * @v lba              Starting LBA
+ * @v count            Number of blocks to read
+ * @v data             Data buffer
+ */
+static void vdisk_fat ( uint64_t lba, unsigned int count, void *data ) {
+       uint32_t *next = data;
+       uint32_t start;
+       uint32_t end;
+       uint32_t file_end_marker;
+       unsigned int i;
+
+       /* Calculate window within FAT */
+       start = ( ( lba - VDISK_FAT_LBA ) *
+                 ( VDISK_SECTOR_SIZE / sizeof ( *next ) ) );
+       end = ( start + ( count * ( VDISK_SECTOR_SIZE / sizeof ( *next ) ) ) );
+       next -= start;
+
+       /* Start by marking each cluster as chaining to the next */
+       for ( i = start ; i < end ; i++ )
+               next[i] = ( i + 1 );
+
+       /* Add first-sector special values, if applicable */
+       if ( start == 0 ) {
+               next[0] = ( ( VDISK_FAT_END_MARKER & ~0xff ) |
+                           VDISK_VBR_MEDIA );
+               for ( i = 1; i < ( VDISK_SECTOR_SIZE / sizeof ( *next ) ); i++ )
+                       next[i] = VDISK_FAT_END_MARKER;
+       }
+
+       /* Add end-of-file markers, if applicable */
+       for ( i = 0 ; i < VDISK_MAX_FILES ; i++ ) {
+               if ( vdisk_files[i].read ) {
+                       file_end_marker = ( VDISK_FILE_CLUSTER ( i ) +
+                                           ( ( vdisk_files[i].xlen - 1 ) /
+                                             VDISK_CLUSTER_SIZE ) );
+                       if ( ( file_end_marker >= start ) &&
+                            ( file_end_marker < end ) ) {
+                               next[file_end_marker] = VDISK_FAT_END_MARKER;
+                       }
+               }
+       }
+}
+
+/**
+ * Initialise empty directory
+ *
+ * @v dir              Virtual directory
+ * @ret dirent         Starting (i.e. final) directory entry
+ */
+static union vdisk_directory_entry *
+vdisk_empty_dir ( struct vdisk_directory *dir ) {
+       unsigned int i;
+
+       /* Mark all entries as present and deleted */
+       memset ( dir, 0, sizeof ( *dir ) );
+       for ( i = 0 ; i < VDISK_DIRENT_PER_SECTOR ; i++ ) {
+               dir->entry[i].deleted = VDISK_DIRENT_DELETED;
+       }
+
+       return &dir->entry[ VDISK_DIRENT_PER_SECTOR - 1 ];
+}
+
+/**
+ * Construct directory entry
+ *
+ * @v dirent           Starting (i.e. final) directory entry
+ * @v name             File name
+ * @v len              File length
+ * @v attr             File attributes
+ * @v cluster          File starting cluster
+ * @ret next           Next available directory entry
+ */
+static union vdisk_directory_entry *
+vdisk_directory_entry ( union vdisk_directory_entry *dirent, const char *name,
+                       size_t len,unsigned int attr, uint32_t cluster ) {
+       union vdisk_directory_entry *dos = dirent;
+       union vdisk_directory_entry *lfn = ( dos - 1 );
+       uint8_t *checksum_data;
+       uint8_t checksum;
+       unsigned int sequence;
+       uint16_t *lfn_char;
+       char c;
+       unsigned int i;
+
+       /* Populate directory entry (with invalid 8.3 filename) */
+       memset ( dos->dos.filename.raw, ' ', sizeof ( dos->dos.filename.raw ) );
+       dos->dos.attr = attr;
+       dos->dos.size = len;
+       dos->dos.cluster_high = ( cluster >> 16 );
+       dos->dos.cluster_low = ( cluster & 0xffff );
+
+       /* Calculate checksum of 8.3 filename */
+       checksum = 0;
+       checksum_data = dos->dos.filename.raw;
+       for ( i = 0 ; i < sizeof ( dos->dos.filename.raw ) ; i++ ) {
+               checksum = ( ( ( ( checksum & 1 ) << 7 ) |
+                              ( checksum >> 1 ) ) +
+                            *(checksum_data++) );
+       }
+
+       /* Construct long filename record */
+       lfn_char = &lfn->lfn.name_1[0];
+       sequence = 1;
+       while ( 1 ) {
+
+               /* Initialise long filename, if necessary */
+               if ( lfn->lfn.attr != VDISK_LFN_ATTR ) {
+                       lfn->lfn.sequence = sequence++;
+                       memset ( lfn->lfn.name_1, 0xff,
+                                sizeof ( lfn->lfn.name_1 ) );
+                       lfn->lfn.attr = VDISK_LFN_ATTR;
+                       lfn->lfn.checksum = checksum;
+                       memset ( lfn->lfn.name_2, 0xff,
+                                sizeof ( lfn->lfn.name_2 ) );
+                       memset ( lfn->lfn.name_3, 0xff,
+                                sizeof ( lfn->lfn.name_3 ) );
+               }
+
+               /* Add character to long filename */
+               c = *(name++);
+               *lfn_char = c;
+               if ( ! c )
+                       break;
+
+               /* Move to next character within long filename */
+               if ( lfn_char == &lfn->lfn.name_1[4] ) {
+                       lfn_char = &lfn->lfn.name_2[0];
+               } else if ( lfn_char == &lfn->lfn.name_2[5] ) {
+                       lfn_char = &lfn->lfn.name_3[0];
+               } else if ( lfn_char == &lfn->lfn.name_3[1] ) {
+                       lfn--;
+                       lfn_char = &lfn->lfn.name_1[0];
+               } else {
+                       lfn_char++;
+               }
+       }
+       lfn->lfn.sequence |= VDISK_LFN_END;
+
+       return ( lfn - 1 );
+}
+
+/**
+ * Read subdirectories from virtual root directory
+ *
+ * @v lba              Starting LBA
+ * @v count            Number of blocks to read
+ * @v data             Data buffer
+ */
+static void vdisk_root ( uint64_t lba __unused, unsigned int count __unused,
+                        void *data ) {
+       struct vdisk_directory *dir = data;
+       union vdisk_directory_entry *dirent;
+
+       /* Construct subdirectories */
+       dirent = vdisk_empty_dir ( dir );
+       dirent = vdisk_directory_entry ( dirent, "BOOT", 0, VDISK_DIRECTORY,
+                                        VDISK_BOOT_CLUSTER );
+       dirent = vdisk_directory_entry ( dirent, "SOURCES", 0, VDISK_DIRECTORY,
+                                        VDISK_SOURCES_CLUSTER );
+       dirent = vdisk_directory_entry ( dirent, "EFI", 0, VDISK_DIRECTORY,
+                                        VDISK_EFI_CLUSTER );
+}
+
+/**
+ * Read subdirectories from virtual boot directory
+ *
+ * @v lba              Starting LBA
+ * @v count            Number of blocks to read
+ * @v data             Data buffer
+ */
+static void vdisk_boot ( uint64_t lba __unused, unsigned int count __unused,
+                        void *data ) {
+       struct vdisk_directory *dir = data;
+       union vdisk_directory_entry *dirent;
+
+       /* Construct subdirectories */
+       dirent = vdisk_empty_dir ( dir );
+       dirent = vdisk_directory_entry ( dirent, "FONTS", 0, VDISK_DIRECTORY,
+                                        VDISK_FONTS_CLUSTER );
+       dirent = vdisk_directory_entry ( dirent, "RESOURCES", 0,
+                                        VDISK_DIRECTORY,
+                                        VDISK_RESOURCES_CLUSTER );
+}
+
+/**
+ * Read subdirectories from virtual sources directory
+ *
+ * @v lba              Starting LBA
+ * @v count            Number of blocks to read
+ * @v data             Data buffer
+ */
+static void vdisk_sources ( uint64_t lba __unused, unsigned int count __unused,
+                           void *data ) {
+       struct vdisk_directory *dir = data;
+
+       /* Construct subdirectories */
+       vdisk_empty_dir ( dir );
+}
+
+/**
+ * Read subdirectories from virtual fonts directory
+ *
+ * @v lba              Starting LBA
+ * @v count            Number of blocks to read
+ * @v data             Data buffer
+ */
+static void vdisk_fonts ( uint64_t lba __unused, unsigned int count __unused,
+                         void *data ) {
+       struct vdisk_directory *dir = data;
+
+       /* Construct subdirectories */
+       vdisk_empty_dir ( dir );
+}
+
+/**
+ * Read subdirectories from virtual resources directory
+ *
+ * @v lba              Starting LBA
+ * @v count            Number of blocks to read
+ * @v data             Data buffer
+ */
+static void vdisk_resources ( uint64_t lba __unused,
+                             unsigned int count __unused, void *data ) {
+       struct vdisk_directory *dir = data;
+
+       /* Construct subdirectories */
+       vdisk_empty_dir ( dir );
+}
+
+/**
+ * Read subdirectories from virtual EFI directory
+ *
+ * @v lba              Starting LBA
+ * @v count            Number of blocks to read
+ * @v data             Data buffer
+ */
+static void vdisk_efi ( uint64_t lba __unused, unsigned int count __unused,
+                       void *data ) {
+       struct vdisk_directory *dir = data;
+       union vdisk_directory_entry *dirent;
+
+       /* Construct subdirectories */
+       dirent = vdisk_empty_dir ( dir );
+       dirent = vdisk_directory_entry ( dirent, "BOOT", 0, VDISK_DIRECTORY,
+                                        VDISK_BOOT_CLUSTER );
+       dirent = vdisk_directory_entry ( dirent, "MICROSOFT", 0,
+                                        VDISK_DIRECTORY,
+                                        VDISK_MICROSOFT_CLUSTER );
+}
+
+/**
+ * Read subdirectories from virtual Microsoft directory
+ *
+ * @v lba              Starting LBA
+ * @v count            Number of blocks to read
+ * @v data             Data buffer
+ */
+static void vdisk_microsoft ( uint64_t lba __unused,
+                             unsigned int count __unused, void *data ) {
+       struct vdisk_directory *dir = data;
+       union vdisk_directory_entry *dirent;
+
+       /* Construct subdirectories */
+       dirent = vdisk_empty_dir ( dir );
+       dirent = vdisk_directory_entry ( dirent, "BOOT", 0, VDISK_DIRECTORY,
+                                        VDISK_BOOT_CLUSTER );
+}
+
+/**
+ * Read files from virtual directory
+ *
+ * @v lba              Starting LBA
+ * @v count            Number of blocks to read
+ * @v data             Data buffer
+ */
+static void vdisk_dir_files ( uint64_t lba, unsigned int count, void *data ) {
+       struct vdisk_directory *dir;
+       union vdisk_directory_entry *dirent;
+       struct vdisk_file *file;
+       unsigned int idx;
+
+       for ( ; count ; lba++, count--, data += VDISK_SECTOR_SIZE ) {
+
+               /* Initialise directory */
+               dir = data;
+               vdisk_empty_dir ( dir );
+               dirent = &dir->entry[ VDISK_DIRENT_PER_SECTOR - 1 ];
+
+               /* Identify file */
+               idx = VDISK_FILE_DIRENT_IDX ( lba );
+               assert ( idx < ( sizeof ( vdisk_files ) /
+                                sizeof ( vdisk_files[0] ) ) );
+               file = &vdisk_files[idx];
+               if ( ! file->read )
+                       continue;
+
+               /* Populate directory entry */
+               vdisk_directory_entry ( dirent, file->name, file->xlen,
+                                       VDISK_READ_ONLY,
+                                       VDISK_FILE_CLUSTER ( idx ) );
+       }
+}
+
+/**
+ * Read from virtual file (or empty space)
+ *
+ * @v lba              Starting LBA
+ * @v count            Number of blocks to read
+ * @v data             Data buffer
+ */
+static void vdisk_file ( uint64_t lba, unsigned int count, void *data ) {
+       struct vdisk_file *file;
+       size_t offset;
+       size_t len;
+       size_t copy_len;
+       size_t pad_len;
+       size_t patch_len;
+
+       /* Construct file portion */
+       file = &vdisk_files[ VDISK_FILE_IDX ( lba ) ];
+       offset = VDISK_FILE_OFFSET ( lba );
+       len = ( count * VDISK_SECTOR_SIZE );
+
+       /* Copy any initialised-data portion */
+       copy_len = ( ( offset < file->len ) ? ( file->len - offset ) : 0 );
+       if ( copy_len > len )
+               copy_len = len;
+       if ( copy_len )
+               file->read ( file, data, offset, copy_len );
+
+       /* Zero any uninitialised-data portion */
+       pad_len = ( len - copy_len );
+       memset ( ( data + copy_len ), 0, pad_len );
+
+       /* Patch any applicable portion */
+       patch_len = ( ( offset < file->xlen ) ? ( file->xlen - offset ) : 0 );
+       if ( patch_len > len )
+               patch_len = len;
+       if ( file->patch )
+               file->patch ( file, data, offset, patch_len );
+}
+
+/** A virtual disk region */
+struct vdisk_region {
+       /** Name */
+       const char *name;
+       /** Starting LBA */
+       uint64_t lba;
+       /** Number of blocks */
+       unsigned int count;
+       /**
+        * Build data from this region
+        *
+        * @v start             Starting LBA
+        * @v count             Number of blocks to read
+        * @v data              Data buffer
+        */
+       void ( * build ) ( uint64_t lba, unsigned int count, void *data );
+};
+
+/** Define a virtual disk region */
+#define VDISK_REGION( _name, _build, _lba, _count ) {          \
+               .name = _name,                                  \
+               .lba = _lba,                                    \
+               .count = _count,                                \
+               .build = _build,                                \
+       }
+
+/** Define a virtual disk directory region */
+#define VDISK_DIRECTORY_REGION( _name, _build_subdirs, _lba ) {        \
+               .name = _name " subdirs",                       \
+               .lba = _lba,                                    \
+               .count = 1,                                     \
+               .build = _build_subdirs,                        \
+       }, {                                                    \
+               .name = _name " files",                         \
+               .lba = ( _lba + 1 ),                            \
+               .count = ( VDISK_CLUSTER_COUNT - 1 ),           \
+               .build = vdisk_dir_files,                       \
+       }
+
+/** Virtual disk regions */
+static struct vdisk_region vdisk_regions[] = {
+       VDISK_REGION ( "MBR", vdisk_mbr,
+                      VDISK_MBR_LBA, VDISK_MBR_COUNT ),
+       VDISK_REGION ( "VBR", vdisk_vbr,
+                      VDISK_VBR_LBA, VDISK_VBR_COUNT ),
+       VDISK_REGION ( "FSInfo", vdisk_fsinfo,
+                      VDISK_FSINFO_LBA, VDISK_FSINFO_COUNT ),
+       VDISK_REGION ( "VBR Backup", vdisk_vbr,
+                      VDISK_BACKUP_VBR_LBA, VDISK_BACKUP_VBR_COUNT ),
+       VDISK_REGION ( "FAT", vdisk_fat,
+                      VDISK_FAT_LBA, VDISK_FAT_COUNT ),
+       VDISK_DIRECTORY_REGION ( "Root", vdisk_root, VDISK_ROOT_LBA ),
+       VDISK_DIRECTORY_REGION ( "Boot", vdisk_boot, VDISK_BOOT_LBA ),
+       VDISK_DIRECTORY_REGION ( "Sources", vdisk_sources, VDISK_SOURCES_LBA ),
+       VDISK_DIRECTORY_REGION ( "Fonts", vdisk_fonts, VDISK_FONTS_LBA ),
+       VDISK_DIRECTORY_REGION ( "Resources", vdisk_resources,
+                                VDISK_RESOURCES_LBA ),
+       VDISK_DIRECTORY_REGION ( "EFI", vdisk_efi, VDISK_EFI_LBA ),
+       VDISK_DIRECTORY_REGION ( "Microsoft", vdisk_microsoft,
+                                VDISK_MICROSOFT_LBA ),
+};
+
+/**
+ * Read from virtual disk
+ *
+ * @v lba              Starting LBA
+ * @v count            Number of blocks to read
+ * @v data             Data buffer
+ */
+void vdisk_read ( uint64_t lba, unsigned int count, void *data ) {
+       struct vdisk_region *region;
+       void ( * build ) ( uint64_t lba, unsigned int count, void *data );
+       const char *name;
+       uint64_t start = lba;
+       uint64_t end = ( lba + count );
+       uint64_t frag_start = start;
+       uint64_t frag_end;
+       int file_idx;
+       uint64_t file_end;
+       uint64_t region_start;
+       uint64_t region_end;
+       unsigned int frag_count;
+       unsigned int i;
+
+       DBG2 ( "Read to %p from %#llx+%#x: ", data, lba, count );
+
+       do {
+               /* Initialise fragment to fill remaining space */
+               frag_end = end;
+               name = NULL;
+               build = NULL;
+
+               /* Truncate fragment and generate data */
+               file_idx = VDISK_FILE_IDX ( frag_start );
+               if ( file_idx >= 0 ) {
+
+                       /* Truncate fragment to end of file */
+                       file_end = VDISK_FILE_LBA ( file_idx + 1 );
+                       if ( frag_end > file_end )
+                               frag_end = file_end;
+
+                       /* Generate data from file */
+                       if ( file_idx < VDISK_MAX_FILES ) {
+                               name = vdisk_files[file_idx].name;
+                               build = vdisk_file;
+                       }
+
+               } else {
+
+                       /* Truncate fragment to region boundaries */
+                       for ( i = 0 ; i < ( sizeof ( vdisk_regions ) /
+                                           sizeof ( vdisk_regions[0] ) ); i++){
+                               region = &vdisk_regions[i];
+                               region_start = region->lba;
+                               region_end = ( region_start + region->count );
+
+                               /* Avoid crossing start of any region */
+                               if ( ( frag_start < region_start ) &&
+                                    ( frag_end > region_start ) ){
+                                       frag_end = region_start;
+                               }
+
+                               /* Ignore unless we overlap with this region */
+                               if ( ( frag_start >= region_end ) ||
+                                    ( frag_end <= region_start ) ) {
+                                       continue;
+                               }
+
+                               /* Avoid crossing end of region */
+                               if ( frag_end > region_end )
+                                       frag_end = region_end;
+
+                               /* Found a suitable region */
+                               name = region->name;
+                               build = region->build;
+                               break;
+                       }
+               }
+
+               /* Generate data from this region */
+               frag_count = ( frag_end - frag_start );
+               DBG2 ( "%s%s (%#x)", ( ( frag_start == start ) ? "" : ", " ),
+                      ( name ? name : "empty" ), frag_count );
+               if ( build ) {
+                       build ( frag_start, frag_count, data );
+               } else {
+                       memset ( data, 0, ( frag_count * VDISK_SECTOR_SIZE ) );
+               }
+
+               /* Move to next fragment */ 
+               frag_start += frag_count;
+               data += ( frag_count * VDISK_SECTOR_SIZE );
+
+       } while ( frag_start != end );
+
+       DBG2 ( "\n" );
+}
+
+/**
+ * Add file to virtual disk
+ *
+ * @v name             Name
+ * @v opaque           Opaque token
+ * @v len              Length
+ * @v read             Read data method
+ * @ret file           Virtual file
+ */
+struct vdisk_file * vdisk_add_file ( const char *name, void *opaque, size_t len,
+                                    void ( * read ) ( struct vdisk_file *file,
+                                                      void *data,
+                                                      size_t offset,
+                                                      size_t len ) ) {
+       static unsigned int index = 0;
+       struct vdisk_file *file;
+
+       /* Sanity check */
+       if ( index >= VDISK_MAX_FILES )
+               die ( "Too many files\n" );
+
+       /* Store file */
+       file = &vdisk_files[index++];
+       snprintf ( file->name, sizeof ( file->name ), "%s", name );
+       file->opaque = opaque;
+       file->len = len;
+       file->xlen = len;
+       file->read = read;
+       DBG ( "Using %s via %p len %#zx\n", file->name, file->opaque,
+             file->len );
+
+       return file;
+}
+
+/**
+ * Patch virtual file
+ *
+ * @v file             Virtual file
+ * @v patch            Patch method
+ */
+void vdisk_patch_file ( struct vdisk_file *file,
+                       void ( * patch ) ( struct vdisk_file *file, void *data,
+                                          size_t offset, size_t len ) ) {
+
+       /* Record patch method */
+       file->patch = patch;
+
+       /* Allow patch method to update file length */
+       patch ( file, NULL, 0, 0 );
+}
diff --git a/wimboot/wimboot-2.7.3/src/vdisk.h b/wimboot/wimboot-2.7.3/src/vdisk.h
new file mode 100644 (file)
index 0000000..7cae51c
--- /dev/null
@@ -0,0 +1,623 @@
+#ifndef _VDISK_H
+#define _VDISK_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Virtual disk emulation
+ *
+ */
+
+#include <stdint.h>
+
+/** Number of cylinders */
+#define VDISK_CYLINDERS 1024 /* Maximum possible */
+
+/** Number of heads */
+#define VDISK_HEADS 255
+
+/** Number of sectors per track */
+#define VDISK_SECTORS_PER_TRACK 63
+
+/** Sector size (in bytes) */
+#define VDISK_SECTOR_SIZE 512
+
+/** Partition start LBA */
+#define VDISK_PARTITION_LBA 128
+
+/** Cluster size (in sectors) */
+#define VDISK_CLUSTER_COUNT 64
+
+/** Cluster size (in bytes) */
+#define VDISK_CLUSTER_SIZE ( VDISK_CLUSTER_COUNT * VDISK_SECTOR_SIZE )
+
+/** Number of clusters */
+#define VDISK_CLUSTERS 0x03ffc000ULL /* Fill 2TB disk */
+
+/** Maximum number of virtual files
+ *
+ * The total number of files must be strictly less than the number of
+ * sectors per cluster.
+ */
+#define VDISK_MAX_FILES ( VDISK_CLUSTER_COUNT - 1 )
+
+/** Maximum file size (in sectors) */
+#define VDISK_FILE_COUNT 0x800000UL /* max for 32-bit address space */
+
+/** Maximum file size (in clusters) */
+#define VDISK_FILE_CLUSTERS ( VDISK_FILE_COUNT / VDISK_CLUSTER_COUNT )
+
+/** File starting LBA */
+#define VDISK_FILE_LBA( idx ) ( ( (idx) + 1 ) * VDISK_FILE_COUNT )
+
+/** File index from LBA */
+#define VDISK_FILE_IDX( lba ) ( ( (lba) / VDISK_FILE_COUNT ) - 1 )
+
+/** File offset (in bytes) from LBA */
+#define VDISK_FILE_OFFSET( lba )                                       \
+       ( ( (lba) % VDISK_FILE_COUNT ) * VDISK_SECTOR_SIZE )
+
+/** File index from directory entry LBA */
+#define VDISK_FILE_DIRENT_IDX( lba ) ( ( (lba) - 1 ) % VDISK_CLUSTER_COUNT )
+
+/** Number of sectors allocated for FAT */
+#define VDISK_SECTORS_PER_FAT                                          \
+       ( ( ( VDISK_CLUSTERS * sizeof ( uint32_t ) +                    \
+             VDISK_CLUSTER_SIZE - 1 ) / VDISK_CLUSTER_SIZE )           \
+         * VDISK_CLUSTER_COUNT )
+
+/** Number of reserved sectors */
+#define VDISK_RESERVED_COUNT VDISK_CLUSTER_COUNT
+
+/** Starting cluster number for file */
+#define VDISK_FILE_CLUSTER( idx )                                      \
+       ( ( ( ( VDISK_FILE_COUNT - VDISK_PARTITION_LBA -                \
+               VDISK_RESERVED_COUNT - VDISK_SECTORS_PER_FAT ) /        \
+             VDISK_CLUSTER_COUNT ) + 2 ) +                             \
+         ( (idx) * VDISK_FILE_CLUSTERS ) )
+
+/** Total number of sectors within partition */
+#define VDISK_PARTITION_COUNT                                          \
+       ( VDISK_RESERVED_COUNT + VDISK_SECTORS_PER_FAT +                \
+         ( VDISK_CLUSTERS * VDISK_CLUSTER_COUNT ) )
+
+/** Number of sectors */
+#define VDISK_COUNT ( VDISK_PARTITION_LBA + VDISK_PARTITION_COUNT )
+
+/** Calculate sector from cluster */
+#define VDISK_CLUSTER_SECTOR( cluster )                                        \
+       ( ( ( (cluster) - 2 ) * VDISK_CLUSTER_COUNT ) +                 \
+         VDISK_RESERVED_COUNT + VDISK_SECTORS_PER_FAT )
+
+/*****************************************************************************
+ *
+ * Master Boot Record
+ *
+ *****************************************************************************
+ */
+
+/** Master Boot Record LBA */
+#define VDISK_MBR_LBA 0x00000000
+
+/** Master Boot Record sector count */
+#define VDISK_MBR_COUNT 1
+
+/** Partition table entry */
+struct vdisk_partition {
+       /** Bootable flag */
+       uint8_t bootable;
+       /** C/H/S start address */
+       uint8_t chs_start[3];
+       /** System indicator (partition type) */
+       uint8_t type;
+       /** C/H/S end address */
+       uint8_t chs_end[3];
+       /** Linear start address */
+       uint32_t start;
+       /** Linear length */
+       uint32_t length;
+} __attribute__ (( packed ));
+
+/** Master Boot Record */
+struct vdisk_mbr {     
+       /** Code area */
+       uint8_t code[440];
+       /** Disk signature */
+       uint32_t signature;
+       /** Padding */
+       uint8_t pad[2];
+       /** Partition table */
+       struct vdisk_partition partitions[4];
+       /** 0x55aa signature */
+       uint16_t magic;
+} __attribute__ (( packed ));
+
+/** MBR boot partition indiciator */
+#define VDISK_MBR_BOOTABLE 0x80
+
+/** MBR type indicator for FAT32 */
+#define VDISK_MBR_TYPE_FAT32 0x0c
+
+/** MBR signature */
+#define VDISK_MBR_SIGNATURE 0xc0ffeeee
+
+/** MBR magic */
+#define VDISK_MBR_MAGIC 0xaa55
+
+/*****************************************************************************
+ *
+ * Volume Boot Record
+ *
+ *****************************************************************************
+ */
+
+/** Volume Boot Record LBA */
+#define VDISK_VBR_LBA VDISK_PARTITION_LBA
+
+/** Volume Boot Record sector count */
+#define VDISK_VBR_COUNT 1
+
+/** Volume Boot Record */
+struct vdisk_vbr {
+       /** Jump instruction */
+       uint8_t jump[3];
+       /** OEM identifier */
+       char oemid[8];
+       /** Number of bytes per sector */
+       uint16_t bytes_per_sector;
+       /** Number of sectors per cluster */
+       uint8_t sectors_per_cluster;
+       /** Number of reserved sectors */
+       uint16_t reserved_sectors;
+       /** Number of FATs */
+       uint8_t fats;
+       /** Number of root directory entries (FAT12/FAT16 only) */
+       uint16_t root_directory_entries;
+       /** Total number of sectors (0 if more than 65535) */
+       uint16_t sectors_short;
+       /** Media descriptor type */
+       uint8_t media;
+       /** Number of sectors per FAT (FAT12/FAT16 only) */
+       uint16_t sectors_per_fat_short;
+       /** Number of sectors per track */
+       uint16_t sectors_per_track;
+       /** Number of heads */
+       uint16_t heads;
+       /** Number of hidden sectors (i.e. LBA of start of partition) */
+       uint32_t hidden_sectors;
+       /** Total number of sectors */
+       uint32_t sectors;
+
+       /* FAT32-specific fields */
+
+       /** Sectors per FAT */
+       uint32_t sectors_per_fat;
+       /** Flags */
+       uint16_t flags;
+       /** FAT version number */
+       uint16_t version;
+       /** Root directory cluster */
+       uint32_t root;
+       /** FSInfo sector */
+       uint16_t fsinfo;
+       /** Backup boot sector */
+       uint16_t backup;
+       /** Reserved */
+       uint8_t reserved[12];
+       /** Drive number */
+       uint8_t drive;
+       /** Windows NT flags */
+       uint8_t nt_flags;
+       /** Signature */
+       uint8_t signature;
+       /** Volume ID serial */
+       uint32_t serial;
+       /** Label (space-padded) */
+       char label[11];
+       /** System identifier */
+       char system[8];
+       /** Boot code */
+       uint8_t code[420];
+       /** 0x55aa signature */
+       uint16_t magic;
+} __attribute__ (( packed ));
+
+/** VBR jump instruction
+ *
+ * bootmgr.exe will actually fail unless this is present.  Someone
+ * must read specification documents without bothering to understand
+ * what's really happening.
+ */
+#define VDISK_VBR_JUMP_WTF_MS 0xe9
+
+/** VBR OEM ID */
+#define VDISK_VBR_OEMID "wimboot\0"
+
+/** VBR media type */
+#define VDISK_VBR_MEDIA 0xf8
+
+/** VBR signature */
+#define VDISK_VBR_SIGNATURE 0x29
+
+/** VBR serial number */
+#define VDISK_VBR_SERIAL 0xf00df00d
+
+/** VBR label */
+#define VDISK_VBR_LABEL "wimboot    "
+
+/** VBR system identifier */
+#define VDISK_VBR_SYSTEM "FAT32   "
+
+/** VBR magic */
+#define VDISK_VBR_MAGIC 0xaa55
+
+/*****************************************************************************
+ *
+ * FSInfo
+ *
+ *****************************************************************************
+ */
+
+/** FSInfo sector */
+#define VDISK_FSINFO_SECTOR 0x00000001
+
+/** FSInfo LBA */
+#define VDISK_FSINFO_LBA ( VDISK_VBR_LBA + VDISK_FSINFO_SECTOR )
+
+/** FSInfo sector count */
+#define VDISK_FSINFO_COUNT 1
+
+/** FSInfo */
+struct vdisk_fsinfo {
+       /** First signature */
+       uint32_t magic1;
+       /** Reserved */
+       uint8_t reserved_1[480];
+       /** Second signature */
+       uint32_t magic2;
+       /** Free cluster count */
+       uint32_t free_count;
+       /** Next free cluster */
+       uint32_t next_free;
+       /** Reserved */
+       uint8_t reserved_2[12];
+       /** Third signature */
+       uint32_t magic3;
+} __attribute__ (( packed ));
+
+/** FSInfo first signature */
+#define VDISK_FSINFO_MAGIC1 0x41615252
+
+/** FSInfo second signature */
+#define VDISK_FSINFO_MAGIC2 0x61417272
+
+/** FSInfo next free cluster */
+#define VDISK_FSINFO_NEXT_FREE 0xffffffff /* No free clusters */
+
+/** FSInfo third signature */
+#define VDISK_FSINFO_MAGIC3 0xaa550000
+
+/*****************************************************************************
+ *
+ * Backup Volume Boot Record
+ *
+ *****************************************************************************
+ */
+
+/** Backup Volume Boot Record sector */
+#define VDISK_BACKUP_VBR_SECTOR 0x00000006
+
+/** Backup Volume Boot Record LBA */
+#define VDISK_BACKUP_VBR_LBA ( VDISK_VBR_LBA + VDISK_BACKUP_VBR_SECTOR )
+
+/** Backup Volume Boot Record sector count */
+#define VDISK_BACKUP_VBR_COUNT 1
+
+/*****************************************************************************
+ *
+ * File Allocation Table
+ *
+ *****************************************************************************
+ */
+
+/** FAT sector */
+#define VDISK_FAT_SECTOR VDISK_RESERVED_COUNT
+
+/** FAT LBA */
+#define VDISK_FAT_LBA ( VDISK_VBR_LBA + VDISK_FAT_SECTOR )
+
+/** FAT sector count */
+#define VDISK_FAT_COUNT VDISK_SECTORS_PER_FAT
+
+/** FAT end marker */
+#define VDISK_FAT_END_MARKER 0x0ffffff8
+
+/*****************************************************************************
+ *
+ * Directory entries
+ *
+ *****************************************************************************
+ */
+
+/** An 8.3 filename record */
+struct vdisk_short_filename {
+       /** Filename */
+       union {
+               /** Structured 8.3 base name and extension */
+               struct {
+                       /** Base name */
+                       char base[8];
+                       /** Extension */
+                       char ext[3];
+               } __attribute__ (( packed ));
+               /** Raw bytes */
+               uint8_t raw[11];
+       } filename;
+       /** Attributes */
+       uint8_t attr;
+       /** Reserved */
+       uint8_t reserved;
+       /** Creation time in tenths of a second */
+       uint8_t created_deciseconds;
+       /** Creation time (HMS packed) */
+       uint16_t created_time;
+       /** Creation date (YMD packed) */
+       uint16_t created_date;
+       /** Last accessed date (YMD packed) */
+       uint16_t accessed_date;
+       /** High 16 bits of starting cluster number */
+       uint16_t cluster_high;
+       /** Modification time (HMS packed) */
+       uint16_t modified_time;
+       /** Modification date (YMD packed) */
+       uint16_t modified_date;
+       /** Low 16 bits of starting cluster number */
+       uint16_t cluster_low;
+       /** Size */
+       uint32_t size;
+} __attribute__ (( packed ));
+
+/** A long filename record */
+struct vdisk_long_filename {
+       /** Sequence number */
+       uint8_t sequence;
+       /** Name characters */
+       uint16_t name_1[5];
+       /** Attributes */
+       uint8_t attr;
+       /** Type */
+       uint8_t type;
+       /** Checksum of 8.3 name */
+       uint8_t checksum;
+       /** Name characters */
+       uint16_t name_2[6];
+       /** Reserved */
+       uint16_t reserved;
+       /** Name characters */
+       uint16_t name_3[2];
+} __attribute__ (( packed ));
+
+/** Directory entry attributes */
+enum vdisk_directory_entry_attributes {
+       VDISK_READ_ONLY = 0x01,
+       VDISK_HIDDEN = 0x02,
+       VDISK_SYSTEM = 0x04,
+       VDISK_VOLUME_LABEL = 0x08,
+       VDISK_DIRECTORY = 0x10,
+};
+
+/** Long filename end-of-sequence marker */
+#define VDISK_LFN_END 0x40
+
+/** Long filename attributes */
+#define VDISK_LFN_ATTR \
+       ( VDISK_READ_ONLY | VDISK_HIDDEN | VDISK_SYSTEM | VDISK_VOLUME_LABEL )
+
+/** A directory entry */
+union vdisk_directory_entry {
+       /** Deleted file marker */
+       uint8_t deleted;
+       /** 8.3 filename */
+       struct vdisk_short_filename dos;
+       /** Long filename */
+       struct vdisk_long_filename lfn;
+} __attribute__ (( packed ));
+
+/** Magic marker for deleted files */
+#define VDISK_DIRENT_DELETED 0xe5
+
+/** Number of directory entries per sector */
+#define VDISK_DIRENT_PER_SECTOR                                        \
+       ( VDISK_SECTOR_SIZE /                                   \
+         sizeof ( union vdisk_directory_entry ) )
+
+/** A directory sector */
+struct vdisk_directory {
+       /** Entries */
+       union vdisk_directory_entry entry[VDISK_DIRENT_PER_SECTOR];
+} __attribute__ (( packed ));
+
+/*****************************************************************************
+ *
+ * Root directory
+ *
+ *****************************************************************************
+ */
+
+/** Root directory cluster */
+#define VDISK_ROOT_CLUSTER 2
+
+/** Root directory sector */
+#define VDISK_ROOT_SECTOR VDISK_CLUSTER_SECTOR ( VDISK_ROOT_CLUSTER )
+
+/** Root directory LBA */
+#define VDISK_ROOT_LBA ( VDISK_VBR_LBA + VDISK_ROOT_SECTOR )
+
+/*****************************************************************************
+ *
+ * Boot directory
+ *
+ *****************************************************************************
+ */
+
+/** Boot directory cluster */
+#define VDISK_BOOT_CLUSTER 3
+
+/** Boot directory sector */
+#define VDISK_BOOT_SECTOR VDISK_CLUSTER_SECTOR ( VDISK_BOOT_CLUSTER )
+
+/** Boot directory LBA */
+#define VDISK_BOOT_LBA ( VDISK_VBR_LBA + VDISK_BOOT_SECTOR )
+
+/*****************************************************************************
+ *
+ * Sources directory
+ *
+ *****************************************************************************
+ */
+
+/** Sources directory cluster */
+#define VDISK_SOURCES_CLUSTER 4
+
+/** Sources directory sector */
+#define VDISK_SOURCES_SECTOR VDISK_CLUSTER_SECTOR ( VDISK_SOURCES_CLUSTER )
+
+/** Sources directory LBA */
+#define VDISK_SOURCES_LBA ( VDISK_VBR_LBA + VDISK_SOURCES_SECTOR )
+
+/*****************************************************************************
+ *
+ * Fonts directory
+ *
+ *****************************************************************************
+ */
+
+/** Fonts directory cluster */
+#define VDISK_FONTS_CLUSTER 5
+
+/** Fonts directory sector */
+#define VDISK_FONTS_SECTOR VDISK_CLUSTER_SECTOR ( VDISK_FONTS_CLUSTER )
+
+/** Fonts directory LBA */
+#define VDISK_FONTS_LBA ( VDISK_VBR_LBA + VDISK_FONTS_SECTOR )
+
+/*****************************************************************************
+ *
+ * Resources directory
+ *
+ *****************************************************************************
+ */
+
+/** Resources directory cluster */
+#define VDISK_RESOURCES_CLUSTER 6
+
+/** Resources directory sector */
+#define VDISK_RESOURCES_SECTOR VDISK_CLUSTER_SECTOR ( VDISK_RESOURCES_CLUSTER )
+
+/** Resources directory LBA */
+#define VDISK_RESOURCES_LBA ( VDISK_VBR_LBA + VDISK_RESOURCES_SECTOR )
+
+/*****************************************************************************
+ *
+ * EFI directory
+ *
+ *****************************************************************************
+ */
+
+/** EFI directory cluster */
+#define VDISK_EFI_CLUSTER 7
+
+/** EFI directory sector */
+#define VDISK_EFI_SECTOR VDISK_CLUSTER_SECTOR ( VDISK_EFI_CLUSTER )
+
+/** EFI directory LBA */
+#define VDISK_EFI_LBA ( VDISK_VBR_LBA + VDISK_EFI_SECTOR )
+
+/*****************************************************************************
+ *
+ * Microsoft directory
+ *
+ *****************************************************************************
+ */
+
+/** Microsoft directory cluster */
+#define VDISK_MICROSOFT_CLUSTER 8
+
+/** Microsoft directory sector */
+#define VDISK_MICROSOFT_SECTOR VDISK_CLUSTER_SECTOR ( VDISK_MICROSOFT_CLUSTER )
+
+/** Microsoft directory LBA */
+#define VDISK_MICROSOFT_LBA ( VDISK_VBR_LBA + VDISK_MICROSOFT_SECTOR )
+
+/*****************************************************************************
+ *
+ * Files
+ *
+ *****************************************************************************
+ */
+
+/** Maximum virtual filename length (excluding NUL) */
+#define VDISK_NAME_LEN 31
+
+/** A virtual file */
+struct vdisk_file {
+       /** Filename */
+       char name[ VDISK_NAME_LEN + 1 /* NUL */ ];
+       /** Opaque token */
+       void *opaque;
+       /** Length (excluding any zero-padding) */
+       size_t len;
+       /** Length (including any zero-padding) */
+       size_t xlen;
+       /** Read data
+        *
+        * @v file              Virtual file
+        * @v data              Data buffer
+        * @v offset            Starting offset
+        * @v len               Length
+        */
+       void ( * read ) ( struct vdisk_file *file, void *data, size_t offset,
+                         size_t len );
+       /** Patch data (optional)
+        *
+        * @v file              Virtual file
+        * @v data              Data buffer
+        * @v offset            Starting offset
+        * @v len               Length
+        */
+       void ( * patch ) ( struct vdisk_file *file, void *data, size_t offset,
+                          size_t len );
+};
+
+extern struct vdisk_file vdisk_files[VDISK_MAX_FILES];
+
+extern void vdisk_read ( uint64_t lba, unsigned int count, void *data );
+extern struct vdisk_file *
+vdisk_add_file ( const char *name, void *opaque, size_t len,
+                void ( * read ) ( struct vdisk_file *file, void *data,
+                                  size_t offset, size_t len ) );
+extern void
+vdisk_patch_file ( struct vdisk_file *file,
+                  void ( * patch ) ( struct vdisk_file *file, void *data,
+                                     size_t offset, size_t len ) );
+
+#endif /* _VDISK_H */
diff --git a/wimboot/wimboot-2.7.3/src/vsprintf.c b/wimboot/wimboot-2.7.3/src/vsprintf.c
new file mode 100644 (file)
index 0000000..ad30469
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Quick and dirty wrapper around iPXE's unmodified vsprintf.c
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "wimboot.h"
+
+#define FILE_LICENCE(x)
+
+#include "ipxe/vsprintf.c"
diff --git a/wimboot/wimboot-2.7.3/src/wchar.h b/wimboot/wimboot-2.7.3/src/wchar.h
new file mode 100644 (file)
index 0000000..e7639e6
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef _WCHAR_H
+#define _WCHAR_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Wide characters
+ *
+ */
+
+#include <stdint.h>
+
+typedef void mbstate_t;
+
+/**
+ * Convert wide character to multibyte sequence
+ *
+ * @v buf              Buffer
+ * @v wc               Wide character
+ * @v ps               Shift state
+ * @ret len            Number of characters written
+ *
+ * This is a stub implementation, sufficient to handle basic ASCII
+ * characters.
+ */
+static inline size_t wcrtomb ( char *buf, wchar_t wc,
+                              mbstate_t *ps __attribute__ (( unused )) ) {
+       *buf = wc;
+       return 1;
+}
+
+extern int wcscasecmp ( const wchar_t *str1, const wchar_t *str2 );
+extern size_t wcslen ( const wchar_t *str );
+extern wchar_t * wcschr ( const wchar_t *str, wchar_t c );
+extern char *strchr(const char *str, char c);
+
+#endif /* _WCHAR_H */
diff --git a/wimboot/wimboot-2.7.3/src/wctype.h b/wimboot/wimboot-2.7.3/src/wctype.h
new file mode 100644 (file)
index 0000000..de70735
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef _WCTYPE_H
+#define _WCTYPE_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Wide character types
+ *
+ * We don't actually care about wide characters.  Internationalisation
+ * is a user interface concern, and has absolutely no place in the
+ * boot process.  However, UEFI uses wide characters and so we have to
+ * at least be able to handle the ASCII subset of UCS-2.
+ *
+ */
+
+#include <ctype.h>
+
+static inline int iswlower ( wint_t c ) {
+       return islower ( c );
+}
+
+static inline int iswupper ( wint_t c ) {
+       return isupper ( c );
+}
+
+static inline int towupper ( wint_t c ) {
+       return toupper ( c );
+}
+
+static inline int iswspace ( wint_t c ) {
+       return isspace ( c );
+}
+
+#endif /* _WCTYPE_H */
diff --git a/wimboot/wimboot-2.7.3/src/wim.c b/wimboot/wimboot-2.7.3/src/wim.c
new file mode 100644 (file)
index 0000000..614305c
--- /dev/null
@@ -0,0 +1,544 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * WIM images
+ *
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+#include <assert.h>
+#include "wimboot.h"
+#include "vdisk.h"
+#include "lzx.h"
+#include "wim.h"
+
+/** WIM chunk buffer */
+static struct wim_chunk_buffer wim_chunk_buffer;
+
+/**
+ * Get WIM header
+ *
+ * @v file             Virtual file
+ * @v header           WIM header to fill in
+ * @ret rc             Return status code
+ */
+int wim_header ( struct vdisk_file *file, struct wim_header *header ) {
+
+       /* Sanity check */
+       if ( sizeof ( *header ) > file->len ) {
+               DBG ( "WIM file too short (%#zx bytes)\n", file->len );
+               return -1;
+       }
+
+       /* Read WIM header */
+       file->read ( file, header, 0, sizeof ( *header ) );
+
+       return 0;
+}
+
+/**
+ * Get compressed chunk offset
+ *
+ * @v file             Virtual file
+ * @v resource         Resource
+ * @v chunk            Chunk number
+ * @v offset           Offset to fill in
+ * @ret rc             Return status code
+ */
+static int wim_chunk_offset ( struct vdisk_file *file,
+                             struct wim_resource_header *resource,
+                             unsigned int chunk, size_t *offset ) {
+       size_t zlen = ( resource->zlen__flags & WIM_RESHDR_ZLEN_MASK );
+       unsigned int chunks;
+       size_t offset_offset;
+       size_t offset_len;
+       size_t chunks_len;
+       union {
+               uint32_t offset_32;
+               uint64_t offset_64;
+       } u;
+
+       /* Special case: zero-length files have no chunks */
+       if ( ! resource->len ) {
+               *offset = 0;
+               return 0;
+       }
+
+       /* Calculate chunk parameters */
+       chunks = ( ( resource->len + WIM_CHUNK_LEN - 1 ) / WIM_CHUNK_LEN );
+       offset_len = ( ( resource->len > 0xffffffffULL ) ?
+                      sizeof ( u.offset_64 ) : sizeof ( u.offset_32 ) );
+       chunks_len = ( ( chunks - 1 ) * offset_len );
+
+       /* Sanity check */
+       if ( chunks_len > zlen ) {
+               DBG ( "Resource too short for %d chunks\n", chunks );
+               return -1;
+       }
+
+       /* Special case: chunk 0 has no offset field */
+       if ( ! chunk ) {
+               *offset = chunks_len;
+               return 0;
+       }
+
+       /* Treat out-of-range chunks as being at the end of the
+        * resource, to allow for length calculation on the final
+        * chunk.
+        */
+       if ( chunk >= chunks ) {
+               *offset = zlen;
+               return 0;
+       }
+
+       /* Otherwise, read the chunk offset */
+       offset_offset = ( ( chunk - 1 ) * offset_len );
+       file->read ( file, &u, ( resource->offset + offset_offset ),
+                    offset_len );
+       *offset = ( chunks_len + ( ( offset_len == sizeof ( u.offset_64 ) ) ?
+                                  u.offset_64 : u.offset_32 ) );
+       if ( *offset > zlen ) {
+               DBG ( "Chunk %d offset lies outside resource\n", chunk );
+               return -1;
+       }
+       return 0;
+}
+
+/**
+ * Read chunk from a compressed resource
+ *
+ * @v file             Virtual file
+ * @v header           WIM header
+ * @v resource         Resource
+ * @v chunk            Chunk number
+ * @v buf              Chunk buffer
+ * @ret rc             Return status code
+ */
+static int wim_chunk ( struct vdisk_file *file, struct wim_header *header,
+                      struct wim_resource_header *resource,
+                      unsigned int chunk, struct wim_chunk_buffer *buf ) {
+       ssize_t ( * decompress ) ( const void *data, size_t len, void *buf );
+       unsigned int chunks;
+       size_t offset;
+       size_t next_offset;
+       size_t len;
+       size_t expected_out_len;
+       ssize_t out_len;
+       int rc;
+
+       /* Get chunk compressed data offset and length */
+       if ( ( rc = wim_chunk_offset ( file, resource, chunk,
+                                      &offset ) ) != 0 )
+               return rc;
+       if ( ( rc = wim_chunk_offset ( file, resource, ( chunk + 1 ),
+                                      &next_offset ) ) != 0 )
+               return rc;
+       len = ( next_offset - offset );
+
+       /* Calculate uncompressed length */
+       assert ( resource->len > 0 );
+       chunks = ( ( resource->len + WIM_CHUNK_LEN - 1 ) / WIM_CHUNK_LEN );
+       expected_out_len = WIM_CHUNK_LEN;
+       if ( chunk >= ( chunks - 1 ) )
+               expected_out_len -= ( -resource->len & ( WIM_CHUNK_LEN - 1 ) );
+
+       /* Read possibly-compressed data */
+       if ( len == expected_out_len ) {
+
+               /* Chunk did not compress; read raw data */
+               file->read ( file, buf->data, ( resource->offset + offset ),
+                            len );
+
+       } else {
+               uint8_t zbuf[len];
+
+               /* Read compressed data into a temporary buffer */
+               file->read ( file, zbuf, ( resource->offset + offset ), len );
+
+               /* Identify decompressor */
+               if ( header->flags & WIM_HDR_LZX ) {
+                       decompress = lzx_decompress;
+               } else {
+                       DBG ( "Can't handle unknown compression scheme %#08x "
+                             "for %#llx chunk %d at [%#llx+%#llx)\n",
+                             header->flags, resource->offset,
+                             chunk, ( resource->offset + offset ),
+                             ( resource->offset + offset + len ) );
+                       return -1;
+               }
+
+               /* Decompress data */
+               out_len = decompress ( zbuf, len, NULL );
+               if ( out_len < 0 )
+                       return out_len;
+               if ( ( ( size_t ) out_len ) != expected_out_len ) {
+                       DBG ( "Unexpected output length %#lx (expected %#zx)\n",
+                             out_len, expected_out_len );
+                       return -1;
+               }
+               decompress ( zbuf, len, buf->data );
+       }
+
+       return 0;
+}
+
+/**
+ * Read from a (possibly compressed) resource
+ *
+ * @v file             Virtual file
+ * @v header           WIM header
+ * @v resource         Resource
+ * @v data             Data buffer
+ * @v offset           Starting offset
+ * @v len              Length
+ * @ret rc             Return status code
+ */
+int wim_read ( struct vdisk_file *file, struct wim_header *header,
+              struct wim_resource_header *resource, void *data,
+              size_t offset, size_t len ) {
+       static struct vdisk_file *cached_file;
+       static size_t cached_resource_offset;
+       static unsigned int cached_chunk;
+       size_t zlen = ( resource->zlen__flags & WIM_RESHDR_ZLEN_MASK );
+       unsigned int chunk;
+       size_t skip_len;
+       size_t frag_len;
+       int rc;
+
+       /* Sanity checks */
+       if ( ( offset + len ) > resource->len ) {
+               DBG ( "Resource too short (%#llx bytes)\n", resource->len );
+               return -1;
+       }
+       if ( ( resource->offset + zlen ) > file->len ) {
+               DBG ( "Resource exceeds length of file\n" );
+               return -1;
+       }
+
+       /* If resource is uncompressed, just read the raw data */
+       if ( ! ( resource->zlen__flags & ( WIM_RESHDR_COMPRESSED |
+                                          WIM_RESHDR_PACKED_STREAMS ) ) ) {
+               file->read ( file, data, ( resource->offset + offset ), len );
+               return 0;
+       }
+
+       /* Read from each chunk overlapping the target region */
+       while ( len ) {
+
+               /* Calculate chunk number */
+               chunk = ( offset / WIM_CHUNK_LEN );
+
+               /* Read chunk, if not already cached */
+               if ( ( file != cached_file ) ||
+                    ( resource->offset != cached_resource_offset ) ||
+                    ( chunk != cached_chunk ) ) {
+
+                       /* Read chunk */
+                       if ( ( rc = wim_chunk ( file, header, resource, chunk,
+                                               &wim_chunk_buffer ) ) != 0 )
+                               return rc;
+
+                       /* Update cache */
+                       cached_file = file;
+                       cached_resource_offset = resource->offset;
+                       cached_chunk = chunk;
+               }
+
+               /* Copy fragment from this chunk */
+               skip_len = ( offset % WIM_CHUNK_LEN );
+               frag_len = ( WIM_CHUNK_LEN - skip_len );
+               if ( frag_len > len )
+                       frag_len = len;
+               memcpy ( data, ( wim_chunk_buffer.data + skip_len ), frag_len );
+
+               /* Move to next chunk */
+               data += frag_len;
+               offset += frag_len;
+               len -= frag_len;
+       }
+
+       return 0;
+}
+
+/**
+ * Get number of images
+ *
+ * @v file             Virtual file
+ * @v header           WIM header
+ * @v count            Count of images to fill in
+ * @ret rc             Return status code
+ */
+int wim_count ( struct vdisk_file *file, struct wim_header *header,
+               unsigned int *count ) {
+       struct wim_lookup_entry entry;
+       size_t offset;
+       int rc;
+
+       /* Count metadata entries */
+       for ( offset = 0 ; ( offset + sizeof ( entry ) ) <= header->lookup.len ;
+             offset += sizeof ( entry ) ) {
+
+               /* Read entry */
+               if ( ( rc = wim_read ( file, header, &header->lookup, &entry,
+                                      offset, sizeof ( entry ) ) ) != 0 )
+                       return rc;
+
+               /* Check for metadata entries */
+               if ( entry.resource.zlen__flags & WIM_RESHDR_METADATA ) {
+                       (*count)++;
+                       DBG2 ( "...found image %d metadata at +%#zx\n",
+                              *count, offset );
+               }
+       }
+
+       return 0;
+}
+
+/**
+ * Get WIM image metadata
+ *
+ * @v file             Virtual file
+ * @v header           WIM header
+ * @v index            Image index, or 0 to use boot image
+ * @v meta             Metadata to fill in
+ * @ret rc             Return status code
+ */
+int wim_metadata ( struct vdisk_file *file, struct wim_header *header,
+                  unsigned int index, struct wim_resource_header *meta ) {
+       struct wim_lookup_entry entry;
+       size_t offset;
+       unsigned int found = 0;
+       int rc;
+
+       /* If no image index is specified, just use the boot metadata */
+       if ( index == 0 ) {
+               memcpy ( meta, &header->boot, sizeof ( *meta ) );
+               return 0;
+       }
+
+       /* Look for metadata entry */
+       for ( offset = 0 ; ( offset + sizeof ( entry ) ) <= header->lookup.len ;
+             offset += sizeof ( entry ) ) {
+
+               /* Read entry */
+               if ( ( rc = wim_read ( file, header, &header->lookup, &entry,
+                                      offset, sizeof ( entry ) ) ) != 0 )
+                       return rc;
+
+               /* Look for our target entry */
+               if ( entry.resource.zlen__flags & WIM_RESHDR_METADATA ) {
+                       found++;
+                       DBG2 ( "...found image %d metadata at +%#zx\n",
+                              found, offset );
+                       if ( found == index ) {
+                               memcpy ( meta, &entry.resource,
+                                        sizeof ( *meta ) );
+                               return 0;
+                       }
+               }
+       }
+
+       /* Fail if index was not found */
+       DBG ( "Cannot find WIM image index %d in %s\n", index, file->name );
+       return -1;
+}
+
+/**
+ * Get directory entry
+ *
+ * @v file             Virtual file
+ * @v header           WIM header
+ * @v meta             Metadata
+ * @v name             Name
+ * @v offset           Directory offset (will be updated)
+ * @v direntry         Directory entry to fill in
+ * @ret rc             Return status code
+ */
+static int wim_direntry ( struct vdisk_file *file, struct wim_header *header,
+                         struct wim_resource_header *meta,
+                         const wchar_t *name, size_t *offset,
+                         struct wim_directory_entry *direntry ) {
+       wchar_t name_buf[ wcslen ( name ) + 1 /* NUL */ ];
+       int rc;
+
+       /* Search directory */
+       for ( ; ; *offset += direntry->len ) {
+
+               /* Read length field */
+               if ( ( rc = wim_read ( file, header, meta, direntry, *offset,
+                                      sizeof ( direntry->len ) ) ) != 0 )
+                       return rc;
+
+               /* Check for end of this directory */
+               if ( ! direntry->len ) {
+                       DBG ( "...directory entry \"%ls\" not found\n", name );
+                       return -1;
+               }
+
+               /* Read fixed-length portion of directory entry */
+               if ( ( rc = wim_read ( file, header, meta, direntry, *offset,
+                                      sizeof ( *direntry ) ) ) != 0 )
+                       return rc;
+
+               /* Check name length */
+               if ( direntry->name_len > sizeof ( name_buf ) )
+                       continue;
+
+               /* Read name */
+               if ( ( rc = wim_read ( file, header, meta, &name_buf,
+                                      ( *offset + sizeof ( *direntry ) ),
+                                      sizeof ( name_buf ) ) ) != 0 )
+                       return rc;
+
+               /* Check name */
+               if ( wcscasecmp ( name, name_buf ) != 0 )
+                       continue;
+
+               DBG2 ( "...found entry \"%ls\"\n", name );
+               return 0;
+       }
+}
+
+/**
+ * Get directory entry for a path
+ *
+ * @v file             Virtual file
+ * @v header           WIM header
+ * @v meta             Metadata
+ * @v path             Path to file/directory
+ * @v offset           Directory entry offset to fill in
+ * @v direntry         Directory entry to fill in
+ * @ret rc             Return status code
+ */
+int wim_path ( struct vdisk_file *file, struct wim_header *header,
+              struct wim_resource_header *meta, const wchar_t *path,
+              size_t *offset, struct wim_directory_entry *direntry ) {
+       wchar_t path_copy[ wcslen ( path ) + 1 /* WNUL */ ];
+       struct wim_security_header security;
+       wchar_t *name;
+       wchar_t *next;
+       int rc;
+
+       /* Read security data header */
+       if ( ( rc = wim_read ( file, header, meta, &security, 0,
+                              sizeof ( security ) ) ) != 0 )
+               return rc;
+
+       /* Get root directory offset */
+       direntry->subdir = ( ( security.len + sizeof ( uint64_t ) - 1 ) &
+                            ~( sizeof ( uint64_t ) - 1 ) );
+
+       /* Find directory entry */
+       name = memcpy ( path_copy, path, sizeof ( path_copy ) );
+       do {
+               next = wcschr ( name, L'\\' );
+               if ( next )
+                       *next = L'\0';
+               *offset = direntry->subdir;
+               if ( ( rc = wim_direntry ( file, header, meta, name, offset,
+                                          direntry ) ) != 0 )
+                       return rc;
+               name = ( next + 1 );
+       } while ( next );
+
+       return 0;
+}
+
+/**
+ * Get file resource
+ *
+ * @v file             Virtual file
+ * @v header           WIM header
+ * @v meta             Metadata
+ * @v path             Path to file
+ * @v resource         File resource to fill in
+ * @ret rc             Return status code
+ */
+int wim_file ( struct vdisk_file *file, struct wim_header *header,
+              struct wim_resource_header *meta, const wchar_t *path,
+              struct wim_resource_header *resource ) {
+       struct wim_directory_entry direntry;
+       struct wim_lookup_entry entry;
+       size_t offset;
+       int rc;
+
+       /* Find directory entry */
+       if ( ( rc = wim_path ( file, header, meta, path, &offset,
+                              &direntry ) ) != 0 )
+               return rc;
+
+       /* File matching file entry */
+       for ( offset = 0 ; ( offset + sizeof ( entry ) ) <= header->lookup.len ;
+             offset += sizeof ( entry ) ) {
+
+               /* Read entry */
+               if ( ( rc = wim_read ( file, header, &header->lookup, &entry,
+                                      offset, sizeof ( entry ) ) ) != 0 )
+                       return rc;
+
+               /* Look for our target entry */
+               if ( memcmp ( &entry.hash, &direntry.hash,
+                             sizeof ( entry.hash ) ) == 0 ) {
+                       DBG ( "...found file \"%ls\"\n", path );
+                       memcpy ( resource, &entry.resource,
+                                sizeof ( *resource ) );
+                       return 0;
+               }
+       }
+
+       DBG ( "Cannot find file %ls\n", path );
+       return -1;
+}
+
+/**
+ * Get length of a directory
+ *
+ * @v file             Virtual file
+ * @v header           WIM header
+ * @v meta             Metadata
+ * @v offset           Directory offset
+ * @v len              Directory length to fill in (excluding terminator)
+ * @ret rc             Return status code
+ */
+int wim_dir_len ( struct vdisk_file *file, struct wim_header *header,
+                 struct wim_resource_header *meta, size_t offset,
+                 size_t *len ) {
+       struct wim_directory_entry direntry;
+       int rc;
+
+       /* Search directory */
+       for ( *len = 0 ; ; *len += direntry.len ) {
+
+               /* Read length field */
+               if ( ( rc = wim_read ( file, header, meta, &direntry,
+                                      ( offset + *len ),
+                                      sizeof ( direntry.len ) ) ) != 0 )
+                       return rc;
+
+               /* Check for end of this directory */
+               if ( ! direntry.len )
+                       return 0;
+       }
+}
diff --git a/wimboot/wimboot-2.7.3/src/wim.h b/wimboot/wimboot-2.7.3/src/wim.h
new file mode 100644 (file)
index 0000000..7ef95d6
--- /dev/null
@@ -0,0 +1,196 @@
+#ifndef _WIM_H
+#define _WIM_H
+
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * WIM images
+ *
+ * The file format is documented in the document "Windows Imaging File
+ * Format (WIM)", available from
+ * 
+ *   http://www.microsoft.com/en-us/download/details.aspx?id=13096
+ *
+ * The wimlib source code is also a useful reference.
+ *
+ */
+
+#include <stdint.h>
+
+/** A WIM resource header */
+struct wim_resource_header {
+       /** Compressed length and flags */
+       uint64_t zlen__flags;
+       /** Offset */
+       uint64_t offset;
+       /** Uncompressed length */
+       uint64_t len;
+} __attribute__ (( packed ));
+
+/** WIM resource header length mask */
+#define WIM_RESHDR_ZLEN_MASK 0x00ffffffffffffffULL
+
+/** WIM resource header flags */
+enum wim_resource_header_flags {
+       /** Resource contains metadata */
+       WIM_RESHDR_METADATA = ( 0x02ULL << 56 ),
+       /** Resource is compressed */
+       WIM_RESHDR_COMPRESSED = ( 0x04ULL << 56 ),
+       /** Resource is compressed using packed streams */
+       WIM_RESHDR_PACKED_STREAMS = ( 0x10ULL << 56 ),
+};
+
+/** A WIM header */
+struct wim_header {
+       /** Signature */
+       uint8_t signature[8];
+       /** Header length */
+       uint32_t header_len;
+       /** Verson */
+       uint32_t version;
+       /** Flags */
+       uint32_t flags;
+       /** Chunk length */
+       uint32_t chunk_len;
+       /** GUID */
+       uint8_t guid[16];
+       /** Part number */
+       uint16_t part;
+       /** Total number of parts */
+       uint16_t parts;
+       /** Number of images */
+       uint32_t images;
+       /** Lookup table */
+       struct wim_resource_header lookup;
+       /** XML data */
+       struct wim_resource_header xml;
+       /** Boot metadata */
+       struct wim_resource_header boot;
+       /** Boot index */
+       uint32_t boot_index;
+       /** Integrity table */
+       struct wim_resource_header integrity;
+       /** Reserved */
+       uint8_t reserved[60];
+} __attribute__ (( packed ));;
+
+/** WIM header flags */
+enum wim_header_flags {
+       /** WIM uses Xpress compresson */
+       WIM_HDR_XPRESS = 0x00020000,
+       /** WIM uses LZX compression */
+       WIM_HDR_LZX = 0x00040000,
+};
+
+/** A WIM file hash */
+struct wim_hash {
+       /** SHA-1 hash */
+       uint8_t sha1[20];
+} __attribute__ (( packed ));
+
+/** A WIM lookup table entry */
+struct wim_lookup_entry {
+       /** Resource header */
+       struct wim_resource_header resource;
+       /** Part number */
+       uint16_t part;
+       /** Reference count */
+       uint32_t refcnt;
+       /** Hash */
+       struct wim_hash hash;
+} __attribute__ (( packed ));
+
+/** WIM chunk length */
+#define WIM_CHUNK_LEN 32768
+
+/** A WIM chunk buffer */
+struct wim_chunk_buffer {
+       /** Data */
+       uint8_t data[WIM_CHUNK_LEN];
+};
+
+/** Security data */
+struct wim_security_header {
+       /** Length */
+       uint32_t len;
+       /** Number of entries */
+       uint32_t count;
+} __attribute__ (( packed ));
+
+/** Directory entry */
+struct wim_directory_entry {
+       /** Length */
+       uint64_t len;
+       /** Attributes */
+       uint32_t attributes;
+       /** Security ID */
+       uint32_t security;
+       /** Subdirectory offset */
+       uint64_t subdir;
+       /** Reserved */
+       uint8_t reserved1[16];
+       /** Creation time */
+       uint64_t created;
+       /** Last access time */
+       uint64_t accessed;
+       /** Last written time */
+       uint64_t written;
+       /** Hash */
+       struct wim_hash hash;
+       /** Reserved */
+       uint8_t reserved2[12];
+       /** Streams */
+       uint16_t streams;
+       /** Short name length */
+       uint16_t short_name_len;
+       /** Name length */
+       uint16_t name_len;
+} __attribute__ (( packed ));
+
+/** Normal file */
+#define WIM_ATTR_NORMAL 0x00000080UL
+
+/** No security information exists for this file */
+#define WIM_NO_SECURITY 0xffffffffUL
+
+/** Windows complains if the time fields are left at zero */
+#define WIM_MAGIC_TIME 0x1a7b83d2ad93000ULL
+
+extern int wim_header ( struct vdisk_file *file, struct wim_header *header );
+extern int wim_count ( struct vdisk_file *file, struct wim_header *header,
+                      unsigned int *count );
+extern int wim_metadata ( struct vdisk_file *file, struct wim_header *header,
+                         unsigned int index, struct wim_resource_header *meta);
+extern int wim_read ( struct vdisk_file *file, struct wim_header *header,
+                     struct wim_resource_header *resource, void *data,
+                     size_t offset, size_t len );
+extern int wim_path ( struct vdisk_file *file, struct wim_header *header,
+                     struct wim_resource_header *meta, const wchar_t *path,
+                     size_t *offset, struct wim_directory_entry *direntry );
+extern int wim_file ( struct vdisk_file *file, struct wim_header *header,
+                     struct wim_resource_header *meta, const wchar_t *path,
+                     struct wim_resource_header *resource );
+extern int wim_dir_len ( struct vdisk_file *file, struct wim_header *header,
+                        struct wim_resource_header *meta, size_t offset,
+                        size_t *len );
+
+#endif /* _WIM_H */
diff --git a/wimboot/wimboot-2.7.3/src/wimboot.h b/wimboot/wimboot-2.7.3/src/wimboot.h
new file mode 100644 (file)
index 0000000..7253a62
--- /dev/null
@@ -0,0 +1,159 @@
+#ifndef _WIMBOOT_H
+#define _WIMBOOT_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * WIM boot loader
+ *
+ */
+
+/** Debug switch */
+#ifndef DEBUG
+#define DEBUG 1
+#endif
+
+/** Base segment address
+ *
+ * We place everything at 2000:0000, since this region is used by the
+ * Microsoft first-stage loaders (e.g. pxeboot.n12, etfsboot.com).
+ */
+#define BASE_SEG 0x2000
+
+/** Base linear address */
+#define BASE_ADDRESS ( BASE_SEG << 4 )
+
+/** 64 bit long mode code segment */
+#define LM_CS 0x10
+
+/** 32 bit protected mode flat code segment */
+#define FLAT_CS 0x20
+
+/** 32 bit protected mode flat data segment */
+#define FLAT_DS 0x30
+
+/** 16 bit real mode code segment */
+#define REAL_CS 0x50
+
+/** 16 bit real mode data segment */
+#define REAL_DS 0x60
+
+#ifndef ASSEMBLY
+
+#include <stdint.h>
+#include <bootapp.h>
+#include <cmdline.h>
+
+/** Construct wide-character version of a string constant */
+#define L( x ) _L ( x )
+#define _L( x ) L ## x
+
+/** Page size */
+#define PAGE_SIZE 4096
+
+/**
+ * Calculate start page number
+ *
+ * @v address          Address
+ * @ret page           Start page number
+ */
+static inline unsigned int page_start ( const void *address ) {
+       return ( ( ( intptr_t ) address ) / PAGE_SIZE );
+}
+
+/**
+ * Calculate end page number
+ *
+ * @v address          Address
+ * @ret page           End page number
+ */
+static inline unsigned int page_end ( const void *address ) {
+       return ( ( ( ( intptr_t ) address ) + PAGE_SIZE - 1 ) / PAGE_SIZE );
+}
+
+/**
+ * Calculate page length
+ *
+ * @v start            Start address
+ * @v end              End address
+ * @ret num_pages      Number of pages
+ */
+static inline unsigned int page_len ( const void *start, const void *end ) {
+       return ( page_end ( end ) - page_start ( start ) );
+}
+
+/**
+ * Bochs magic breakpoint
+ *
+ */
+static inline void bochsbp ( void ) {
+       __asm__ __volatile__ ( "xchgw %bx, %bx" );
+}
+
+/** Debugging output */
+#define DBG(...) do {                                          \
+               if ( ( DEBUG & 1 ) && ( ! cmdline_quiet ) ) {   \
+                       printf ( __VA_ARGS__ );                 \
+               }                                               \
+       } while ( 0 )
+
+/** Verbose debugging output */
+#define DBG2(...) do {                                         \
+               if ( ( DEBUG & 2 ) && ( ! cmdline_quiet ) ) {   \
+                       printf ( __VA_ARGS__ );                 \
+               }                                               \
+       } while ( 0 )
+
+/* Branch prediction macros */
+#define likely( x ) __builtin_expect ( !! (x), 1 )
+#define unlikely( x ) __builtin_expect ( (x), 0 )
+
+/* Mark parameter as unused */
+#define __unused __attribute__ (( unused ))
+
+#if __x86_64__
+static inline void call_real ( struct bootapp_callback_params *params ) {
+       /* Not available in 64-bit mode */
+       ( void ) params;
+}
+static inline void call_interrupt ( struct bootapp_callback_params *params ) {
+       /* Not available in 64-bit mode */
+       ( void ) params;
+}
+static inline void reboot ( void ) {
+       /* Not available in 64-bit mode */
+}
+#else
+extern void call_real ( struct bootapp_callback_params *params );
+extern void call_interrupt ( struct bootapp_callback_params *params );
+extern void __attribute__ (( noreturn )) reboot ( void );
+#endif
+
+extern void __attribute__ (( noreturn, format ( printf, 1, 2 ) ))
+die ( const char *fmt, ... );
+
+extern unsigned long __stack_chk_guard;
+extern void init_cookie ( void );
+
+#endif /* ASSEMBLY */
+
+#endif /* _WIMBOOT_H */
diff --git a/wimboot/wimboot-2.7.3/src/wimfile.c b/wimboot/wimboot-2.7.3/src/wimfile.c
new file mode 100644 (file)
index 0000000..c009565
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * WIM virtual files
+ *
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <wchar.h>
+#include "wimboot.h"
+#include "vdisk.h"
+#include "wim.h"
+#include "wimfile.h"
+
+/** A WIM virtual file */
+struct wim_file {
+       /** Underlying virtual file */
+       struct vdisk_file *file;
+       /** WIM header */
+       struct wim_header header;
+       /** Resource */
+       struct wim_resource_header resource;
+};
+
+/** Maximum number of WIM virtual files */
+#define WIM_MAX_FILES 8
+
+/** WIM virtual files */
+static struct wim_file wim_files[WIM_MAX_FILES];
+
+/**
+ * Read from WIM virtual file
+ *
+ * @v file             Virtual file
+ * @v data             Data buffer
+ * @v offset           Offset
+ * @v len              Length
+ */
+static void wim_read_file ( struct vdisk_file *file, void *data,
+                           size_t offset, size_t len ) {
+       struct wim_file *wfile = file->opaque;
+       int rc;
+
+       /* Read from resource */
+       if ( ( rc = wim_read ( wfile->file, &wfile->header, &wfile->resource,
+                              data, offset, len ) ) != 0 ) {
+               die ( "Could not read from WIM virtual file\n" );
+       }
+}
+
+/**
+ * Add WIM virtual file
+ *
+ * @v file             Underlying virtual file
+ * @v index            Image index, or 0 to use boot image
+ * @v path             Path to file within WIM
+ * @v wname            New virtual file name
+ * @ret file           Virtual file, or NULL if not found
+ */
+struct vdisk_file * wim_add_file ( struct vdisk_file *file, unsigned int index,
+                                  const wchar_t *path, const wchar_t *wname ) {
+       static unsigned int wim_file_idx = 0;
+       struct wim_resource_header meta;
+       struct wim_file *wfile;
+       char name[ VDISK_NAME_LEN + 1 /* NUL */ ];
+       unsigned int i;
+       int rc;
+
+       /* Sanity check */
+       if ( wim_file_idx >= WIM_MAX_FILES )
+               die ( "Too many WIM files\n" );
+       wfile = &wim_files[wim_file_idx];
+
+       /* Construct ASCII file name */
+       snprintf ( name, sizeof ( name ), "%ls", wname );
+
+       /* Skip files already added explicitly */
+       for ( i = 0 ; i < VDISK_MAX_FILES ; i++ ) {
+               if ( strcasecmp ( name, vdisk_files[i].name ) == 0 )
+                       return NULL;
+       }
+
+       /* Get WIM header */
+       if ( ( rc = wim_header ( file, &wfile->header ) ) != 0 )
+               return NULL;
+
+       /* Get image metadata */
+       if ( ( rc = wim_metadata ( file, &wfile->header, index, &meta ) ) != 0 )
+               return NULL;
+
+       /* Get file resource */
+       if ( ( rc = wim_file ( file, &wfile->header, &meta, path,
+                              &wfile->resource ) ) != 0 )
+               return NULL;
+
+       /* Add virtual file */
+       wim_file_idx++;
+       wfile->file = file;
+       return vdisk_add_file ( name, wfile, wfile->resource.len,
+                               wim_read_file );
+}
+
+/**
+ * Add WIM virtual files
+ *
+ * @v file             Underlying virtual file
+ * @v index            Image index, or 0 to use boot image
+ * @v paths            List of paths to files within WIM
+ */
+void wim_add_files ( struct vdisk_file *file, unsigned int index,
+                    const wchar_t **paths ) {
+       const wchar_t **path;
+       const wchar_t *wname;
+       const wchar_t *tmp;
+
+       /* Add any existent files within the list */
+       for ( path = paths ; *path ; path++ ) {
+
+               /* Construct file name */
+               wname = *path;
+               for ( tmp = wname ; *tmp ; tmp++ ) {
+                       if ( *tmp == L'\\' )
+                               wname = ( tmp + 1 );
+               }
+
+               /* Add virtual file, if existent */
+               wim_add_file ( file, index, *path, wname );
+       }
+}
diff --git a/wimboot/wimboot-2.7.3/src/wimfile.h b/wimboot/wimboot-2.7.3/src/wimfile.h
new file mode 100644 (file)
index 0000000..d91c297
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef _WIMFILE_H
+#define _WIMFILE_H
+
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * WIM virtual files
+ *
+ */
+
+#include <wchar.h>
+
+struct vdisk_file;
+
+extern struct vdisk_file * wim_add_file ( struct vdisk_file *file,
+                                         unsigned int index,
+                                         const wchar_t *path,
+                                         const wchar_t *wname );
+extern void wim_add_files ( struct vdisk_file *file, unsigned int index,
+                           const wchar_t **paths );
+
+#endif /* _WIMFILE_H */
diff --git a/wimboot/wimboot-2.7.3/src/wimpatch.c b/wimboot/wimboot-2.7.3/src/wimpatch.c
new file mode 100644 (file)
index 0000000..fd86e50
--- /dev/null
@@ -0,0 +1,811 @@
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * WIM dynamic patching
+ *
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <assert.h>
+#include "wimboot.h"
+#include "cmdline.h"
+#include "vdisk.h"
+#include "sha1.h"
+#include "wim.h"
+#include "wimpatch.h"
+
+/** Directory into which files are injected */
+#define WIM_INJECT_DIR "\\Windows\\System32"
+
+struct wim_patch;
+
+/** A region of a patched WIM file */
+struct wim_patch_region {
+       /** Name */
+       const char *name;
+       /** Opaque token */
+       void *opaque;
+       /** Starting offset of region */
+       size_t offset;
+       /** Length of region */
+       size_t len;
+       /** Patch region
+        *
+        * @v patch             WIM patch
+        * @v region            Patch region
+        * @v data              Data buffer
+        * @v offset            Relative offset
+        * @v len               Length
+        * @ret rc              Return status code
+        */
+       int ( * patch ) ( struct wim_patch *patch,
+                         struct wim_patch_region *region,
+                         void *data, size_t offset, size_t len );
+};
+
+/** Regions of a patched WIM directory containing injected files */
+struct wim_patch_dir_regions {
+       /** Subdirectory offset within parent entry */
+       struct wim_patch_region subdir;
+       /** Copy of original directory entries */
+       struct wim_patch_region copy;
+       /** Injected file directory entries */
+       struct wim_patch_region file[VDISK_MAX_FILES];
+} __attribute__ (( packed ));
+
+/** Regions of a patched WIM file */
+union wim_patch_regions {
+       /** Structured list of regions */
+       struct {
+               /** WIM header */
+               struct wim_patch_region header;
+               /** Injected file contents */
+               struct wim_patch_region file[VDISK_MAX_FILES];
+               /** Injected lookup table */
+               struct {
+                       /** Uncompressed copy of original lookup table */
+                       struct wim_patch_region copy;
+                       /** Injected boot image metadata lookup table entry */
+                       struct wim_patch_region boot;
+                       /** Injected file lookup table entries */
+                       struct wim_patch_region file[VDISK_MAX_FILES];
+               } __attribute__ (( packed )) lookup;
+               /** Injected boot image metadata */
+               struct {
+                       /** Uncompressed copy of original metadata */
+                       struct wim_patch_region copy;
+                       /** Patched directory containing injected files */
+                       struct wim_patch_dir_regions dir;
+               } __attribute__ (( packed )) boot;
+       } __attribute__ (( packed ));
+       /** Unstructured list of regions */
+       struct wim_patch_region region[0];
+};
+
+/** An injected directory entry */
+struct wim_patch_dir_entry {
+       /** Directory entry */
+       struct wim_directory_entry dir;
+       /** Name */
+       wchar_t name[ VDISK_NAME_LEN + 1 /* wNUL */ ];
+} __attribute__ (( packed ));
+
+/** A directory containing injected files */
+struct wim_patch_dir {
+       /** Name */
+       const char *name;
+       /** Offset to parent directory entry */
+       size_t parent;
+       /** Offset to original directory entries */
+       size_t offset;
+       /** Length of original directory entries (excluding terminator) */
+       size_t len;
+       /** Offset to modified directory entries */
+       size_t subdir;
+};
+
+/** A patched WIM file */
+struct wim_patch {
+       /** Virtual file */
+       struct vdisk_file *file;
+       /** Patched WIM header */
+       struct wim_header header;
+       /** Original lookup table */
+       struct wim_resource_header lookup;
+       /** Original boot image metadata */
+       struct wim_resource_header boot;
+       /** Original boot index */
+       uint32_t boot_index;
+       /** Directory containing injected files */
+       struct wim_patch_dir dir;
+       /** Patched regions */
+       union wim_patch_regions regions;
+};
+
+/**
+ * Align WIM offset to nearest qword
+ *
+ * @v len              Length
+ * @ret len            Aligned length
+ */
+static size_t wim_align ( size_t len ) {
+       return ( ( len + 0x07 ) & ~0x07 );
+}
+
+/**
+ * Calculate WIM hash
+ *
+ * @v vfile            Virtual file
+ * @v hash             Hash to fill in
+ */
+static void wim_hash ( struct vdisk_file *vfile, struct wim_hash *hash ) {
+       uint8_t ctx[SHA1_CTX_SIZE];
+       uint8_t buf[512];
+       size_t offset;
+       size_t len;
+
+       /* Calculate SHA-1 digest */
+       sha1_init ( ctx );
+       for ( offset = 0 ; offset < vfile->len ; offset += len ) {
+
+               /* Read block */
+               len = ( vfile->len - offset );
+               if ( len > sizeof ( buf ) )
+                       len = sizeof ( buf );
+               vfile->read ( vfile, buf, offset, len );
+
+               /* Update digest */
+               sha1_update ( ctx, buf, len );
+       }
+       sha1_final ( ctx, hash->sha1 );
+}
+
+/**
+ * Determine whether or not to inject file
+ *
+ * @v vfile            Virtual file
+ * @ret inject         Inject this file
+ */
+static int wim_inject_file ( struct vdisk_file *vfile ) {
+       size_t name_len;
+       const char *ext;
+
+       /* Ignore non-existent files */
+       if ( ! vfile->read )
+               return 0;
+
+       /* Ignore wimboot itself */
+       if ( strcasecmp ( vfile->name, "wimboot" ) == 0 )
+               return 0;
+
+       /* Ignore bootmgr files */
+       if ( strcasecmp ( vfile->name, "bootmgr" ) == 0 )
+               return 0;
+       if ( strcasecmp ( vfile->name, "bootmgr.exe" ) == 0 )
+               return 0;
+
+       /* Ignore BCD files */
+       if ( strcasecmp ( vfile->name, "BCD" ) == 0 )
+               return 0;
+
+       /* Locate file extension */
+       name_len = strlen ( vfile->name );
+       ext = ( ( name_len > 4 ) ? ( vfile->name + name_len - 4 ) : "" );
+
+       /* Ignore .wim files */
+       if ( strcasecmp ( ext, ".wim" ) == 0 )
+               return 0;
+
+       /* Ignore .sdi files */
+       if ( strcasecmp ( ext, ".sdi" ) == 0 )
+               return 0;
+
+       /* Ignore .efi files */
+       if ( strcasecmp ( ext, ".efi" ) == 0 )
+               return 0;
+
+       /* Ignore .ttf files */
+       if ( strcasecmp ( ext, ".ttf" ) == 0 )
+               return 0;
+
+       return 1;
+}
+
+/**
+ * Patch WIM header
+ *
+ * @v patch            WIM patch
+ * @v region           Patch region
+ * @v data             Data buffer
+ * @v offset           Relative offset
+ * @v len              Length
+ * @ret rc             Return status code
+ */
+static int wim_patch_header ( struct wim_patch *patch,
+                             struct wim_patch_region *region,
+                             void *data, size_t offset, size_t len ) {
+       struct wim_header *header = &patch->header;
+
+       /* Sanity checks */
+       assert ( offset < sizeof ( *header ) );
+       assert ( len <= ( sizeof ( *header ) - offset ) );
+
+       /* Copy patched header */
+       if ( patch->lookup.offset != patch->header.lookup.offset ) {
+               DBG2 ( "...patched WIM %s lookup table %#llx->%#llx\n",
+                      region->name, patch->lookup.offset,
+                      patch->header.lookup.offset );
+       }
+       if ( patch->boot.offset != patch->header.boot.offset ) {
+               DBG2 ( "...patched WIM %s boot metadata %#llx->%#llx\n",
+                      region->name, patch->boot.offset,
+                      patch->header.boot.offset );
+       }
+       if ( patch->boot_index != patch->header.boot_index ) {
+               DBG2 ( "...patched WIM %s boot index %d->%d\n", region->name,
+                      patch->boot_index, patch->header.boot_index );
+       }
+       memcpy ( data, ( ( ( void * ) &patch->header ) + offset ), len );
+
+       return 0;
+}
+
+/**
+ * Patch injected file content
+ *
+ * @v patch            WIM patch
+ * @v region           Patch region
+ * @v data             Data buffer
+ * @v offset           Relative offset
+ * @v len              Length
+ * @ret rc             Return status code
+ */
+static int wim_patch_file ( struct wim_patch *patch __unused,
+                           struct wim_patch_region *region,
+                           void *data, size_t offset, size_t len ) {
+       struct vdisk_file *vfile = region->opaque;
+
+       /* Read from file */
+       vfile->read ( vfile, data, offset, len );
+
+       return 0;
+}
+
+/**
+ * Patch uncompressed copy of original lookup table
+ *
+ * @v patch            WIM patch
+ * @v region           Patch region
+ * @v data             Data buffer
+ * @v offset           Relative offset
+ * @v len              Length
+ * @ret rc             Return status code
+ */
+static int wim_patch_lookup_copy ( struct wim_patch *patch,
+                                  struct wim_patch_region *region __unused,
+                                  void *data, size_t offset, size_t len ) {
+       int rc;
+
+       /* Read original lookup table */
+       if ( ( rc = wim_read ( patch->file, &patch->header, &patch->lookup,
+                              data, offset, len ) ) != 0 )
+               return rc;
+
+       return 0;
+}
+
+/**
+ * Patch injected boot image metadata lookup table entry
+ *
+ * @v patch            WIM patch
+ * @v region           Patch region
+ * @v data             Data buffer
+ * @v offset           Relative offset
+ * @v len              Length
+ * @ret rc             Return status code
+ */
+static int wim_patch_lookup_boot ( struct wim_patch *patch,
+                                  struct wim_patch_region *region __unused,
+                                  void *data, size_t offset, size_t len ) {
+       struct wim_lookup_entry entry;
+
+       /* Sanity checks */
+       assert ( offset < sizeof ( entry ) );
+       assert ( len <= ( sizeof ( entry ) - offset ) );
+
+       /* Construct lookup table entry */
+       memset ( &entry, 0, sizeof ( entry ) );
+       memcpy ( &entry.resource, &patch->header.boot,
+                sizeof ( entry.resource ) );
+
+       /* Copy lookup table entry */
+       memcpy ( data, ( ( ( void * ) &entry ) + offset ), len );
+
+       return 0;
+}
+
+/**
+ * Patch injected file lookup table entry
+ *
+ * @v patch            WIM patch
+ * @v region           Patch region
+ * @v data             Data buffer
+ * @v offset           Relative offset
+ * @v len              Length
+ * @ret rc             Return status code
+ */
+static int wim_patch_lookup_file ( struct wim_patch *patch __unused,
+                                  struct wim_patch_region *region,
+                                  void *data, size_t offset, size_t len ) {
+       struct wim_patch_region *rfile = region->opaque;
+       struct vdisk_file *vfile = rfile->opaque;
+       struct wim_lookup_entry entry;
+
+       /* Sanity checks */
+       assert ( offset < sizeof ( entry ) );
+       assert ( len <= ( sizeof ( entry ) - offset ) );
+
+       /* Construct lookup table entry */
+       memset ( &entry, 0, sizeof ( entry ) );
+       entry.resource.offset = rfile->offset;
+       entry.resource.len = vfile->len;
+       entry.resource.zlen__flags = entry.resource.len;
+       entry.refcnt = 1;
+       wim_hash ( vfile, &entry.hash );
+
+       /* Copy lookup table entry */
+       memcpy ( data, ( ( ( void * ) &entry ) + offset ), len );
+       DBG2 ( "...patched WIM %s %s\n", region->name, vfile->name );
+
+       return 0;
+}
+
+/**
+ * Patch uncompressed copy of original boot metadata
+ *
+ * @v patch            WIM patch
+ * @v region           Patch region
+ * @v data             Data buffer
+ * @v offset           Relative offset
+ * @v len              Length
+ * @ret rc             Return status code
+ */
+static int wim_patch_boot_copy ( struct wim_patch *patch,
+                                struct wim_patch_region *region __unused,
+                                void *data, size_t offset, size_t len ) {
+       int rc;
+
+       /* Read original boot metadata */
+       if ( ( rc = wim_read ( patch->file, &patch->header, &patch->boot,
+                              data, offset, len ) ) != 0 )
+               return rc;
+
+       return 0;
+}
+
+/**
+ * Patch subdirectory offset within parent directory entry
+ *
+ * @v patch            WIM patch
+ * @v region           Patch region
+ * @v data             Data buffer
+ * @v offset           Relative offset
+ * @v len              Length
+ * @ret rc             Return status code
+ */
+static int wim_patch_dir_subdir ( struct wim_patch *patch,
+                                 struct wim_patch_region *region,
+                                 void *data, size_t offset, size_t len ) {
+       struct wim_patch_dir *dir = region->opaque;
+       uint64_t subdir = dir->subdir;
+
+       /* Sanity checks */
+       assert ( offset < sizeof ( subdir ) );
+       assert ( len <= ( sizeof ( subdir ) - offset ) );
+
+       /* Copy subdirectory offset */
+       memcpy ( data, ( ( ( void * ) &subdir ) + offset ), len );
+       DBG2 ( "...patched WIM %s %s %#llx\n", region->name, dir->name,
+              ( patch->header.boot.offset + subdir ) );
+
+       return 0;
+}
+
+/**
+ * Patch copy of original directory entries
+ *
+ * @v patch            WIM patch
+ * @v region           Patch region
+ * @v data             Data buffer
+ * @v offset           Relative offset
+ * @v len              Length
+ * @ret rc             Return status code
+ */
+static int wim_patch_dir_copy ( struct wim_patch *patch,
+                               struct wim_patch_region *region,
+                               void *data, size_t offset, size_t len ) {
+       struct wim_patch_dir *dir = region->opaque;
+       int rc;
+
+       /* Read portion of original boot metadata */
+       if ( ( rc = wim_read ( patch->file, &patch->header, &patch->boot,
+                              data, ( dir->offset + offset ), len ) ) != 0 )
+               return rc;
+
+       return 0;
+}
+
+/**
+ * Patch injected directory entries
+ *
+ * @v patch            WIM patch
+ * @v region           Patch region
+ * @v data             Data buffer
+ * @v offset           Relative offset
+ * @v len              Length
+ * @ret rc             Return status code
+ */
+static int wim_patch_dir_file ( struct wim_patch *patch __unused,
+                               struct wim_patch_region *region,
+                               void *data, size_t offset, size_t len ) {
+       struct wim_patch_region *rfile = region->opaque;
+       struct vdisk_file *vfile = rfile->opaque;
+       struct wim_patch_dir_entry entry;
+       size_t name_len = strlen ( vfile->name );
+       unsigned int i;
+
+       /* Sanity checks */
+       assert ( offset < sizeof ( entry ) );
+       assert ( len <= ( sizeof ( entry ) - offset ) );
+
+       /* Construct directory entry */
+       memset ( &entry, 0, sizeof ( entry ) );
+       entry.dir.len = wim_align ( sizeof ( entry ) );
+       entry.dir.attributes = WIM_ATTR_NORMAL;
+       entry.dir.security = WIM_NO_SECURITY;
+       entry.dir.created = WIM_MAGIC_TIME;
+       entry.dir.accessed = WIM_MAGIC_TIME;
+       entry.dir.written = WIM_MAGIC_TIME;
+       wim_hash ( vfile, &entry.dir.hash );
+       entry.dir.name_len = ( name_len * sizeof ( entry.name[0] ) );
+       for ( i = 0 ; i < name_len ; i++ )
+               entry.name[i] = vfile->name[i];
+
+       /* Copy directory entry */
+       memcpy ( data, ( ( ( void * ) &entry ) + offset ), len );
+       DBG2 ( "...patched WIM %s %s\n", region->name, vfile->name );
+
+       return 0;
+}
+
+/**
+ * Patch WIM region
+ *
+ * @v patch            WIM patch
+ * @v region           Patch region
+ * @v data             Data buffer
+ * @v offset           Relative offset
+ * @v len              Length
+ * @ret rc             Return status code
+ */
+static int wim_patch_region ( struct wim_patch *patch,
+                             struct wim_patch_region *region,
+                             void *data, size_t offset, size_t len ) {
+       size_t skip;
+       int rc;
+
+       /* Skip unused regions */
+       if ( ! region->patch )
+               return 0;
+
+       /* Skip any data before this region */
+       skip = ( ( region->offset > offset ) ?
+                ( region->offset - offset ) : 0 );
+       if ( skip >= len )
+               return 0;
+       data += skip;
+       offset += skip;
+       len -= skip;
+
+       /* Convert to relative offset within this region */
+       offset -= region->offset;
+
+       /* Skip any data after this region */
+       if ( offset >= region->len )
+               return 0;
+       if ( len > ( region->len - offset ) )
+               len = ( region->len - offset );
+
+       /* Patch this region */
+       if ( ( rc = region->patch ( patch, region, data, offset, len ) ) != 0 )
+               return rc;
+       DBG2 ( "...patched WIM %s at [%#zx,%#zx)\n", region->name,
+              ( region->offset + offset ), ( region->offset + offset + len ) );
+
+       return 0;
+}
+
+/**
+ * Construct patched WIM region
+ *
+ * @v region           Patched region to fill in
+ * @v name             Name
+ * @v opaque           Opaque data
+ * @v offset           Offset
+ * @v len              Length
+ * @v patch            Patch method
+ * @ret offset         Next offset
+ */
+static inline __attribute__ (( always_inline )) size_t
+wim_construct_region ( struct wim_patch_region *region, const char *name,
+                      void *opaque, size_t offset, size_t len,
+                      int ( * patch ) ( struct wim_patch *patch,
+                                        struct wim_patch_region *region,
+                                        void *data, size_t offset,
+                                        size_t len ) ) {
+
+       DBG ( "...patching WIM %s at [%#zx,%#zx)\n",
+             name, offset, ( offset + len ) );
+       region->name = name;
+       region->opaque = opaque;
+       region->offset = offset;
+       region->len = len;
+       region->patch = patch;
+       return ( offset + len );
+}
+
+/**
+ * Construct patch WIM directory regions
+ *
+ * @v patch            WIM patch
+ * @v dir              Patched directory
+ * @v offset           Offset
+ * @v regions          Patched directory regions to fill in
+ * @ret offset         Next offset
+ */
+static size_t wim_construct_dir ( struct wim_patch *patch,
+                                 struct wim_patch_dir *dir, size_t offset,
+                                 struct wim_patch_dir_regions *regions ) {
+       struct wim_patch_dir_entry *entry;
+       struct wim_patch_region *rfile;
+       size_t boot_offset = patch->header.boot.offset;
+       unsigned int i;
+
+       DBG ( "...patching WIM directory at %#zx from [%#zx,%#zx)\n",
+             ( boot_offset + dir->parent ), ( boot_offset + dir->offset ),
+             ( boot_offset + dir->offset + dir->len ) );
+
+       /* Align directory entries */
+       offset = wim_align ( offset );
+       dir->subdir = ( offset - patch->header.boot.offset );
+
+       /* Construct injected file directory entries */
+       for ( i = 0 ; i < VDISK_MAX_FILES ; i++ ) {
+               rfile = &patch->regions.file[i];
+               if ( ! rfile->patch )
+                       continue;
+               offset = wim_construct_region ( &regions->file[i], "dir.file",
+                                               rfile, offset,
+                                               sizeof ( *entry ),
+                                               wim_patch_dir_file );
+               offset = wim_align ( offset );
+       }
+
+       /* Construct copy of original directory entries */
+       offset = wim_construct_region ( &regions->copy, dir->name, dir, offset,
+                                       dir->len, wim_patch_dir_copy );
+
+       /* Allow space for directory terminator */
+       offset += sizeof ( entry->dir.len );
+
+       /* Construct subdirectory offset within parent directory entry */
+       wim_construct_region ( &regions->subdir, "dir.subdir", dir,
+                              ( boot_offset + dir->parent +
+                                offsetof ( typeof ( entry->dir ), subdir ) ),
+                              sizeof ( entry->dir.subdir ),
+                              wim_patch_dir_subdir );
+
+       return offset;
+}
+
+/**
+ * Construct WIM patch
+ *
+ * @v file             Virtual file
+ * @v boot_index       New boot index (or zero)
+ * @v inject           Inject files into WIM
+ * @v patch            Patch to fill in
+ * @ret rc             Return status code
+ */
+static int wim_construct_patch ( struct vdisk_file *file,
+                                unsigned int boot_index, int inject,
+                                struct wim_patch *patch ) {
+       union wim_patch_regions *regions = &patch->regions;
+       struct wim_patch_region *rfile;
+       struct wim_resource_header *lookup;
+       struct wim_resource_header *boot;
+       struct wim_directory_entry direntry;
+       struct wim_lookup_entry *entry;
+       struct vdisk_file *vfile;
+       size_t offset;
+       unsigned int injected = 0;
+       unsigned int i;
+       int rc;
+
+       /* Initialise patch */
+       memset ( patch, 0, sizeof ( *patch ) );
+       patch->file = file;
+       DBG ( "...patching WIM %s\n", file->name );
+
+       /* Reset file length */
+       file->xlen = file->len;
+       offset = file->len;
+
+       /* Read WIM header */
+       if ( ( rc = wim_header ( file, &patch->header ) ) != 0 )
+               return rc;
+       lookup = &patch->header.lookup;
+       boot = &patch->header.boot;
+
+       /* Patch header within original image body */
+       wim_construct_region ( &regions->header, "header", NULL, 0,
+                              sizeof ( patch->header ), wim_patch_header );
+
+       /* Record original lookup table */
+       memcpy ( &patch->lookup, lookup, sizeof ( patch->lookup ) );
+
+       /* Record original metadata for selected boot image (which may
+        * not be the originally selected boot image).
+        */
+       if ( ( rc = wim_metadata ( file, &patch->header, boot_index,
+                                  &patch->boot ) ) != 0 )
+               return rc;
+
+       /* Record original boot index */
+       patch->boot_index = patch->header.boot_index;
+
+       /* Update boot index in patched header, if applicable */
+       if ( boot_index )
+               patch->header.boot_index = boot_index;
+
+       /* Do nothing more if injection is disabled */
+       if ( ! inject )
+               return 0;
+
+       /* Construct injected files */
+       for ( i = 0 ; i < VDISK_MAX_FILES ; i++ ) {
+               vfile = &vdisk_files[i];
+               if ( ! wim_inject_file ( vfile ) )
+                       continue;
+               offset = wim_construct_region ( &regions->file[i], vfile->name,
+                                               vfile, offset, vfile->len,
+                                               wim_patch_file );
+               injected++;
+       }
+
+       /* Do nothing more if no files are injected */
+       if ( injected == 0 )
+               return 0;
+
+       /* Calculate boot index for injected image */
+       if ( ( rc = wim_count ( file, &patch->header, &boot_index ) ) != 0 )
+               return rc;
+       patch->header.images = ( boot_index + 1 );
+       patch->header.boot_index = patch->header.images;
+
+       /* Construct injected lookup table */
+       lookup->offset = offset = wim_align ( offset );
+       offset = wim_construct_region ( &regions->lookup.copy, "lookup.copy",
+                                       NULL, offset, patch->lookup.len,
+                                       wim_patch_lookup_copy );
+       offset = wim_construct_region ( &regions->lookup.boot, "lookup.boot",
+                                       NULL, offset, sizeof ( *entry ),
+                                       wim_patch_lookup_boot );
+       for ( i = 0 ; i < VDISK_MAX_FILES ; i++ ) {
+               rfile = &regions->file[i];
+               if ( ! rfile->patch )
+                       continue;
+               offset = wim_construct_region ( &regions->lookup.file[i],
+                                               "lookup.file", rfile,
+                                               offset, sizeof ( *entry ),
+                                               wim_patch_lookup_file );
+       }
+       lookup->offset = regions->lookup.copy.offset;
+       lookup->len = ( offset - lookup->offset );
+       lookup->zlen__flags = lookup->len;
+
+       /* Locate directory containing injected files */
+       patch->dir.name = WIM_INJECT_DIR;
+       if ( ( rc = wim_path ( file, &patch->header, &patch->boot,
+                              L(WIM_INJECT_DIR), &patch->dir.parent,
+                              &direntry ) ) != 0 )
+               return rc;
+       patch->dir.offset = direntry.subdir;
+       if ( ( rc = wim_dir_len ( file, &patch->header, &patch->boot,
+                                 patch->dir.offset, &patch->dir.len ) ) != 0 )
+               return rc;
+
+       /* Construct injected boot image metadata */
+       boot->offset = offset = wim_align ( offset );
+       offset = wim_construct_region ( &regions->boot.copy, "boot.copy",
+                                       NULL, offset, patch->boot.len,
+                                       wim_patch_boot_copy );
+       offset = wim_construct_dir ( patch, &patch->dir, offset,
+                                    &regions->boot.dir );
+       boot->len = ( offset - boot->offset );
+       boot->zlen__flags = ( boot->len | WIM_RESHDR_METADATA );
+
+       /* Record patched length */
+       file->xlen = offset;
+       DBG ( "...patching WIM length %#zx->%#zx\n", file->len, file->xlen );
+
+       return 0;
+}
+
+/**
+ * Patch WIM file
+ *
+ * @v file             Virtual file
+ * @v data             Data buffer
+ * @v offset           Offset
+ * @v len              Length
+ */
+void patch_wim ( struct vdisk_file *file, void *data, size_t offset,
+                size_t len ) {
+       static struct wim_patch cached_patch;
+       struct wim_patch *patch = &cached_patch;
+       struct wim_patch_region *region;
+       unsigned int boot_index;
+       unsigned int i;
+       int inject;
+       int rc;
+
+       /* Do nothing unless patching is required */
+       boot_index = cmdline_index;
+       inject = ( ! cmdline_rawwim );
+       if ( ( boot_index == 0 ) && ( ! inject ) )
+               return;
+
+       /* Update cached patch if required */
+       if ( file != patch->file ) {
+               if ( ( rc = wim_construct_patch ( file, boot_index, inject,
+                                                 patch ) ) != 0 ) {
+                       die ( "Could not patch WIM %s\n", file->name );
+               }
+       }
+       patch = &cached_patch;
+
+       /* Patch regions */
+       for ( i = 0 ; i < ( sizeof ( patch->regions ) /
+                           sizeof ( patch->regions.region[0] ) ) ; i++ ) {
+               region = &patch->regions.region[i];
+               if ( ( rc = wim_patch_region ( patch, region, data, offset,
+                                              len ) ) != 0 ) {
+                       die ( "Could not patch WIM %s %s at [%#zx,%#zx)\n",
+                             file->name, region->name, offset,
+                             ( offset + len ) );
+               }
+       }
+}
diff --git a/wimboot/wimboot-2.7.3/src/wimpatch.h b/wimboot/wimboot-2.7.3/src/wimpatch.h
new file mode 100644 (file)
index 0000000..3882ad7
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _WIMPATCH_H
+#define _WIMPATCH_H
+
+/*
+ * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * WIM dynamic patching
+ *
+ */
+
+#include <stdint.h>
+
+struct vdisk_file;
+
+extern void patch_wim ( struct vdisk_file *file, void *data, size_t offset,
+                       size_t len );
+
+#endif /* _WIMPATCH_H */
diff --git a/wimboot/wimboot-2.7.3/src/x86_64.i b/wimboot/wimboot-2.7.3/src/x86_64.i
new file mode 100644 (file)
index 0000000..f821626
--- /dev/null
@@ -0,0 +1 @@
+       .code64
diff --git a/wimboot/wimboot-2.7.3/src/xca.c b/wimboot/wimboot-2.7.3/src/xca.c
new file mode 100644 (file)
index 0000000..52a691a
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Xpress Compression Algorithm (MS-XCA) decompression
+ *
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include "wimboot.h"
+#include "huffman.h"
+#include "xca.h"
+
+/**
+ * Decompress XCA-compressed data
+ *
+ * @v data             Compressed data
+ * @v len              Length of compressed data
+ * @v buf              Decompression buffer, or NULL
+ * @ret out_len                Length of decompressed data, or negative error
+ */
+ssize_t xca_decompress ( const void *data, size_t len, void *buf ) {
+       const void *src = data;
+       const void *end = ( src + len );
+       uint8_t *out = buf;
+       size_t out_len = 0;
+       size_t out_len_threshold = 0;
+       const struct xca_huf_len *lengths;
+       struct xca xca;
+       uint32_t accum = 0;
+       int extra_bits = 0;
+       unsigned int huf;
+       struct huffman_symbols *sym;
+       unsigned int raw;
+       unsigned int match_len;
+       unsigned int match_offset_bits;
+       unsigned int match_offset;
+       const uint8_t *copy;
+       int rc;
+
+       /* Process data stream */
+       while ( src < end ) {
+
+               /* (Re)initialise decompressor if applicable */
+               if ( out_len >= out_len_threshold ) {
+
+                       /* Construct symbol lengths */
+                       lengths = src;
+                       src += sizeof ( *lengths );
+                       if ( src > end ) {
+                               DBG ( "XCA too short to hold Huffman lengths "
+                                     "table at input offset %#zx\n",
+                                     ( src - data ) );
+                               return -1;
+                       }
+                       for ( raw = 0 ; raw < XCA_CODES ; raw++ )
+                               xca.lengths[raw] = xca_huf_len ( lengths, raw );
+
+                       /* Construct Huffman alphabet */
+                       if ( ( rc = huffman_alphabet ( &xca.alphabet,
+                                                      xca.lengths,
+                                                      XCA_CODES ) ) != 0 )
+                               return rc;
+
+                       /* Initialise state */
+                       accum = XCA_GET16 ( src );
+                       accum <<= 16;
+                       accum |= XCA_GET16 ( src );
+                       extra_bits = 16;
+
+                       /* Determine next threshold */
+                       out_len_threshold = ( out_len + XCA_BLOCK_SIZE );
+               }
+
+               /* Determine symbol */
+               huf = ( accum >> ( 32 - HUFFMAN_BITS ) );
+               sym = huffman_sym ( &xca.alphabet, huf );
+               raw = huffman_raw ( sym, huf );
+               accum <<= huffman_len ( sym );
+               extra_bits -= huffman_len ( sym );
+               if ( extra_bits < 0 ) {
+                       accum |= ( XCA_GET16 ( src ) << ( -extra_bits ) );
+                       extra_bits += 16;
+               }
+
+               /* Process symbol */
+               if ( raw < XCA_END_MARKER ) {
+
+                       /* Literal symbol - add to output stream */
+                       if ( buf )
+                               *(out++) = raw;
+                       out_len++;
+
+               } else if ( ( raw == XCA_END_MARKER ) &&
+                           ( src >= ( end - 1 ) ) ) {
+
+                       /* End marker symbol */
+                       return out_len;
+
+               } else {
+
+                       /* LZ77 match symbol */
+                       raw -= XCA_END_MARKER;
+                       match_offset_bits = ( raw >> 4 );
+                       match_len = ( raw & 0x0f );
+                       if ( match_len == 0x0f ) {
+                               match_len = XCA_GET8 ( src );
+                               if ( match_len == 0xff ) {
+                                       match_len = XCA_GET16 ( src );
+                               } else {
+                                       match_len += 0x0f;
+                               }
+                       }
+                       match_len += 3;
+                       if ( match_offset_bits ) {
+                               match_offset =
+                                       ( ( accum >> ( 32 - match_offset_bits ))
+                                         + ( 1 << match_offset_bits ) );
+                       } else {
+                               match_offset = 1;
+                       }
+                       accum <<= match_offset_bits;
+                       extra_bits -= match_offset_bits;
+                       if ( extra_bits < 0 ) {
+                               accum |= ( XCA_GET16 ( src ) << (-extra_bits) );
+                               extra_bits += 16;
+                       }
+
+                       /* Copy data */
+                       out_len += match_len;
+                       if ( buf ) {
+                               copy = ( out - match_offset );
+                               while ( match_len-- )
+                                       *(out++) = *(copy++);
+                       }
+               }
+       }
+
+       DBG ( "XCA input overrun at output length %#zx\n", out_len );
+       return -1;
+}
diff --git a/wimboot/wimboot-2.7.3/src/xca.h b/wimboot/wimboot-2.7.3/src/xca.h
new file mode 100644 (file)
index 0000000..ca1a617
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef _XCA_H
+#define _XCA_H
+
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/**
+ * @file
+ *
+ * Xpress Compression Algorithm (MS-XCA) decompression
+ *
+ */
+
+#include <stdint.h>
+#include "huffman.h"
+
+/** Number of XCA codes */
+#define XCA_CODES 512
+
+/** XCA decompressor */
+struct xca {
+       /** Huffman alphabet */
+       struct huffman_alphabet alphabet;
+       /** Raw symbols
+        *
+        * Must immediately follow the Huffman alphabet.
+        */
+       huffman_raw_symbol_t raw[XCA_CODES];
+       /** Code lengths */
+       uint8_t lengths[XCA_CODES];
+};
+
+/** XCA symbol Huffman lengths table */
+struct xca_huf_len {
+       /** Lengths of each symbol */
+       uint8_t nibbles[ XCA_CODES / 2 ];
+} __attribute__ (( packed ));
+
+/**
+ * Extract Huffman-coded length of a raw symbol
+ *
+ * @v lengths          Huffman lengths table
+ * @v symbol           Raw symbol
+ * @ret len            Huffman-coded length
+ */
+static inline unsigned int xca_huf_len ( const struct xca_huf_len *lengths,
+                                        unsigned int symbol ) {
+       return ( ( ( lengths->nibbles[ symbol / 2 ] ) >>
+                  ( 4 * ( symbol % 2 ) ) ) & 0x0f );
+}
+
+/** Get word from source data stream */
+#define XCA_GET16( src ) ( {                   \
+       const uint16_t *src16 = src;            \
+       src += sizeof ( *src16 );               \
+       *src16; } )
+
+/** Get byte from source data stream */
+#define XCA_GET8( src ) ( {                    \
+       const uint8_t *src8 = src;              \
+       src += sizeof ( *src8 );                \
+       *src8; } )
+
+/** XCA source data stream end marker */
+#define XCA_END_MARKER 256
+
+/** XCA block size */
+#define XCA_BLOCK_SIZE ( 64 * 1024 )
+
+extern ssize_t xca_decompress ( const void *data, size_t len, void *buf );
+
+#endif /* _XCA_H */