--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/LoadLinuxLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/QemuFwCfgLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+\r
+EFI_STATUS\r
+TryRunningQemuKernel (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN KernelSize;\r
+ UINTN KernelInitialSize;\r
+ VOID *KernelBuf;\r
+ UINTN SetupSize;\r
+ VOID *SetupBuf;\r
+ UINTN CommandLineSize;\r
+ CHAR8 *CommandLine;\r
+ UINTN InitrdSize;\r
+ VOID* InitrdData;\r
+\r
+ SetupBuf = NULL;\r
+ SetupSize = 0;\r
+ KernelBuf = NULL;\r
+ KernelInitialSize = 0;\r
+ CommandLine = NULL;\r
+ CommandLineSize = 0;\r
+ InitrdData = NULL;\r
+ InitrdSize = 0;\r
+\r
+ if (!QemuFwCfgIsAvailable ()) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ QemuFwCfgSelectItem (QemuFwCfgItemKernelSize);\r
+ KernelSize = (UINTN) QemuFwCfgRead64 ();\r
+\r
+ QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupSize);\r
+ SetupSize = (UINTN) QemuFwCfgRead64 ();\r
+\r
+ if (KernelSize == 0 || SetupSize == 0) {\r
+ DEBUG ((EFI_D_INFO, "qemu -kernel was not used.\n"));\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ SetupBuf = LoadLinuxAllocateKernelSetupPages (EFI_SIZE_TO_PAGES (SetupSize));\r
+ if (SetupBuf == NULL) {\r
+ DEBUG ((EFI_D_ERROR, "Unable to allocate memory for kernel setup!\n"));\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ DEBUG ((EFI_D_INFO, "Setup size: 0x%x\n", (UINT32) SetupSize));\r
+ DEBUG ((EFI_D_INFO, "Reading kernel setup image ..."));\r
+ QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupData);\r
+ QemuFwCfgReadBytes (SetupSize, SetupBuf);\r
+ DEBUG ((EFI_D_INFO, " [done]\n"));\r
+\r
+ Status = LoadLinuxCheckKernelSetup (SetupBuf, SetupSize);\r
+ if (EFI_ERROR (Status)) {\r
+ goto FreeAndReturn;\r
+ }\r
+\r
+ KernelInitialSize = LoadLinuxGetKernelSize (SetupBuf, KernelSize);\r
+ if (KernelInitialSize == 0) {\r
+ Status = EFI_UNSUPPORTED;\r
+ goto FreeAndReturn;\r
+ }\r
+\r
+ KernelBuf = LoadLinuxAllocateKernelPages (\r
+ SetupBuf,\r
+ EFI_SIZE_TO_PAGES (KernelInitialSize));\r
+ if (KernelBuf == NULL) {\r
+ DEBUG ((EFI_D_ERROR, "Unable to allocate memory for kernel!\n"));\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto FreeAndReturn;\r
+ }\r
+\r
+ DEBUG ((EFI_D_INFO, "Kernel size: 0x%x\n", (UINT32) KernelSize));\r
+ DEBUG ((EFI_D_INFO, "Reading kernel image ..."));\r
+ QemuFwCfgSelectItem (QemuFwCfgItemKernelData);\r
+ QemuFwCfgReadBytes (KernelSize, KernelBuf);\r
+ DEBUG ((EFI_D_INFO, " [done]\n"));\r
+\r
+ QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize);\r
+ CommandLineSize = (UINTN) QemuFwCfgRead64 ();\r
+\r
+ if (CommandLineSize > 0) {\r
+ CommandLine = LoadLinuxAllocateCommandLinePages (\r
+ EFI_SIZE_TO_PAGES (CommandLineSize));\r
+ QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData);\r
+ QemuFwCfgReadBytes (CommandLineSize, CommandLine);\r
+ } else {\r
+ CommandLine = NULL;\r
+ }\r
+\r
+ Status = LoadLinuxSetCommandLine (SetupBuf, CommandLine);\r
+ if (EFI_ERROR (Status)) {\r
+ goto FreeAndReturn;\r
+ }\r
+\r
+ QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize);\r
+ InitrdSize = (UINTN) QemuFwCfgRead64 ();\r
+\r
+ if (InitrdSize > 0) {\r
+ InitrdData = LoadLinuxAllocateInitrdPages (\r
+ SetupBuf,\r
+ EFI_SIZE_TO_PAGES (InitrdSize)\r
+ );\r
+ DEBUG ((EFI_D_INFO, "Initrd size: 0x%x\n", (UINT32) InitrdSize));\r
+ DEBUG ((EFI_D_INFO, "Reading initrd image ..."));\r
+ QemuFwCfgSelectItem (QemuFwCfgItemInitrdData);\r
+ QemuFwCfgReadBytes (InitrdSize, InitrdData);\r
+ DEBUG ((EFI_D_INFO, " [done]\n"));\r
+ } else {\r
+ InitrdData = NULL;\r
+ }\r
+\r
+ Status = LoadLinuxSetInitrd (SetupBuf, InitrdData, InitrdSize);\r
+ if (EFI_ERROR (Status)) {\r
+ goto FreeAndReturn;\r
+ }\r
+\r
+ Status = LoadLinux (KernelBuf, SetupBuf);\r
+\r
+FreeAndReturn:\r
+ if (SetupBuf != NULL) {\r
+ FreePages (SetupBuf, EFI_SIZE_TO_PAGES (SetupSize));\r
+ }\r
+ if (KernelBuf != NULL) {\r
+ FreePages (KernelBuf, EFI_SIZE_TO_PAGES (KernelInitialSize));\r
+ }\r
+ if (CommandLine != NULL) {\r
+ FreePages (CommandLine, EFI_SIZE_TO_PAGES (CommandLineSize));\r
+ }\r
+ if (InitrdData != NULL) {\r
+ FreePages (InitrdData, EFI_SIZE_TO_PAGES (InitrdSize));\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r