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