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