]>
Commit | Line | Data |
---|---|---|
2ef2b01e | 1 | /** @file\r |
3402aac7 RC |
2 | The entry of the embedded BDS. This BDS does not follow the Boot Manager requirements\r |
3 | of the UEFI specification as it is designed to implement an embedded systmes\r | |
2ef2b01e A |
4 | propriatary boot scheme.\r |
5 | \r | |
3402aac7 | 6 | This template assume a DXE driver produces a SerialIo protocol not using the EFI\r |
2ef2b01e A |
7 | driver module and it will attempt to connect a console on top of this.\r |
8 | \r | |
1ebd6c11 | 9 | Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r |
3402aac7 | 10 | \r |
1ebd6c11 | 11 | This program and the accompanying materials\r |
2ef2b01e A |
12 | are licensed and made available under the terms and conditions of the BSD License\r |
13 | which accompanies this distribution. The full text of the license may be found at\r | |
14 | http://opensource.org/licenses/bsd-license.php\r | |
15 | \r | |
16 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
17 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
18 | \r | |
19 | **/\r | |
20 | \r | |
21 | #include "BdsEntry.h"\r | |
22 | \r | |
23 | \r | |
24 | BOOLEAN gConsolePresent = FALSE;\r | |
25 | \r | |
2ef2b01e A |
26 | EFI_BDS_ARCH_PROTOCOL gBdsProtocol = {\r |
27 | BdsEntry,\r | |
28 | };\r | |
29 | \r | |
30 | \r | |
3402aac7 RC |
31 | \r |
32 | \r | |
2ef2b01e | 33 | /**\r |
3402aac7 RC |
34 | This function uses policy data from the platform to determine what operating\r |
35 | system or system utility should be loaded and invoked. This function call\r | |
36 | also optionally make the use of user input to determine the operating system\r | |
37 | or system utility to be loaded and invoked. When the DXE Core has dispatched\r | |
38 | all the drivers on the dispatch queue, this function is called. This\r | |
39 | function will attempt to connect the boot devices required to load and invoke\r | |
40 | the selected operating system or system utility. During this process,\r | |
41 | additional firmware volumes may be discovered that may contain addition DXE\r | |
42 | drivers that can be dispatched by the DXE Core. If a boot device cannot be\r | |
43 | fully connected, this function calls the DXE Service Dispatch() to allow the\r | |
44 | DXE drivers from any newly discovered firmware volumes to be dispatched.\r | |
45 | Then the boot device connection can be attempted again. If the same boot\r | |
46 | device connection operation fails twice in a row, then that boot device has\r | |
2ef2b01e A |
47 | failed, and should be skipped. This function should never return.\r |
48 | \r | |
49 | @param This The EFI_BDS_ARCH_PROTOCOL instance.\r | |
50 | \r | |
51 | @return None.\r | |
52 | \r | |
53 | **/\r | |
54 | VOID\r | |
55 | EFIAPI\r | |
56 | BdsEntry (\r | |
57 | IN EFI_BDS_ARCH_PROTOCOL *This\r | |
58 | )\r | |
59 | {\r | |
60 | EFI_STATUS Status;\r | |
61 | UINTN NoHandles;\r | |
62 | EFI_HANDLE *Buffer;\r | |
63 | EFI_HANDLE FvHandle;\r | |
64 | EFI_HANDLE ImageHandle;\r | |
65 | EFI_HANDLE UsbDeviceHandle;\r | |
66 | EFI_GUID NameGuid;\r | |
67 | UINTN Size;\r | |
68 | UINTN HandleCount;\r | |
69 | UINTN OldHandleCount;\r | |
70 | EFI_HANDLE *HandleBuffer;\r | |
71 | UINTN Index;\r | |
72 | EFI_DEVICE_PATH_PROTOCOL *LoadImageDevicePath;\r | |
73 | EFI_DEVICE_PATH_PROTOCOL *FileSystemDevicePath;\r | |
3402aac7 | 74 | \r |
d39eb83c | 75 | PERF_END (NULL, "DXE", NULL, 0);\r |
76 | PERF_START (NULL, "BDS", NULL, 0);\r | |
77 | \r | |
78 | \r | |
2ef2b01e A |
79 | //\r |
80 | // Now do the EFI stuff\r | |
81 | //\r | |
82 | Size = 0x100;\r | |
83 | gST->FirmwareVendor = AllocateRuntimePool (Size);\r | |
84 | ASSERT (gST->FirmwareVendor != NULL);\r | |
3402aac7 | 85 | \r |
2ef2b01e A |
86 | UnicodeSPrint (gST->FirmwareVendor, Size, L"BeagleBoard EFI %a %a", __DATE__, __TIME__);\r |
87 | \r | |
88 | //\r | |
89 | // Now we need to setup the EFI System Table with information about the console devices.\r | |
3402aac7 | 90 | // This code is normally in the console spliter driver on platforms that support multiple\r |
2ef2b01e A |
91 | // consoles at the same time\r |
92 | //\r | |
93 | Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleTextOutProtocolGuid, NULL, &NoHandles, &Buffer);\r | |
94 | if (!EFI_ERROR (Status)) {\r | |
95 | // Use the first SimpleTextOut we find and update the EFI System Table\r | |
96 | gST->ConsoleOutHandle = Buffer[0];\r | |
97 | gST->StandardErrorHandle = Buffer[0];\r | |
98 | Status = gBS->HandleProtocol (Buffer[0], &gEfiSimpleTextOutProtocolGuid, (VOID **)&gST->ConOut);\r | |
99 | ASSERT_EFI_ERROR (Status);\r | |
3402aac7 | 100 | \r |
2ef2b01e | 101 | gST->StdErr = gST->ConOut;\r |
3402aac7 | 102 | \r |
2ef2b01e A |
103 | gST->ConOut->OutputString (gST->ConOut, L"BDS: Console Started!!!!\n\r");\r |
104 | FreePool (Buffer);\r | |
3402aac7 | 105 | \r |
2ef2b01e | 106 | gConsolePresent = TRUE;\r |
3402aac7 RC |
107 | }\r |
108 | \r | |
2ef2b01e A |
109 | \r |
110 | Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleTextInProtocolGuid, NULL, &NoHandles, &Buffer);\r | |
111 | if (!EFI_ERROR (Status)) {\r | |
112 | // Use the first SimpleTextIn we find and update the EFI System Table\r | |
113 | gST->ConsoleInHandle = Buffer[0];\r | |
114 | Status = gBS->HandleProtocol (Buffer[0], &gEfiSimpleTextInProtocolGuid, (VOID **)&gST->ConIn);\r | |
115 | ASSERT_EFI_ERROR (Status);\r | |
3402aac7 | 116 | \r |
2ef2b01e A |
117 | FreePool (Buffer);\r |
118 | }\r | |
119 | \r | |
120 | //\r | |
3402aac7 | 121 | // We now have EFI Consoles up and running. Print () will work now. DEBUG () and ASSERT () worked\r |
2ef2b01e A |
122 | // prior to this point as they were configured to use a more primative output scheme.\r |
123 | //\r | |
124 | \r | |
125 | //\r | |
126 | //Perform Connect\r | |
127 | //\r | |
128 | HandleCount = 0;\r | |
129 | while (1) {\r | |
130 | OldHandleCount = HandleCount;\r | |
131 | Status = gBS->LocateHandleBuffer (\r | |
132 | AllHandles,\r | |
133 | NULL,\r | |
134 | NULL,\r | |
135 | &HandleCount,\r | |
136 | &HandleBuffer\r | |
137 | );\r | |
138 | if (EFI_ERROR (Status)) {\r | |
139 | break;\r | |
140 | }\r | |
3402aac7 | 141 | \r |
2ef2b01e A |
142 | if (HandleCount == OldHandleCount) {\r |
143 | break;\r | |
144 | }\r | |
145 | \r | |
146 | for (Index = 0; Index < HandleCount; Index++) {\r | |
147 | gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);\r | |
148 | }\r | |
149 | }\r | |
150 | \r | |
2a9fe540 | 151 | EfiSignalEventReadyToBoot ();\r |
152 | \r | |
2ef2b01e A |
153 | //Locate handles for SimpleFileSystem protocol\r |
154 | Status = gBS->LocateHandleBuffer (\r | |
155 | ByProtocol,\r | |
156 | &gEfiSimpleFileSystemProtocolGuid,\r | |
157 | NULL,\r | |
158 | &HandleCount,\r | |
159 | &HandleBuffer\r | |
160 | );\r | |
161 | if (!EFI_ERROR(Status)) {\r | |
162 | for (Index = 0; Index < HandleCount; Index++) {\r | |
163 | //Get the device path\r | |
164 | FileSystemDevicePath = DevicePathFromHandle(HandleBuffer[Index]);\r | |
165 | if (FileSystemDevicePath == NULL) {\r | |
166 | continue;\r | |
167 | }\r | |
168 | \r | |
169 | //Check if UsbIo is on any handles in the device path.\r | |
170 | Status = gBS->LocateDevicePath(&gEfiUsbIoProtocolGuid, &FileSystemDevicePath, &UsbDeviceHandle);\r | |
171 | if (EFI_ERROR(Status)) {\r | |
172 | continue;\r | |
173 | }\r | |
174 | \r | |
175 | //Check if Usb stick has a magic EBL file.\r | |
176 | LoadImageDevicePath = FileDevicePath(HandleBuffer[Index], L"Ebl.efi");\r | |
177 | Status = gBS->LoadImage (TRUE, gImageHandle, LoadImageDevicePath, NULL, 0, &ImageHandle);\r | |
178 | if (EFI_ERROR(Status)) {\r | |
179 | continue;\r | |
180 | }\r | |
181 | \r | |
182 | //Boot to Shell on USB stick.\r | |
183 | Status = gBS->StartImage (ImageHandle, NULL, NULL);\r | |
184 | if (EFI_ERROR(Status)) {\r | |
185 | continue;\r | |
186 | }\r | |
187 | }\r | |
188 | }\r | |
3402aac7 | 189 | \r |
2ef2b01e | 190 | //\r |
3402aac7 | 191 | // Normal UEFI behavior is to process Globally Defined Variables as defined in Chapter 3\r |
2ef2b01e A |
192 | // (Boot Manager) of the UEFI specification. For this embedded system we don't do this.\r |
193 | //\r | |
194 | \r | |
195 | //\r | |
196 | // Search all the FVs for an application with a UI Section of Ebl. A .FDF file can be used\r | |
197 | // to control the names of UI sections in an FV.\r | |
198 | //\r | |
199 | Status = FindApplicationMatchingUiSection (L"Ebl", &FvHandle, &NameGuid);\r | |
200 | if (!EFI_ERROR (Status)) {\r | |
201 | \r | |
202 | //Boot to Shell.\r | |
203 | Status = LoadPeCoffSectionFromFv (FvHandle, &NameGuid);\r | |
204 | \r | |
205 | if (EFI_ERROR(Status)) {\r | |
206 | DEBUG((EFI_D_ERROR, "Boot from Shell failed. Status: %r\n", Status));\r | |
207 | }\r | |
208 | }\r | |
209 | \r | |
210 | //\r | |
3402aac7 | 211 | // EFI does not define the behaviour if all boot attemps fail and the last one returns.\r |
2ef2b01e A |
212 | // So we make a policy choice to reset the system since this BDS does not have a UI.\r |
213 | //\r | |
214 | gRT->ResetSystem (EfiResetShutdown, Status, 0, NULL);\r | |
215 | \r | |
216 | return ;\r | |
217 | }\r | |
218 | \r | |
219 | \r | |
220 | EFI_STATUS\r | |
221 | EFIAPI\r | |
222 | BdsInitialize (\r | |
223 | IN EFI_HANDLE ImageHandle,\r | |
224 | IN EFI_SYSTEM_TABLE *SystemTable\r | |
225 | )\r | |
226 | {\r | |
227 | EFI_STATUS Status;\r | |
228 | \r | |
2ef2b01e A |
229 | //\r |
230 | // Install protocol interface\r | |
231 | //\r | |
232 | Status = gBS->InstallMultipleProtocolInterfaces (\r | |
c3b6d975 | 233 | &ImageHandle,\r |
2ef2b01e A |
234 | &gEfiBdsArchProtocolGuid, &gBdsProtocol,\r |
235 | NULL\r | |
236 | );\r | |
237 | ASSERT_EFI_ERROR (Status);\r | |
238 | \r | |
239 | return Status;\r | |
240 | }\r | |
241 | \r | |
242 | \r |