]>
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 | |
ac0a286f MK |
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 | |
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 |
32 | SYSTEM_ROM_TABLE mSystemRomTable[] = {\r |
33 | { SYSTEM_ROM_FILE_GUID, 1 },\r | |
34 | { NULL_ROM_FILE_GUID, 0 }\r | |
8016da21 | 35 | };\r |
36 | \r | |
37 | EFI_HANDLE mVgaHandles[0x20];\r | |
38 | EFI_HANDLE mDiskHandles[0x20];\r | |
39 | EFI_HANDLE mIsaHandles[0x20];\r | |
40 | \r | |
ac0a286f MK |
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 | |
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 | 57 | EFI_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 |
100 | LEGACY_BIOS_PLATFORM_INSTANCE mPrivateData;\r |
101 | EFI_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 | |
115 | EFI_STATUS\r | |
116 | FindAllDeviceTypes (\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 | |
225 | EFI_STATUS\r | |
226 | EFIAPI\r | |
227 | SmmInit (\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 | |
241 | VOID\r | |
242 | GetSelectedVgaDeviceInfo (\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 | |
364 | EFI_STATUS\r | |
365 | EFIAPI\r | |
366 | GetPlatformHandle (\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 | |
634 | EFI_STATUS\r | |
635 | EFIAPI\r | |
636 | PlatformHooks (\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 | |
692 | EFI_STATUS\r | |
693 | EFIAPI\r | |
694 | GetRoutingTable (\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 | |
789 | EFI_STATUS\r | |
790 | EFIAPI\r | |
791 | GetPlatformInfo (\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 | |
853 | EFI_STATUS\r | |
854 | EFIAPI\r | |
855 | TranslatePirq (\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 | |
937 | EFI_STATUS\r | |
938 | EFIAPI\r | |
939 | PrepareToBoot (\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 | |
1051 | EFI_STATUS\r | |
1052 | LegacyBiosPlatformInstall (\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 |