]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Library/PlatformBootManagerLib/QemuKernel.c
OvmfPkg/PlatformBootManagerLib: add missing report status code call
[mirror_edk2.git] / OvmfPkg / Library / PlatformBootManagerLib / QemuKernel.c
1 /** @file
2
3 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 **/
13
14 #include <Uefi.h>
15
16 #include <Library/BaseLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/LoadLinuxLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/QemuFwCfgLib.h>
21 #include <Library/ReportStatusCodeLib.h>
22 #include <Library/UefiBootServicesTableLib.h>
23 #include <Library/UefiLib.h>
24
25
26 EFI_STATUS
27 TryRunningQemuKernel (
28 VOID
29 )
30 {
31 EFI_STATUS Status;
32 UINTN KernelSize;
33 UINTN KernelInitialSize;
34 VOID *KernelBuf;
35 UINTN SetupSize;
36 VOID *SetupBuf;
37 UINTN CommandLineSize;
38 CHAR8 *CommandLine;
39 UINTN InitrdSize;
40 VOID* InitrdData;
41
42 SetupBuf = NULL;
43 SetupSize = 0;
44 KernelBuf = NULL;
45 KernelInitialSize = 0;
46 CommandLine = NULL;
47 CommandLineSize = 0;
48 InitrdData = NULL;
49 InitrdSize = 0;
50
51 if (!QemuFwCfgIsAvailable ()) {
52 return EFI_NOT_FOUND;
53 }
54
55 QemuFwCfgSelectItem (QemuFwCfgItemKernelSize);
56 KernelSize = (UINTN) QemuFwCfgRead64 ();
57
58 QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupSize);
59 SetupSize = (UINTN) QemuFwCfgRead64 ();
60
61 if (KernelSize == 0 || SetupSize == 0) {
62 DEBUG ((EFI_D_INFO, "qemu -kernel was not used.\n"));
63 return EFI_NOT_FOUND;
64 }
65
66 SetupBuf = LoadLinuxAllocateKernelSetupPages (EFI_SIZE_TO_PAGES (SetupSize));
67 if (SetupBuf == NULL) {
68 DEBUG ((EFI_D_ERROR, "Unable to allocate memory for kernel setup!\n"));
69 return EFI_OUT_OF_RESOURCES;
70 }
71
72 DEBUG ((EFI_D_INFO, "Setup size: 0x%x\n", (UINT32) SetupSize));
73 DEBUG ((EFI_D_INFO, "Reading kernel setup image ..."));
74 QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupData);
75 QemuFwCfgReadBytes (SetupSize, SetupBuf);
76 DEBUG ((EFI_D_INFO, " [done]\n"));
77
78 Status = LoadLinuxCheckKernelSetup (SetupBuf, SetupSize);
79 if (EFI_ERROR (Status)) {
80 goto FreeAndReturn;
81 }
82
83 Status = LoadLinuxInitializeKernelSetup (SetupBuf);
84 if (EFI_ERROR (Status)) {
85 goto FreeAndReturn;
86 }
87
88 KernelInitialSize = LoadLinuxGetKernelSize (SetupBuf, KernelSize);
89 if (KernelInitialSize == 0) {
90 Status = EFI_UNSUPPORTED;
91 goto FreeAndReturn;
92 }
93
94 KernelBuf = LoadLinuxAllocateKernelPages (
95 SetupBuf,
96 EFI_SIZE_TO_PAGES (KernelInitialSize));
97 if (KernelBuf == NULL) {
98 DEBUG ((EFI_D_ERROR, "Unable to allocate memory for kernel!\n"));
99 Status = EFI_OUT_OF_RESOURCES;
100 goto FreeAndReturn;
101 }
102
103 DEBUG ((EFI_D_INFO, "Kernel size: 0x%x\n", (UINT32) KernelSize));
104 DEBUG ((EFI_D_INFO, "Reading kernel image ..."));
105 QemuFwCfgSelectItem (QemuFwCfgItemKernelData);
106 QemuFwCfgReadBytes (KernelSize, KernelBuf);
107 DEBUG ((EFI_D_INFO, " [done]\n"));
108
109 QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize);
110 CommandLineSize = (UINTN) QemuFwCfgRead64 ();
111
112 if (CommandLineSize > 0) {
113 CommandLine = LoadLinuxAllocateCommandLinePages (
114 EFI_SIZE_TO_PAGES (CommandLineSize));
115 QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData);
116 QemuFwCfgReadBytes (CommandLineSize, CommandLine);
117 } else {
118 CommandLine = NULL;
119 }
120
121 Status = LoadLinuxSetCommandLine (SetupBuf, CommandLine);
122 if (EFI_ERROR (Status)) {
123 goto FreeAndReturn;
124 }
125
126 QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize);
127 InitrdSize = (UINTN) QemuFwCfgRead64 ();
128
129 if (InitrdSize > 0) {
130 InitrdData = LoadLinuxAllocateInitrdPages (
131 SetupBuf,
132 EFI_SIZE_TO_PAGES (InitrdSize)
133 );
134 DEBUG ((EFI_D_INFO, "Initrd size: 0x%x\n", (UINT32) InitrdSize));
135 DEBUG ((EFI_D_INFO, "Reading initrd image ..."));
136 QemuFwCfgSelectItem (QemuFwCfgItemInitrdData);
137 QemuFwCfgReadBytes (InitrdSize, InitrdData);
138 DEBUG ((EFI_D_INFO, " [done]\n"));
139 } else {
140 InitrdData = NULL;
141 }
142
143 Status = LoadLinuxSetInitrd (SetupBuf, InitrdData, InitrdSize);
144 if (EFI_ERROR (Status)) {
145 goto FreeAndReturn;
146 }
147
148 //
149 // Signal the EVT_SIGNAL_READY_TO_BOOT event
150 //
151 EfiSignalEventReadyToBoot();
152
153 REPORT_STATUS_CODE (EFI_PROGRESS_CODE,
154 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT));
155
156 Status = LoadLinux (KernelBuf, SetupBuf);
157
158 FreeAndReturn:
159 if (SetupBuf != NULL) {
160 FreePages (SetupBuf, EFI_SIZE_TO_PAGES (SetupSize));
161 }
162 if (KernelBuf != NULL) {
163 FreePages (KernelBuf, EFI_SIZE_TO_PAGES (KernelInitialSize));
164 }
165 if (CommandLine != NULL) {
166 FreePages (CommandLine, EFI_SIZE_TO_PAGES (CommandLineSize));
167 }
168 if (InitrdData != NULL) {
169 FreePages (InitrdData, EFI_SIZE_TO_PAGES (InitrdSize));
170 }
171
172 return Status;
173 }
174