]>
Commit | Line | Data |
---|---|---|
8016da21 | 1 | /** @file\r |
2 | Legacy BIOS Platform support\r | |
3 | \r | |
4 | Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r | |
5 | \r | |
b26f0cf9 | 6 | SPDX-License-Identifier: BSD-2-Clause-Patent\r |
8016da21 | 7 | \r |
8 | **/\r | |
9 | \r | |
10 | #include "LegacyPlatform.h"\r | |
11 | \r | |
12 | EFI_SETUP_BBS_MAP mSetupBbsMap[] = {\r | |
13 | { 1, 2, 1, 1 }, // ATA HardDrive\r | |
14 | { 2, 3, 1, 1 }, // ATAPI CDROM\r | |
15 | { 3, 0x80, 2, 0 }, // PXE\r | |
16 | { 4, 1, 0, 6 }, // USB Floppy\r | |
17 | { 4, 2, 0, 6 }, // USB HDD\r | |
18 | { 4, 3, 0, 6 }, // USB CD\r | |
19 | { 4, 1, 0, 0 }, // USB ZIP Bugbug since Class/SubClass code is uninitialized\r | |
20 | { 4, 2, 0, 0 } // USB ZIP Bugbug since Class/SubClass code is uninitialized\r | |
21 | };\r | |
22 | \r | |
23 | //\r | |
24 | // Global variables for System ROMs\r | |
25 | //\r | |
26 | #define SYSTEM_ROM_FILE_GUID \\r | |
f4a8ab28 | 27 | { 0x1547B4F3, 0x3E8A, 0x4FEF, { 0x81, 0xC8, 0x32, 0x8E, 0xD6, 0x47, 0xAB, 0x1A } }\r |
8016da21 | 28 | \r |
29 | #define NULL_ROM_FILE_GUID \\r | |
f4a8ab28 | 30 | { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }\r |
8016da21 | 31 | \r |
32 | SYSTEM_ROM_TABLE mSystemRomTable[] = {\r | |
33 | { SYSTEM_ROM_FILE_GUID, 1 },\r | |
34 | { NULL_ROM_FILE_GUID, 0 }\r | |
35 | };\r | |
36 | \r | |
37 | EFI_HANDLE mVgaHandles[0x20];\r | |
38 | EFI_HANDLE mDiskHandles[0x20];\r | |
39 | EFI_HANDLE mIsaHandles[0x20];\r | |
40 | \r | |
41 | EFI_LEGACY_IRQ_PRIORITY_TABLE_ENTRY IrqPriorityTable[MAX_IRQ_PRIORITY_ENTRIES] = {\r | |
42 | {0x0B,0},\r | |
43 | {0x09,0},\r | |
44 | {0x0A,0},\r | |
45 | {0x05,0},\r | |
46 | {0x07,0},\r | |
47 | {0x00,0},\r | |
48 | {0x00,0}\r | |
49 | };\r | |
50 | \r | |
51 | //\r | |
52 | // PIRQ Table\r | |
53 | // - Slot numbering will be used to update the bus number and determine bridge\r | |
54 | // to check to get bus number. The Slot number - 1 is an index into a decode\r | |
55 | // table to get the bridge information.\r | |
56 | //\r | |
57 | EFI_LEGACY_PIRQ_TABLE PirqTableHead = {\r | |
58 | {\r | |
59 | EFI_LEGACY_PIRQ_TABLE_SIGNATURE, // UINT32 Signature\r | |
60 | 0x00, // UINT8 MinorVersion\r | |
61 | 0x01, // UINT8 MajorVersion\r | |
62 | 0x0000, // UINT16 TableSize\r | |
63 | 0x00, // UINT8 Bus\r | |
64 | 0x08, // UINT8 DevFun\r | |
65 | 0x0000, // UINT16 PciOnlyIrq\r | |
66 | 0x8086, // UINT16 CompatibleVid\r | |
67 | 0x122e, // UINT16 CompatibleDid\r | |
68 | 0x00000000, // UINT32 Miniport\r | |
69 | { // UINT8 Reserved[11]\r | |
70 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r | |
71 | 0x00, 0x00, 0x00\r | |
72 | },\r | |
73 | 0x00, // UINT8 Checksum\r | |
74 | },\r | |
75 | {\r | |
f4a8ab28 LE |
76 | // -- Pin 1 -- -- Pin 2 -- -- Pin 3 -- -- Pin 4 --\r |
77 | // Bus Dev Reg Map Reg Map Reg Map Reg Map\r | |
78 | //\r | |
79 | {0x00,0x08,{{0x60,0xDEB8},{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8}},0x00,0x00},\r | |
80 | {0x00,0x10,{{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8},{0x60,0xDEB8}},0x01,0x00},\r | |
81 | {0x00,0x18,{{0x62,0xDEB8},{0x63,0xDEB8},{0x60,0xDEB8},{0x61,0xDEB8}},0x02,0x00},\r | |
82 | {0x00,0x20,{{0x63,0xDEB8},{0x60,0xDEB8},{0x61,0xDEB8},{0x62,0xDEB8}},0x03,0x00},\r | |
83 | {0x00,0x28,{{0x60,0xDEB8},{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8}},0x04,0x00},\r | |
84 | {0x00,0x30,{{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8},{0x60,0xDEB8}},0x05,0x00},\r | |
8016da21 | 85 | }\r |
86 | };\r | |
87 | \r | |
88 | LEGACY_BIOS_PLATFORM_INSTANCE mPrivateData;\r | |
89 | EFI_HANDLE mImageHandle = NULL;\r | |
90 | \r | |
91 | /**\r | |
92 | Return the handles and assorted information for the specified PCI Class code\r | |
93 | \r | |
94 | @param[in] PciClasses Array of PCI_CLASS_RECORD to find terminated with ClassCode 0xff\r | |
95 | @param[in,out] DeviceTable Table to place handles etc in.\r | |
96 | @param[in,out] DeviceIndex Number of devices found\r | |
97 | @param[in] DeviceFlags FALSE if a valid legacy ROM is required, TRUE otherwise.\r | |
98 | \r | |
99 | @retval EFI_SUCCESS One or more devices found\r | |
100 | @retval EFI_NOT_FOUND No device found\r | |
101 | \r | |
102 | **/\r | |
103 | EFI_STATUS\r | |
104 | FindAllDeviceTypes (\r | |
105 | IN PCI_CLASS_RECORD *PciClasses,\r | |
106 | IN OUT DEVICE_STRUCTURE *DeviceTable,\r | |
107 | IN OUT UINT16 *DeviceIndex,\r | |
108 | IN BOOLEAN DeviceFlags\r | |
109 | )\r | |
110 | {\r | |
111 | UINTN HandleCount;\r | |
112 | EFI_HANDLE *HandleBuffer;\r | |
113 | UINTN Index;\r | |
114 | UINTN StartIndex;\r | |
115 | PCI_TYPE00 PciConfigHeader;\r | |
116 | EFI_PCI_IO_PROTOCOL *PciIo;\r | |
117 | EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r | |
118 | UINTN Flags;\r | |
119 | EFI_STATUS Status;\r | |
120 | UINTN Index2;\r | |
121 | \r | |
122 | //\r | |
123 | // Get legacy BIOS protocol as it is required to deal with Option ROMs.\r | |
124 | //\r | |
125 | StartIndex = *DeviceIndex;\r | |
126 | Status = gBS->LocateProtocol (\r | |
127 | &gEfiLegacyBiosProtocolGuid,\r | |
128 | NULL,\r | |
129 | (VOID**)&LegacyBios\r | |
130 | );\r | |
131 | ASSERT_EFI_ERROR (Status);\r | |
132 | \r | |
133 | //\r | |
134 | // Get all PCI handles and check them to generate a list of matching devices.\r | |
135 | //\r | |
136 | gBS->LocateHandleBuffer (\r | |
137 | ByProtocol,\r | |
138 | &gEfiPciIoProtocolGuid,\r | |
139 | NULL,\r | |
140 | &HandleCount,\r | |
141 | &HandleBuffer\r | |
142 | );\r | |
143 | for (Index = 0; Index < HandleCount; Index++) {\r | |
144 | gBS->HandleProtocol (\r | |
145 | HandleBuffer[Index],\r | |
146 | &gEfiPciIoProtocolGuid,\r | |
147 | (VOID**)&PciIo\r | |
148 | );\r | |
149 | PciIo->Pci.Read (\r | |
150 | PciIo,\r | |
151 | EfiPciIoWidthUint32,\r | |
152 | 0,\r | |
153 | sizeof (PciConfigHeader) / sizeof (UINT32),\r | |
154 | &PciConfigHeader\r | |
155 | );\r | |
156 | for (Index2 = 0; PciClasses[Index2].Class != 0xff; Index2++) {\r | |
157 | if ((PciConfigHeader.Hdr.ClassCode[2] == PciClasses[Index2].Class) &&\r | |
158 | (PciConfigHeader.Hdr.ClassCode[1] == PciClasses[Index2].SubClass)) {\r | |
159 | LegacyBios->CheckPciRom (\r | |
160 | LegacyBios,\r | |
161 | HandleBuffer[Index],\r | |
162 | NULL,\r | |
163 | NULL,\r | |
164 | &Flags\r | |
165 | );\r | |
166 | \r | |
167 | //\r | |
168 | // Verify that results of OPROM check match request.\r | |
169 | // The two valid requests are:\r | |
170 | // DeviceFlags = 0 require a valid legacy ROM\r | |
171 | // DeviceFlags = 1 require either no ROM or a valid legacy ROM\r | |
172 | //\r | |
173 | if (\r | |
174 | ((DeviceFlags != 0) && (Flags == NO_ROM)) ||\r | |
175 | ((Flags & (ROM_FOUND | VALID_LEGACY_ROM)) == (ROM_FOUND | VALID_LEGACY_ROM))\r | |
176 | ) {\r | |
177 | DeviceTable->Handle = HandleBuffer[Index];\r | |
178 | DeviceTable->Vid = PciConfigHeader.Hdr.VendorId;\r | |
179 | DeviceTable->Did = PciConfigHeader.Hdr.DeviceId;\r | |
180 | DeviceTable->SvId = PciConfigHeader.Device.SubsystemVendorID;\r | |
181 | DeviceTable->SysId = PciConfigHeader.Device.SubsystemID;\r | |
182 | ++ *DeviceIndex;\r | |
183 | DeviceTable++;\r | |
184 | }\r | |
185 | }\r | |
186 | }\r | |
187 | }\r | |
188 | \r | |
189 | //\r | |
190 | // Free any allocated buffers\r | |
191 | //\r | |
192 | gBS->FreePool (HandleBuffer);\r | |
193 | \r | |
194 | if (*DeviceIndex != StartIndex) {\r | |
195 | return EFI_SUCCESS;\r | |
196 | } else {\r | |
197 | return EFI_NOT_FOUND;\r | |
198 | }\r | |
199 | }\r | |
200 | \r | |
201 | /**\r | |
202 | Load and initialize the Legacy BIOS SMM handler.\r | |
203 | \r | |
204 | @param This The protocol instance pointer.\r | |
205 | @param EfiToLegacy16BootTable A pointer to Legacy16 boot table.\r | |
206 | \r | |
207 | @retval EFI_SUCCESS SMM code loaded.\r | |
208 | @retval EFI_DEVICE_ERROR SMM code failed to load\r | |
209 | \r | |
210 | **/\r | |
211 | EFI_STATUS\r | |
212 | EFIAPI\r | |
213 | SmmInit (\r | |
214 | IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,\r | |
215 | IN VOID *EfiToLegacy16BootTable\r | |
216 | )\r | |
217 | {\r | |
218 | return EFI_SUCCESS;\r | |
219 | }\r | |
220 | \r | |
221 | /**\r | |
222 | Finds the device path that should be used as the primary display adapter.\r | |
223 | \r | |
224 | @param VgaHandle - The handle of the video device\r | |
225 | \r | |
226 | **/\r | |
227 | VOID\r | |
228 | GetSelectedVgaDeviceInfo (\r | |
229 | OUT EFI_HANDLE *VgaHandle\r | |
230 | )\r | |
231 | {\r | |
232 | EFI_STATUS Status;\r | |
233 | UINTN HandleCount;\r | |
234 | EFI_HANDLE *HandleBuffer;\r | |
235 | UINTN Index;\r | |
236 | EFI_PCI_IO_PROTOCOL *PciIo;\r | |
237 | PCI_TYPE00 Pci;\r | |
238 | UINT8 MinBus;\r | |
239 | UINT8 MaxBus;\r | |
240 | UINTN Segment;\r | |
241 | UINTN Bus;\r | |
242 | UINTN Device;\r | |
243 | UINTN Function;\r | |
244 | UINTN SelectedAddress;\r | |
245 | UINTN CurrentAddress;\r | |
246 | \r | |
247 | //\r | |
248 | // Initialize return to 'not found' state\r | |
249 | //\r | |
250 | *VgaHandle = NULL;\r | |
251 | \r | |
252 | //\r | |
8c0b0b34 TH |
253 | // Initialize variable states. This is important for selecting the VGA\r |
254 | // device if multiple devices exist behind a single bridge.\r | |
8016da21 | 255 | //\r |
256 | HandleCount = 0;\r | |
257 | HandleBuffer = NULL;\r | |
258 | SelectedAddress = PCI_LIB_ADDRESS(0xff, 0x1f, 0x7, 0);\r | |
259 | \r | |
260 | //\r | |
261 | // The bus range to search for a VGA device in.\r | |
262 | //\r | |
263 | MinBus = MaxBus = 0;\r | |
264 | \r | |
265 | //\r | |
266 | // Start to check all the pci io to find all possible VGA device\r | |
267 | //\r | |
268 | HandleCount = 0;\r | |
269 | HandleBuffer = NULL;\r | |
270 | Status = gBS->LocateHandleBuffer (\r | |
271 | ByProtocol,\r | |
272 | &gEfiPciIoProtocolGuid,\r | |
273 | NULL,\r | |
274 | &HandleCount,\r | |
275 | &HandleBuffer\r | |
276 | );\r | |
277 | if (EFI_ERROR (Status)) {\r | |
278 | return;\r | |
279 | }\r | |
280 | \r | |
281 | for (Index = 0; Index < HandleCount; Index++) {\r | |
282 | Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID**)&PciIo);\r | |
283 | if (!EFI_ERROR (Status)) {\r | |
284 | //\r | |
48cf40b8 | 285 | // Determine if this is in the correct bus range.\r |
8016da21 | 286 | //\r |
287 | Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);\r | |
288 | if (EFI_ERROR(Status) || (Bus < MinBus || Bus > MaxBus)) {\r | |
289 | continue;\r | |
290 | }\r | |
291 | \r | |
292 | //\r | |
293 | // Read device information.\r | |
294 | //\r | |
295 | Status = PciIo->Pci.Read (\r | |
296 | PciIo,\r | |
297 | EfiPciIoWidthUint32,\r | |
298 | 0,\r | |
299 | sizeof (Pci) / sizeof (UINT32),\r | |
300 | &Pci\r | |
301 | );\r | |
302 | if (EFI_ERROR (Status)) {\r | |
303 | continue;\r | |
304 | }\r | |
305 | \r | |
306 | //\r | |
307 | // Make sure the device is a VGA device.\r | |
308 | //\r | |
309 | if (!IS_PCI_VGA (&Pci)) {\r | |
310 | continue;\r | |
311 | }\r | |
70d5086c | 312 | DEBUG ((DEBUG_INFO,\r |
8016da21 | 313 | "PCI VGA: 0x%04x:0x%04x\n",\r |
314 | Pci.Hdr.VendorId,\r | |
315 | Pci.Hdr.DeviceId\r | |
316 | ));\r | |
317 | \r | |
318 | //\r | |
319 | // Currently we use the lowest numbered bus/device/function if multiple\r | |
320 | // devices are found in the target bus range.\r | |
321 | //\r | |
322 | CurrentAddress = PCI_LIB_ADDRESS(Bus, Device, Function, 0);\r | |
323 | if (CurrentAddress < SelectedAddress) {\r | |
324 | SelectedAddress = CurrentAddress;\r | |
325 | *VgaHandle = HandleBuffer[Index];\r | |
326 | }\r | |
327 | }\r | |
328 | }\r | |
329 | \r | |
330 | FreePool (HandleBuffer);\r | |
331 | }\r | |
332 | \r | |
333 | \r | |
334 | /**\r | |
335 | Returns a buffer of handles for the requested subfunction.\r | |
336 | \r | |
337 | @param This The protocol instance pointer.\r | |
338 | @param Mode Specifies what handle to return. See EFI_GET_PLATFORM_HANDLE_MODE enum.\r | |
339 | @param Type Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.\r | |
340 | @param HandleBuffer Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.\r | |
341 | @param HandleCount Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.\r | |
342 | @param AdditionalData Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.\r | |
343 | \r | |
344 | @retval EFI_SUCCESS Handle is valid.\r | |
345 | @retval EFI_UNSUPPORTED Mode is not supported on the platform.\r | |
346 | @retval EFI_NOT_FOUND Handle is not known.\r | |
347 | \r | |
348 | **/\r | |
349 | EFI_STATUS\r | |
350 | EFIAPI\r | |
351 | GetPlatformHandle (\r | |
352 | IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,\r | |
353 | IN EFI_GET_PLATFORM_HANDLE_MODE Mode,\r | |
354 | IN UINT16 Type,\r | |
355 | OUT EFI_HANDLE **HandleBuffer,\r | |
356 | OUT UINTN *HandleCount,\r | |
357 | OUT VOID **AdditionalData OPTIONAL\r | |
358 | )\r | |
359 | {\r | |
360 | DEVICE_STRUCTURE LocalDevice[0x40];\r | |
361 | UINT32 LocalIndex;\r | |
362 | UINT32 Index;\r | |
363 | DEVICE_STRUCTURE TempDevice;\r | |
364 | EFI_STATUS Status;\r | |
365 | EFI_PCI_IO_PROTOCOL *PciIo;\r | |
366 | UINTN Segment;\r | |
367 | UINTN Bus;\r | |
368 | UINTN Device;\r | |
369 | UINTN Function;\r | |
370 | HDD_INFO *HddInfo;\r | |
371 | PCI_TYPE00 PciConfigHeader;\r | |
372 | UINT32 HddIndex;\r | |
373 | EFI_HANDLE IdeHandle;\r | |
374 | EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r | |
375 | PCI_CLASS_RECORD ClassLists[10];\r | |
376 | UINTN PriorityIndex;\r | |
377 | \r | |
378 | static BOOLEAN bConnected = FALSE;\r | |
379 | \r | |
380 | LocalIndex = 0x00;\r | |
381 | HddInfo = NULL;\r | |
382 | HddIndex = 0;\r | |
383 | \r | |
384 | Status = gBS->LocateProtocol (\r | |
385 | &gEfiLegacyBiosProtocolGuid,\r | |
386 | NULL,\r | |
387 | (VOID**)&LegacyBios\r | |
388 | );\r | |
389 | \r | |
390 | //\r | |
391 | // Process mode specific operations\r | |
392 | //\r | |
393 | switch (Mode) {\r | |
394 | case EfiGetPlatformVgaHandle:\r | |
395 | //\r | |
396 | // Get the handle for the currently selected VGA device.\r | |
397 | //\r | |
398 | GetSelectedVgaDeviceInfo (&mVgaHandles[0]);\r | |
399 | *HandleBuffer = &mVgaHandles[0];\r | |
400 | *HandleCount = (mVgaHandles[0] != NULL) ? 1 : 0;\r | |
401 | return EFI_SUCCESS;\r | |
402 | case EfiGetPlatformIdeHandle:\r | |
403 | IdeHandle = NULL;\r | |
404 | if (AdditionalData != NULL) {\r | |
405 | HddInfo = (HDD_INFO *) *AdditionalData;\r | |
406 | }\r | |
407 | \r | |
408 | //\r | |
409 | // Locate all found block io devices\r | |
410 | //\r | |
411 | ClassLists[0].Class = PCI_CLASS_MASS_STORAGE;\r | |
412 | ClassLists[0].SubClass = PCI_CLASS_MASS_STORAGE_SCSI;\r | |
413 | ClassLists[1].Class = PCI_CLASS_MASS_STORAGE;\r | |
414 | ClassLists[1].SubClass = PCI_CLASS_MASS_STORAGE_IDE;\r | |
415 | ClassLists[2].Class = PCI_CLASS_MASS_STORAGE;\r | |
416 | ClassLists[2].SubClass = PCI_CLASS_MASS_STORAGE_RAID;\r | |
417 | ClassLists[3].Class = PCI_CLASS_MASS_STORAGE;\r | |
418 | ClassLists[3].SubClass = PCI_CLASS_MASS_STORAGE_SATADPA;\r | |
419 | ClassLists[4].Class = 0xff;\r | |
420 | FindAllDeviceTypes (ClassLists, LocalDevice, (UINT16 *) &LocalIndex, TRUE);\r | |
421 | if (LocalIndex == 0) {\r | |
422 | return EFI_NOT_FOUND;\r | |
423 | }\r | |
424 | \r | |
425 | //\r | |
426 | // Make sure all IDE controllers are connected. This is necessary\r | |
427 | // in NO_CONFIG_CHANGE boot path to ensure IDE controller is correctly\r | |
428 | // initialized and all IDE drives are enumerated\r | |
429 | //\r | |
430 | if (!bConnected) {\r | |
431 | for (Index = 0; Index < LocalIndex; Index++) {\r | |
432 | gBS->ConnectController (LocalDevice[Index].Handle, NULL, NULL, TRUE);\r | |
433 | }\r | |
434 | }\r | |
435 | \r | |
436 | //\r | |
437 | // Locate onboard controllers.\r | |
438 | //\r | |
439 | for (Index = 0; Index < LocalIndex; Index++) {\r | |
440 | if (LocalDevice[Index].Vid == V_INTEL_VENDOR_ID) {\r | |
441 | if (LocalDevice[Index].Did == V_PIIX4_IDE_DEVICE_ID) {\r | |
442 | IdeHandle = LocalDevice[Index].Handle;\r | |
443 | }\r | |
444 | }\r | |
445 | }\r | |
446 | \r | |
447 | //\r | |
448 | // Set the IDE contorller as primary devices.\r | |
449 | //\r | |
450 | PriorityIndex = 0;\r | |
451 | for (Index = 0; Index < LocalIndex; Index++) {\r | |
452 | if (LocalDevice[Index].Handle == IdeHandle && PriorityIndex == 0) {\r | |
453 | TempDevice = LocalDevice[PriorityIndex];\r | |
454 | LocalDevice[PriorityIndex] = LocalDevice[Index];\r | |
455 | LocalDevice[Index] = TempDevice;\r | |
456 | PriorityIndex++;\r | |
457 | break;\r | |
458 | }\r | |
459 | }\r | |
460 | \r | |
461 | //\r | |
462 | // Copy over handles and update return values.\r | |
463 | //\r | |
464 | for (Index = 0; Index < LocalIndex; Index++) {\r | |
465 | mDiskHandles[Index] = LocalDevice[Index].Handle;\r | |
466 | }\r | |
467 | *HandleBuffer = &mDiskHandles[0];\r | |
468 | *HandleCount = LocalIndex;\r | |
469 | \r | |
470 | //\r | |
471 | // We have connected all IDE controllers once. No more needed\r | |
472 | //\r | |
473 | bConnected = TRUE;\r | |
474 | \r | |
475 | //\r | |
476 | // Log all onboard controllers.\r | |
477 | //\r | |
478 | for (Index = 0; (Index < LocalIndex) && (AdditionalData != NULL); Index++) {\r | |
479 | if ((LocalDevice[Index].Handle != NULL) &&\r | |
480 | (LocalDevice[Index].Handle == IdeHandle)) {\r | |
481 | Status = gBS->HandleProtocol (\r | |
482 | LocalDevice[Index].Handle,\r | |
483 | &gEfiPciIoProtocolGuid,\r | |
484 | (VOID **) &PciIo\r | |
485 | );\r | |
486 | PciIo->Pci.Read (\r | |
487 | PciIo,\r | |
488 | EfiPciIoWidthUint32,\r | |
489 | 0,\r | |
490 | sizeof (PciConfigHeader) / sizeof (UINT32),\r | |
491 | &PciConfigHeader\r | |
492 | );\r | |
493 | if (!EFI_ERROR (Status)) {\r | |
494 | PciIo->GetLocation (\r | |
495 | PciIo,\r | |
496 | &Segment,\r | |
497 | &Bus,\r | |
498 | &Device,\r | |
499 | &Function\r | |
500 | );\r | |
501 | \r | |
502 | //\r | |
503 | // Be sure to only fill out correct information based on platform\r | |
48cf40b8 | 504 | // configuration.\r |
8016da21 | 505 | //\r |
506 | HddInfo[HddIndex].Status |= HDD_PRIMARY;\r | |
507 | HddInfo[HddIndex].Bus = (UINT32)Bus;\r | |
508 | HddInfo[HddIndex].Device = (UINT32)Device;\r | |
509 | HddInfo[HddIndex].Function = (UINT32)Function;\r | |
510 | HddInfo[HddIndex + 1].Status |= HDD_SECONDARY;\r | |
511 | HddInfo[HddIndex + 1].Bus = (UINT32)Bus;\r | |
512 | HddInfo[HddIndex + 1].Device = (UINT32)Device;\r | |
513 | HddInfo[HddIndex + 1].Function = (UINT32)Function;\r | |
514 | \r | |
515 | //\r | |
516 | // Primary controller data\r | |
517 | //\r | |
518 | if ((PciConfigHeader.Hdr.ClassCode[0] & 0x01) != 0) {\r | |
519 | HddInfo[HddIndex].CommandBaseAddress =\r | |
520 | (UINT16)(PciConfigHeader.Device.Bar[0] & 0xfffc);\r | |
521 | HddInfo[HddIndex].ControlBaseAddress =\r | |
522 | (UINT16)((PciConfigHeader.Device.Bar[1] & 0xfffc)+2);\r | |
523 | HddInfo[HddIndex].BusMasterAddress =\r | |
524 | (UINT16)(PciConfigHeader.Device.Bar[4] & 0xfffc);\r | |
525 | HddInfo[HddIndex].HddIrq = PciConfigHeader.Device.InterruptLine;\r | |
526 | } else {\r | |
527 | HddInfo[HddIndex].HddIrq = 14;\r | |
528 | HddInfo[HddIndex].CommandBaseAddress = 0x1f0;\r | |
529 | HddInfo[HddIndex].ControlBaseAddress = 0x3f6;\r | |
530 | HddInfo[HddIndex].BusMasterAddress = 0;\r | |
531 | }\r | |
532 | HddIndex++;\r | |
533 | \r | |
534 | //\r | |
535 | // Secondary controller data\r | |
536 | //\r | |
537 | if ((PciConfigHeader.Hdr.ClassCode[0] & 0x04) != 0) {\r | |
538 | HddInfo[HddIndex].CommandBaseAddress =\r | |
539 | (UINT16)(PciConfigHeader.Device.Bar[2] & 0xfffc);\r | |
540 | HddInfo[HddIndex].ControlBaseAddress =\r | |
541 | (UINT16)((PciConfigHeader.Device.Bar[3] & 0xfffc)+2);\r | |
542 | HddInfo[HddIndex].BusMasterAddress =\r | |
543 | (UINT16)(HddInfo[HddIndex].BusMasterAddress + 8);\r | |
544 | HddInfo[HddIndex].HddIrq = PciConfigHeader.Device.InterruptLine;\r | |
545 | } else {\r | |
546 | HddInfo[HddIndex].HddIrq = 15;\r | |
547 | HddInfo[HddIndex].CommandBaseAddress = 0x170;\r | |
548 | HddInfo[HddIndex].ControlBaseAddress = 0x376;\r | |
549 | HddInfo[HddIndex].BusMasterAddress = 0;\r | |
550 | }\r | |
551 | HddIndex++;\r | |
552 | }\r | |
553 | }\r | |
554 | }\r | |
555 | return EFI_SUCCESS;\r | |
556 | case EfiGetPlatformIsaBusHandle:\r | |
557 | ClassLists[0].Class = (UINT8) PCI_CLASS_BRIDGE;\r | |
558 | ClassLists[0].SubClass = (UINT8) PCI_CLASS_BRIDGE_ISA_PDECODE;\r | |
559 | ClassLists[1].Class = (UINT8) PCI_CLASS_BRIDGE;\r | |
560 | ClassLists[1].SubClass = (UINT8) PCI_CLASS_BRIDGE_ISA;\r | |
561 | ClassLists[2].Class = 0xff;\r | |
562 | \r | |
563 | //\r | |
564 | // Locate all found block io devices\r | |
565 | //\r | |
566 | FindAllDeviceTypes (ClassLists, LocalDevice, (UINT16 *) (&LocalIndex), TRUE);\r | |
567 | if (LocalIndex == 0) {\r | |
568 | return EFI_NOT_FOUND;\r | |
569 | }\r | |
570 | \r | |
571 | //\r | |
572 | // Find our ISA bridge.\r | |
573 | //\r | |
574 | for (Index = 0; Index < LocalIndex; Index++) {\r | |
575 | if (LocalDevice[Index].Vid == V_INTEL_VENDOR_ID) {\r | |
576 | TempDevice = LocalDevice[0];\r | |
577 | LocalDevice[0] = LocalDevice[Index];\r | |
578 | LocalDevice[Index] = TempDevice;\r | |
579 | }\r | |
580 | }\r | |
581 | \r | |
582 | //\r | |
583 | // Perform copy and update return values.\r | |
584 | //\r | |
585 | for (Index = 0; Index < LocalIndex; Index++) {\r | |
586 | mIsaHandles[Index] = LocalDevice[Index].Handle;\r | |
587 | }\r | |
588 | *HandleBuffer = &mIsaHandles[0];\r | |
589 | *HandleCount = LocalIndex;\r | |
590 | return EFI_SUCCESS;\r | |
591 | case EfiGetPlatformUsbHandle:\r | |
592 | default:\r | |
593 | return EFI_UNSUPPORTED;\r | |
594 | };\r | |
595 | }\r | |
596 | \r | |
597 | /**\r | |
598 | Allows platform to perform any required action after a LegacyBios operation.\r | |
599 | Invokes the specific sub function specified by Mode.\r | |
600 | \r | |
601 | @param This The protocol instance pointer.\r | |
602 | @param Mode Specifies what handle to return. See EFI_GET_PLATFORM_HOOK_MODE enum.\r | |
603 | @param Type Mode specific. See EFI_GET_PLATFORM_HOOK_MODE enum.\r | |
604 | @param DeviceHandle Mode specific. See EFI_GET_PLATFORM_HOOK_MODE enum.\r | |
605 | @param ShadowAddress Mode specific. See EFI_GET_PLATFORM_HOOK_MODE enum.\r | |
606 | @param Compatibility16Table Mode specific. See EFI_GET_PLATFORM_HOOK_MODE enum.\r | |
607 | @param AdditionalData Mode specific. See EFI_GET_PLATFORM_HOOK_MODE enum.\r | |
608 | \r | |
609 | @retval EFI_SUCCESS The operation performed successfully. Mode specific.\r | |
610 | @retval EFI_UNSUPPORTED Mode is not supported on the platform.\r | |
611 | \r | |
612 | **/\r | |
613 | EFI_STATUS\r | |
614 | EFIAPI\r | |
615 | PlatformHooks (\r | |
616 | IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,\r | |
617 | IN EFI_GET_PLATFORM_HOOK_MODE Mode,\r | |
618 | IN UINT16 Type,\r | |
619 | OUT EFI_HANDLE DeviceHandle, OPTIONAL\r | |
620 | IN OUT UINTN *Shadowaddress, OPTIONAL\r | |
621 | IN EFI_COMPATIBILITY16_TABLE *Compatibility16Table, OPTIONAL\r | |
622 | OUT VOID **AdditionalData OPTIONAL\r | |
623 | )\r | |
624 | {\r | |
625 | EFI_IA32_REGISTER_SET Regs;\r | |
626 | EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r | |
627 | EFI_STATUS Status;\r | |
628 | \r | |
629 | switch (Mode) {\r | |
630 | case EfiPlatformHookPrepareToScanRom:\r | |
631 | Status = gBS->LocateProtocol (\r | |
632 | &gEfiLegacyBiosProtocolGuid,\r | |
633 | NULL,\r | |
634 | (VOID**)&LegacyBios\r | |
635 | );\r | |
636 | \r | |
637 | //\r | |
638 | // Set the 80x25 Text VGA Mode\r | |
639 | //\r | |
640 | Regs.H.AH = 0x00;\r | |
641 | Regs.H.AL = 0x03;\r | |
642 | Status = LegacyBios->Int86 (LegacyBios, 0x10, &Regs);\r | |
643 | return Status;\r | |
644 | case EfiPlatformHookShadowServiceRoms:\r | |
645 | return EFI_SUCCESS;\r | |
646 | case EfiPlatformHookAfterRomInit:\r | |
647 | default:\r | |
648 | return EFI_UNSUPPORTED;\r | |
649 | };\r | |
650 | }\r | |
651 | \r | |
652 | /**\r | |
653 | Returns information associated with PCI IRQ routing.\r | |
654 | This function returns the following information associated with PCI IRQ routing:\r | |
655 | * An IRQ routing table and number of entries in the table.\r | |
656 | * The $PIR table and its size.\r | |
657 | * A list of PCI IRQs and the priority order to assign them.\r | |
658 | \r | |
659 | @param This The protocol instance pointer.\r | |
660 | @param RoutingTable The pointer to PCI IRQ Routing table.\r | |
661 | This location is the $PIR table minus the header.\r | |
662 | @param RoutingTableEntries The number of entries in table.\r | |
663 | @param LocalPirqTable $PIR table.\r | |
664 | @param PirqTableSize $PIR table size.\r | |
665 | @param LocalIrqPriorityTable A list of interrupts in priority order to assign.\r | |
666 | @param IrqPriorityTableEntries The number of entries in the priority table.\r | |
667 | \r | |
668 | @retval EFI_SUCCESS Data was successfully returned.\r | |
669 | \r | |
670 | **/\r | |
671 | EFI_STATUS\r | |
672 | EFIAPI\r | |
673 | GetRoutingTable (\r | |
674 | IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,\r | |
675 | OUT VOID **RoutingTable,\r | |
676 | OUT UINTN *RoutingTableEntries,\r | |
677 | OUT VOID **LocalPirqTable, OPTIONAL\r | |
678 | OUT UINTN *PirqTableSize, OPTIONAL\r | |
679 | OUT VOID **LocalIrqPriorityTable, OPTIONAL\r | |
680 | OUT UINTN *IrqPriorityTableEntries OPTIONAL\r | |
681 | )\r | |
682 | {\r | |
683 | UINT16 PTableSize;\r | |
684 | UINT32 Index;\r | |
685 | UINT8 Bus;\r | |
686 | UINT8 Device;\r | |
687 | UINT8 Function;\r | |
688 | UINT8 Checksum;\r | |
689 | UINT8 *Ptr;\r | |
690 | EFI_STATUS Status;\r | |
691 | EFI_LEGACY_INTERRUPT_PROTOCOL *LegacyInterrupt;\r | |
692 | \r | |
693 | Checksum = 0;\r | |
694 | \r | |
695 | if (LocalPirqTable != NULL) {\r | |
696 | PTableSize = sizeof (EFI_LEGACY_PIRQ_TABLE_HEADER) +\r | |
697 | sizeof (EFI_LEGACY_IRQ_ROUTING_ENTRY) * MAX_IRQ_ROUTING_ENTRIES;\r | |
698 | \r | |
699 | Status = gBS->LocateProtocol (\r | |
700 | &gEfiLegacyInterruptProtocolGuid,\r | |
701 | NULL,\r | |
702 | (VOID**)&LegacyInterrupt\r | |
703 | );\r | |
704 | ASSERT_EFI_ERROR (Status);\r | |
705 | LegacyInterrupt->GetLocation (\r | |
706 | LegacyInterrupt,\r | |
707 | &Bus,\r | |
708 | &Device,\r | |
709 | &Function\r | |
710 | );\r | |
711 | \r | |
712 | //\r | |
713 | // Update fields in $PIR table header\r | |
714 | //\r | |
715 | PirqTableHead.PirqTable.TableSize = PTableSize;\r | |
716 | PirqTableHead.PirqTable.Bus = Bus;\r | |
717 | PirqTableHead.PirqTable.DevFun = (UINT8) ((Device << 3) + Function);\r | |
718 | Ptr = (UINT8 *) (&PirqTableHead);\r | |
719 | \r | |
720 | //\r | |
721 | // Calculate checksum.\r | |
722 | //\r | |
723 | for (Index = 0; Index < PTableSize; Index++) {\r | |
724 | Checksum = (UINT8) (Checksum + (UINT8) *Ptr);\r | |
725 | Ptr += 1;\r | |
726 | }\r | |
727 | Checksum = (UINT8) (0x00 - Checksum);\r | |
728 | PirqTableHead.PirqTable.Checksum = Checksum;\r | |
729 | \r | |
730 | //\r | |
731 | // Update return values.\r | |
732 | //\r | |
733 | *LocalPirqTable = (VOID *) (&PirqTableHead);\r | |
734 | *PirqTableSize = PTableSize;\r | |
735 | }\r | |
736 | \r | |
737 | //\r | |
738 | // More items to return.\r | |
739 | //\r | |
740 | *RoutingTable = PirqTableHead.IrqRoutingEntry;\r | |
741 | *RoutingTableEntries = MAX_IRQ_ROUTING_ENTRIES;\r | |
742 | if (LocalIrqPriorityTable != NULL) {\r | |
743 | *LocalIrqPriorityTable = IrqPriorityTable;\r | |
744 | *IrqPriorityTableEntries = MAX_IRQ_PRIORITY_ENTRIES;\r | |
745 | }\r | |
746 | \r | |
747 | return EFI_SUCCESS;\r | |
748 | }\r | |
749 | \r | |
750 | /**\r | |
751 | Finds the binary data or other platform information.\r | |
752 | \r | |
753 | @param This The protocol instance pointer.\r | |
754 | @param Mode Specifies what data to return. See See EFI_GET_PLATFORM_INFO_MODE enum.\r | |
755 | @param Table Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.\r | |
756 | @param TableSize Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.\r | |
757 | @param Location Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.\r | |
758 | @param Alignment Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.\r | |
759 | @param LegacySegment Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.\r | |
760 | @param LegacyOffset Mode specific. See EFI_GET_PLATFORM_INFO_MODE enum.\r | |
761 | \r | |
762 | @retval EFI_SUCCESS Data returned successfully.\r | |
763 | @retval EFI_UNSUPPORTED Mode is not supported on the platform.\r | |
764 | @retval EFI_NOT_FOUND Binary image or table not found.\r | |
765 | \r | |
766 | **/\r | |
767 | EFI_STATUS\r | |
768 | EFIAPI\r | |
769 | GetPlatformInfo (\r | |
770 | IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,\r | |
771 | IN EFI_GET_PLATFORM_INFO_MODE Mode,\r | |
772 | OUT VOID **Table,\r | |
773 | OUT UINTN *TableSize,\r | |
774 | OUT UINTN *Location,\r | |
775 | OUT UINTN *Alignment,\r | |
776 | IN UINT16 LegacySegment,\r | |
777 | IN UINT16 LegacyOffset\r | |
778 | )\r | |
779 | {\r | |
780 | EFI_STATUS Status;\r | |
781 | UINTN Index;\r | |
782 | \r | |
783 | switch (Mode) {\r | |
784 | case EfiGetPlatformBinarySystemRom:\r | |
785 | //\r | |
786 | // Loop through table of System rom descriptions\r | |
787 | //\r | |
788 | for (Index = 0; mSystemRomTable[Index].Valid != 0; Index++) {\r | |
789 | Status = GetSectionFromFv (\r | |
790 | &mSystemRomTable[Index].FileName,\r | |
791 | EFI_SECTION_RAW,\r | |
792 | 0,\r | |
793 | Table,\r | |
794 | (UINTN *) TableSize\r | |
795 | );\r | |
796 | if (EFI_ERROR (Status)) {\r | |
797 | continue;\r | |
798 | }\r | |
799 | return EFI_SUCCESS;\r | |
800 | }\r | |
801 | \r | |
802 | return EFI_NOT_FOUND;\r | |
803 | case EfiGetPlatformBinaryOem16Data:\r | |
804 | case EfiGetPlatformBinaryMpTable:\r | |
805 | case EfiGetPlatformBinaryOemIntData:\r | |
806 | case EfiGetPlatformBinaryOem32Data:\r | |
807 | case EfiGetPlatformBinaryTpmBinary:\r | |
808 | case EfiGetPlatformPciExpressBase:\r | |
809 | default:\r | |
810 | return EFI_UNSUPPORTED;\r | |
811 | };\r | |
812 | }\r | |
813 | \r | |
814 | /**\r | |
815 | Translates the given PIRQ accounting for bridge.\r | |
816 | This function translates the given PIRQ back through all buses, if required,\r | |
817 | and returns the true PIRQ and associated IRQ.\r | |
818 | \r | |
819 | @param This The protocol instance pointer.\r | |
820 | @param PciBus The PCI bus number for this device.\r | |
821 | @param PciDevice The PCI device number for this device.\r | |
822 | @param PciFunction The PCI function number for this device.\r | |
823 | @param Pirq Input is PIRQ reported by device, and output is true PIRQ.\r | |
824 | @param PciIrq The IRQ already assigned to the PIRQ, or the IRQ to be\r | |
825 | assigned to the PIRQ.\r | |
826 | \r | |
827 | @retval EFI_SUCCESS The PIRQ was translated.\r | |
828 | \r | |
829 | **/\r | |
830 | EFI_STATUS\r | |
831 | EFIAPI\r | |
832 | TranslatePirq (\r | |
833 | IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,\r | |
834 | IN UINTN PciBus,\r | |
835 | IN UINTN PciDevice,\r | |
836 | IN UINTN PciFunction,\r | |
837 | IN OUT UINT8 *Pirq,\r | |
838 | OUT UINT8 *PciIrq\r | |
839 | )\r | |
840 | {\r | |
841 | EFI_LEGACY_INTERRUPT_PROTOCOL *LegacyInterrupt;\r | |
842 | EFI_STATUS Status;\r | |
843 | UINTN Index;\r | |
844 | UINTN Index1;\r | |
845 | UINT8 LocalPirq;\r | |
846 | UINT8 PirqData;\r | |
847 | UINT8 MatchData;\r | |
848 | \r | |
849 | Status = gBS->LocateProtocol (\r | |
850 | &gEfiLegacyInterruptProtocolGuid,\r | |
851 | NULL,\r | |
852 | (VOID**)&LegacyInterrupt\r | |
853 | );\r | |
854 | ASSERT_EFI_ERROR (Status);\r | |
855 | LocalPirq = (UINT8) (*Pirq);\r | |
856 | \r | |
857 | for (Index = 0; Index < MAX_IRQ_ROUTING_ENTRIES; Index++) {\r | |
858 | if ((PirqTableHead.IrqRoutingEntry[Index].Bus == PciBus) &&\r | |
859 | (PirqTableHead.IrqRoutingEntry[Index].Device == PciDevice)) {\r | |
860 | LocalPirq = (UINT8) (PirqTableHead.IrqRoutingEntry[Index].PirqEntry[LocalPirq].Pirq & 0x0f);\r | |
861 | if (LocalPirq > 4) {\r | |
862 | LocalPirq -= 4;\r | |
863 | }\r | |
864 | \r | |
865 | LegacyInterrupt->ReadPirq (LegacyInterrupt, LocalPirq, &PirqData);\r | |
866 | MatchData = PCI_UNUSED;\r | |
867 | while (PirqData == 0) {\r | |
868 | for (Index1 = 0; Index1 < MAX_IRQ_PRIORITY_ENTRIES; Index1++) {\r | |
869 | if ((IrqPriorityTable[Index1].Used == MatchData) &&\r | |
870 | (IrqPriorityTable[Index1].Irq != 0)) {\r | |
871 | PirqData = IrqPriorityTable[Index1].Irq;\r | |
872 | IrqPriorityTable[Index1].Used = 0xff;\r | |
873 | LegacyInterrupt->WritePirq (\r | |
874 | LegacyInterrupt,\r | |
875 | LocalPirq,\r | |
876 | PirqData\r | |
877 | );\r | |
878 | break;\r | |
879 | }\r | |
880 | }\r | |
881 | \r | |
882 | if (PirqData == 0) {\r | |
883 | \r | |
884 | //\r | |
48cf40b8 | 885 | // No unused interrupts, so start reusing them.\r |
8016da21 | 886 | //\r |
887 | MatchData = (UINT8) (~MatchData);\r | |
888 | }\r | |
889 | }\r | |
890 | \r | |
891 | *PciIrq = PirqData;\r | |
892 | *Pirq = LocalPirq;\r | |
893 | }\r | |
894 | }\r | |
895 | \r | |
896 | return EFI_SUCCESS;\r | |
897 | }\r | |
898 | \r | |
899 | \r | |
900 | /**\r | |
901 | Attempt to legacy boot the BootOption. If the EFI contexted has been\r | |
902 | compromised this function will not return.\r | |
903 | \r | |
904 | @param This The protocol instance pointer.\r | |
905 | @param BbsDevicePath The EFI Device Path from BootXXXX variable.\r | |
906 | @param BbsTable The Internal BBS table.\r | |
907 | @param LoadOptionSize The size of LoadOption in size.\r | |
908 | @param LoadOption The LoadOption from BootXXXX variable\r | |
909 | @param EfiToLegacy16BootTable A pointer to BootTable structure\r | |
910 | \r | |
911 | @retval EFI_SUCCESS Ready to boot.\r | |
912 | \r | |
913 | **/\r | |
914 | EFI_STATUS\r | |
915 | EFIAPI\r | |
916 | PrepareToBoot (\r | |
917 | IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,\r | |
918 | IN BBS_BBS_DEVICE_PATH *BbsDevicePath,\r | |
919 | IN VOID *BbsTable,\r | |
920 | IN UINT32 LoadOptionsSize,\r | |
921 | IN VOID *LoadOptions,\r | |
922 | IN VOID *EfiToLegacy16BootTable\r | |
923 | )\r | |
924 | {\r | |
925 | BBS_TABLE *LocalBbsTable;\r | |
926 | EFI_TO_COMPATIBILITY16_BOOT_TABLE *Legacy16BootTable;\r | |
927 | DEVICE_PRODUCER_DATA_HEADER *SioPtr;\r | |
928 | UINT16 DevicePathType;\r | |
929 | UINT16 Index;\r | |
930 | UINT16 Priority;\r | |
931 | \r | |
932 | //\r | |
933 | // Initialize values\r | |
934 | //\r | |
935 | Priority = 0;\r | |
936 | Legacy16BootTable = (EFI_TO_COMPATIBILITY16_BOOT_TABLE*) EfiToLegacy16BootTable;\r | |
937 | \r | |
938 | //\r | |
939 | // Set how Gate A20 is gated by hardware\r | |
940 | //\r | |
941 | SioPtr = &Legacy16BootTable->SioData;\r | |
942 | SioPtr->Flags.A20Kybd = 1;\r | |
943 | SioPtr->Flags.A20Port90 = 1;\r | |
944 | SioPtr->MousePresent = 1;\r | |
945 | \r | |
946 | LocalBbsTable = BbsTable;\r | |
947 | \r | |
948 | //\r | |
949 | // There are 2 cases that must be covered.\r | |
950 | // Case 1: Booting to a legacy OS - BbsDevicePath is non-NULL.\r | |
951 | // Case 2: Booting to an EFI aware OS - BbsDevicePath is NULL.\r | |
952 | // We need to perform the PrepareToBoot function to assign\r | |
953 | // drive numbers to HDD devices to allow the shell or EFI\r | |
954 | // to access them.\r | |
955 | //\r | |
956 | if (BbsDevicePath != NULL) {\r | |
957 | DevicePathType = BbsDevicePath->DeviceType;\r | |
958 | } else {\r | |
959 | DevicePathType = BBS_HARDDISK;\r | |
960 | }\r | |
961 | \r | |
962 | //\r | |
963 | // Skip the boot devices where priority is set by BDS and set the next one\r | |
964 | //\r | |
965 | for (Index = 0; Index < Legacy16BootTable->NumberBbsEntries; Index++) {\r | |
966 | if ((LocalBbsTable[Index].BootPriority != BBS_UNPRIORITIZED_ENTRY) &&\r | |
967 | (LocalBbsTable[Index].BootPriority != BBS_IGNORE_ENTRY) &&\r | |
968 | (LocalBbsTable[Index].BootPriority != BBS_LOWEST_PRIORITY) &&\r | |
969 | (Priority <= LocalBbsTable[Index].BootPriority)) {\r | |
970 | Priority = (UINT16) (LocalBbsTable[Index].BootPriority + 1);\r | |
971 | }\r | |
972 | }\r | |
973 | \r | |
974 | switch (DevicePathType) {\r | |
975 | case BBS_FLOPPY:\r | |
976 | case BBS_HARDDISK:\r | |
977 | case BBS_CDROM:\r | |
978 | case BBS_EMBED_NETWORK:\r | |
979 | for (Index = 0; Index < Legacy16BootTable->NumberBbsEntries; Index++) {\r | |
980 | if ((LocalBbsTable[Index].BootPriority == BBS_UNPRIORITIZED_ENTRY) &&\r | |
981 | (LocalBbsTable[Index].DeviceType == DevicePathType)) {\r | |
982 | LocalBbsTable[Index].BootPriority = Priority;\r | |
983 | ++Priority;\r | |
984 | }\r | |
985 | }\r | |
986 | break;\r | |
987 | case BBS_BEV_DEVICE:\r | |
988 | for (Index = 0; Index < Legacy16BootTable->NumberBbsEntries; Index++) {\r | |
989 | if ((LocalBbsTable[Index].BootPriority == BBS_UNPRIORITIZED_ENTRY) &&\r | |
990 | (LocalBbsTable[Index].Class == 01) &&\r | |
991 | (LocalBbsTable[Index].SubClass == 01)) {\r | |
992 | LocalBbsTable[Index].BootPriority = Priority;\r | |
993 | ++Priority;\r | |
994 | }\r | |
995 | }\r | |
996 | break;\r | |
997 | case BBS_USB:\r | |
998 | case BBS_PCMCIA:\r | |
999 | case BBS_UNKNOWN:\r | |
1000 | default:\r | |
1001 | break;\r | |
1002 | };\r | |
1003 | \r | |
1004 | //\r | |
1005 | // Set priority for rest of devices\r | |
1006 | //\r | |
1007 | for (Index = 0; Index < Legacy16BootTable->NumberBbsEntries; Index++) {\r | |
1008 | if (LocalBbsTable[Index].BootPriority == BBS_UNPRIORITIZED_ENTRY) {\r | |
1009 | LocalBbsTable[Index].BootPriority = Priority;\r | |
1010 | ++Priority;\r | |
1011 | }\r | |
1012 | }\r | |
1013 | \r | |
1014 | return EFI_SUCCESS;\r | |
1015 | }\r | |
1016 | \r | |
1017 | \r | |
1018 | /**\r | |
1019 | Initialize Legacy Platform support\r | |
1020 | \r | |
1021 | @retval EFI_SUCCESS Successfully initialized\r | |
1022 | \r | |
1023 | **/\r | |
1024 | EFI_STATUS\r | |
1025 | LegacyBiosPlatformInstall (\r | |
1026 | VOID\r | |
1027 | )\r | |
1028 | {\r | |
1029 | EFI_STATUS Status;\r | |
1030 | LEGACY_BIOS_PLATFORM_INSTANCE *Private;\r | |
1031 | \r | |
1032 | mImageHandle = gImageHandle;\r | |
1033 | Private = &mPrivateData;\r | |
1034 | \r | |
1035 | //\r | |
1036 | // Grab a copy of all the protocols we depend on.\r | |
1037 | //\r | |
1038 | Private->Signature = LEGACY_BIOS_PLATFORM_INSTANCE_SIGNATURE;\r | |
1039 | Private->LegacyBiosPlatform.GetPlatformInfo = GetPlatformInfo;\r | |
1040 | Private->LegacyBiosPlatform.GetPlatformHandle = GetPlatformHandle;\r | |
1041 | Private->LegacyBiosPlatform.SmmInit = SmmInit;\r | |
1042 | Private->LegacyBiosPlatform.PlatformHooks = PlatformHooks;\r | |
1043 | Private->LegacyBiosPlatform.GetRoutingTable = GetRoutingTable;\r | |
1044 | Private->LegacyBiosPlatform.TranslatePirq = TranslatePirq;\r | |
1045 | Private->LegacyBiosPlatform.PrepareToBoot = PrepareToBoot;\r | |
1046 | Private->ImageHandle = gImageHandle;\r | |
1047 | \r | |
1048 | //\r | |
1049 | // Make a new handle and install the protocol\r | |
1050 | //\r | |
1051 | Private->Handle = NULL;\r | |
1052 | Status = gBS->InstallProtocolInterface (\r | |
1053 | &Private->Handle,\r | |
1054 | &gEfiLegacyBiosPlatformProtocolGuid,\r | |
1055 | EFI_NATIVE_INTERFACE,\r | |
1056 | &Private->LegacyBiosPlatform\r | |
1057 | );\r | |
1058 | return Status;\r | |
1059 | }\r | |
1060 | \r |