]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Csm/LegacyBiosDxe/LegacyBbs.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / Csm / LegacyBiosDxe / LegacyBbs.c
CommitLineData
b522c77b
HW
1/** @file\r
2\r
3Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
4\r
5SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include "LegacyBiosInterface.h"\r
10#include <IndustryStandard/Pci.h>\r
11\r
12// Give floppy 3 states\r
13// FLOPPY_PRESENT_WITH_MEDIA = Floppy controller present and media is inserted\r
14// FLOPPY_NOT_PRESENT = No floppy controller present\r
15// FLOPPY_PRESENT_NO_MEDIA = Floppy controller present but no media inserted\r
16//\r
ac0a286f
MK
17#define FLOPPY_NOT_PRESENT 0\r
18#define FLOPPY_PRESENT_WITH_MEDIA 1\r
19#define FLOPPY_PRESENT_NO_MEDIA 2\r
b522c77b 20\r
ac0a286f
MK
21BBS_TABLE *mBbsTable;\r
22BOOLEAN mBbsTableDoneFlag = FALSE;\r
23BOOLEAN IsHaveMediaInFloppy = TRUE;\r
b522c77b
HW
24\r
25/**\r
26 Checks the state of the floppy and if media is inserted.\r
27\r
28 This routine checks the state of the floppy and if media is inserted.\r
29 There are 3 cases:\r
30 No floppy present - Set BBS entry to ignore\r
31 Floppy present & no media - Set BBS entry to lowest priority. We cannot\r
32 set it to ignore since 16-bit CSM will\r
33 indicate no floppy and thus drive A: is\r
34 unusable. CSM-16 will not try floppy since\r
35 lowest priority and thus not incur boot\r
36 time penality.\r
37 Floppy present & media - Set BBS entry to some priority.\r
38\r
39 @return State of floppy media\r
40\r
41**/\r
42UINT8\r
43HasMediaInFloppy (\r
44 VOID\r
45 )\r
46{\r
ac0a286f
MK
47 EFI_STATUS Status;\r
48 UINTN HandleCount;\r
49 EFI_HANDLE *HandleBuffer;\r
50 UINTN Index;\r
51 EFI_ISA_IO_PROTOCOL *IsaIo;\r
52 EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
b522c77b 53\r
ac0a286f
MK
54 HandleBuffer = NULL;\r
55 HandleCount = 0;\r
b522c77b
HW
56\r
57 gBS->LocateHandleBuffer (\r
ac0a286f
MK
58 ByProtocol,\r
59 &gEfiIsaIoProtocolGuid,\r
60 NULL,\r
61 &HandleCount,\r
62 &HandleBuffer\r
63 );\r
b522c77b
HW
64\r
65 //\r
66 // If don't find any ISA/IO protocol assume no floppy. Need for floppy\r
67 // free system\r
68 //\r
69 if (HandleCount == 0) {\r
70 return FLOPPY_NOT_PRESENT;\r
71 }\r
72\r
73 ASSERT (HandleBuffer != NULL);\r
74\r
75 for (Index = 0; Index < HandleCount; Index++) {\r
76 Status = gBS->HandleProtocol (\r
77 HandleBuffer[Index],\r
78 &gEfiIsaIoProtocolGuid,\r
ac0a286f 79 (VOID **)&IsaIo\r
b522c77b
HW
80 );\r
81 if (EFI_ERROR (Status)) {\r
82 continue;\r
83 }\r
84\r
85 if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x604)) {\r
86 continue;\r
87 }\r
ac0a286f 88\r
b522c77b
HW
89 //\r
90 // Update blockio in case the floppy is inserted in during BdsTimeout\r
91 //\r
92 Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);\r
93\r
94 if (EFI_ERROR (Status)) {\r
95 continue;\r
96 }\r
97\r
98 Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);\r
99\r
100 if (EFI_ERROR (Status)) {\r
101 continue;\r
102 }\r
103\r
104 Status = gBS->HandleProtocol (\r
105 HandleBuffer[Index],\r
106 &gEfiBlockIoProtocolGuid,\r
ac0a286f 107 (VOID **)&BlkIo\r
b522c77b
HW
108 );\r
109 if (EFI_ERROR (Status)) {\r
110 continue;\r
111 }\r
112\r
113 if (BlkIo->Media->MediaPresent) {\r
114 FreePool (HandleBuffer);\r
115 return FLOPPY_PRESENT_WITH_MEDIA;\r
116 } else {\r
117 FreePool (HandleBuffer);\r
118 return FLOPPY_PRESENT_NO_MEDIA;\r
119 }\r
120 }\r
121\r
122 FreePool (HandleBuffer);\r
123\r
124 return FLOPPY_NOT_PRESENT;\r
b522c77b
HW
125}\r
126\r
b522c77b
HW
127/**\r
128 Complete build of BBS TABLE.\r
129\r
130 @param Private Legacy BIOS Instance data\r
131 @param BbsTable BBS Table passed to 16-bit code\r
132\r
133 @retval EFI_SUCCESS Removable media not present\r
134\r
135**/\r
136EFI_STATUS\r
137LegacyBiosBuildBbs (\r
ac0a286f
MK
138 IN LEGACY_BIOS_INSTANCE *Private,\r
139 IN BBS_TABLE *BbsTable\r
b522c77b
HW
140 )\r
141{\r
16ec209a
DW
142 UINTN BbsIndex;\r
143 HDD_INFO *HddInfo;\r
144 UINTN HddIndex;\r
145 UINTN Index;\r
146 EFI_HANDLE *BlockIoHandles;\r
147 UINTN NumberBlockIoHandles;\r
148 UINTN BlockIndex;\r
149 EFI_STATUS Status;\r
b522c77b
HW
150\r
151 //\r
152 // First entry is floppy.\r
153 // Next 2*MAX_IDE_CONTROLLER entries are for onboard IDE.\r
154 // Next n entries are filled in after each ROM is dispatched.\r
155 // Entry filled in if follow BBS spec. See LegacyPci.c\r
156 // Next entries are for non-BBS compliant ROMS. They are filled in by\r
157 // 16-bit code during Legacy16UpdateBbs invocation. Final BootPriority\r
158 // occurs after that invocation.\r
159 //\r
160 // Floppy\r
161 // Set default state.\r
162 //\r
163 IsHaveMediaInFloppy = HasMediaInFloppy ();\r
164 if (IsHaveMediaInFloppy == FLOPPY_PRESENT_WITH_MEDIA) {\r
165 BbsTable[0].BootPriority = BBS_UNPRIORITIZED_ENTRY;\r
166 } else {\r
167 if (IsHaveMediaInFloppy == FLOPPY_PRESENT_NO_MEDIA) {\r
168 BbsTable[0].BootPriority = BBS_LOWEST_PRIORITY;\r
169 } else {\r
170 BbsTable[0].BootPriority = BBS_IGNORE_ENTRY;\r
171 }\r
172 }\r
173\r
ac0a286f
MK
174 BbsTable[0].Bus = 0xff;\r
175 BbsTable[0].Device = 0xff;\r
176 BbsTable[0].Function = 0xff;\r
177 BbsTable[0].DeviceType = BBS_FLOPPY;\r
178 BbsTable[0].Class = 01;\r
179 BbsTable[0].SubClass = 02;\r
180 BbsTable[0].StatusFlags.OldPosition = 0;\r
181 BbsTable[0].StatusFlags.Reserved1 = 0;\r
182 BbsTable[0].StatusFlags.Enabled = 0;\r
183 BbsTable[0].StatusFlags.Failed = 0;\r
184 BbsTable[0].StatusFlags.MediaPresent = 0;\r
185 BbsTable[0].StatusFlags.Reserved2 = 0;\r
b522c77b
HW
186\r
187 //\r
188 // Onboard HDD - Note Each HDD controller controls 2 drives\r
189 // Master & Slave\r
190 //\r
191 HddInfo = &Private->IntThunk->EfiToLegacy16BootTable.HddInfo[0];\r
192 //\r
193 // Get IDE Drive Info\r
194 //\r
195 LegacyBiosBuildIdeData (Private, &HddInfo, 0);\r
196\r
197 for (HddIndex = 0; HddIndex < MAX_IDE_CONTROLLER; HddIndex++) {\r
b522c77b
HW
198 BbsIndex = HddIndex * 2 + 1;\r
199 for (Index = 0; Index < 2; ++Index) {\r
b522c77b
HW
200 BbsTable[BbsIndex + Index].Bus = HddInfo[HddIndex].Bus;\r
201 BbsTable[BbsIndex + Index].Device = HddInfo[HddIndex].Device;\r
202 BbsTable[BbsIndex + Index].Function = HddInfo[HddIndex].Function;\r
203 BbsTable[BbsIndex + Index].Class = 01;\r
204 BbsTable[BbsIndex + Index].SubClass = 01;\r
205 BbsTable[BbsIndex + Index].StatusFlags.OldPosition = 0;\r
206 BbsTable[BbsIndex + Index].StatusFlags.Reserved1 = 0;\r
207 BbsTable[BbsIndex + Index].StatusFlags.Enabled = 0;\r
208 BbsTable[BbsIndex + Index].StatusFlags.Failed = 0;\r
209 BbsTable[BbsIndex + Index].StatusFlags.MediaPresent = 0;\r
210 BbsTable[BbsIndex + Index].StatusFlags.Reserved2 = 0;\r
211\r
212 //\r
213 // If no controller found or no device found set to ignore\r
214 // else set to unprioritized and set device type\r
215 //\r
216 if (HddInfo[HddIndex].CommandBaseAddress == 0) {\r
217 BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY;\r
218 } else {\r
219 if (Index == 0) {\r
220 if ((HddInfo[HddIndex].Status & (HDD_MASTER_IDE | HDD_MASTER_ATAPI_CDROM | HDD_MASTER_ATAPI_ZIPDISK)) != 0) {\r
221 BbsTable[BbsIndex + Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;\r
222 if ((HddInfo[HddIndex].Status & HDD_MASTER_IDE) != 0) {\r
223 BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK;\r
224 } else if ((HddInfo[HddIndex].Status & HDD_MASTER_ATAPI_CDROM) != 0) {\r
225 BbsTable[BbsIndex + Index].DeviceType = BBS_CDROM;\r
226 } else {\r
227 //\r
228 // for ZIPDISK\r
229 //\r
230 BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK;\r
231 }\r
232 } else {\r
233 BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY;\r
234 }\r
235 } else {\r
236 if ((HddInfo[HddIndex].Status & (HDD_SLAVE_IDE | HDD_SLAVE_ATAPI_CDROM | HDD_SLAVE_ATAPI_ZIPDISK)) != 0) {\r
237 BbsTable[BbsIndex + Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;\r
238 if ((HddInfo[HddIndex].Status & HDD_SLAVE_IDE) != 0) {\r
239 BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK;\r
240 } else if ((HddInfo[HddIndex].Status & HDD_SLAVE_ATAPI_CDROM) != 0) {\r
241 BbsTable[BbsIndex + Index].DeviceType = BBS_CDROM;\r
242 } else {\r
243 //\r
244 // for ZIPDISK\r
245 //\r
246 BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK;\r
247 }\r
248 } else {\r
249 BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY;\r
250 }\r
251 }\r
252 }\r
253 }\r
254 }\r
255\r
16ec209a
DW
256 //\r
257 // Add non-IDE block devices\r
258 //\r
259 BbsIndex = HddIndex * 2 + 1;\r
260\r
261 Status = gBS->LocateHandleBuffer (\r
262 ByProtocol,\r
263 &gEfiBlockIoProtocolGuid,\r
264 NULL,\r
265 &NumberBlockIoHandles,\r
266 &BlockIoHandles\r
267 );\r
268\r
269 if (!EFI_ERROR (Status)) {\r
270 UINTN Removable;\r
271 EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
272 EFI_PCI_IO_PROTOCOL *PciIo;\r
273 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
274 EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;\r
275 EFI_HANDLE PciHandle;\r
276 UINTN SegNum;\r
277 UINTN BusNum;\r
278 UINTN DevNum;\r
279 UINTN FuncNum;\r
280\r
281 for (Removable = 0; Removable < 2; Removable++) {\r
282 for (BlockIndex = 0; BlockIndex < NumberBlockIoHandles; BlockIndex++) {\r
283 Status = gBS->HandleProtocol (\r
284 BlockIoHandles[BlockIndex],\r
285 &gEfiBlockIoProtocolGuid,\r
ac0a286f 286 (VOID **)&BlkIo\r
16ec209a
DW
287 );\r
288\r
289 if (EFI_ERROR (Status)) {\r
290 continue;\r
291 }\r
292\r
293 //\r
294 // Skip the logical partitions\r
295 //\r
296 if (BlkIo->Media->LogicalPartition) {\r
297 continue;\r
298 }\r
299\r
300 //\r
301 // Skip the fixed block io then the removable block io\r
302 //\r
303 if (BlkIo->Media->RemovableMedia == ((Removable == 0) ? FALSE : TRUE)) {\r
304 continue;\r
305 }\r
b522c77b 306\r
16ec209a
DW
307 //\r
308 // Get Device Path\r
309 //\r
310 Status = gBS->HandleProtocol (\r
311 BlockIoHandles[BlockIndex],\r
312 &gEfiDevicePathProtocolGuid,\r
ac0a286f 313 (VOID **)&DevicePath\r
16ec209a
DW
314 );\r
315 if (EFI_ERROR (Status)) {\r
316 continue;\r
317 }\r
318\r
319 //\r
320 // Skip ATA devices as they have already been handled\r
321 //\r
322 DevicePathNode = DevicePath;\r
323 while (!IsDevicePathEnd (DevicePathNode)) {\r
ac0a286f
MK
324 if ((DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH) &&\r
325 (DevicePathSubType (DevicePathNode) == MSG_ATAPI_DP))\r
326 {\r
16ec209a
DW
327 break;\r
328 }\r
ac0a286f 329\r
16ec209a
DW
330 DevicePathNode = NextDevicePathNode (DevicePathNode);\r
331 }\r
ac0a286f 332\r
16ec209a 333 if (!IsDevicePathEnd (DevicePathNode)) {\r
ac0a286f 334 continue;\r
16ec209a
DW
335 }\r
336\r
337 //\r
338 // Locate which PCI device\r
339 //\r
340 Status = gBS->LocateDevicePath (\r
341 &gEfiPciIoProtocolGuid,\r
342 &DevicePath,\r
343 &PciHandle\r
344 );\r
345 if (EFI_ERROR (Status)) {\r
346 continue;\r
347 }\r
348\r
349 Status = gBS->HandleProtocol (\r
350 PciHandle,\r
351 &gEfiPciIoProtocolGuid,\r
ac0a286f 352 (VOID **)&PciIo\r
16ec209a
DW
353 );\r
354 if (EFI_ERROR (Status)) {\r
355 continue;\r
356 }\r
357\r
358 Status = PciIo->GetLocation (\r
359 PciIo,\r
360 &SegNum,\r
361 &BusNum,\r
362 &DevNum,\r
363 &FuncNum\r
364 );\r
365 if (EFI_ERROR (Status)) {\r
366 continue;\r
367 }\r
368\r
369 if (SegNum != 0) {\r
ac0a286f
MK
370 DEBUG ((\r
371 DEBUG_WARN,\r
372 "CSM cannot use PCI devices in segment %Lu\n",\r
373 (UINT64)SegNum\r
374 ));\r
16ec209a
DW
375 continue;\r
376 }\r
377\r
ac0a286f
MK
378 DEBUG ((\r
379 DEBUG_INFO,\r
380 "Add Legacy Bbs entry for PCI %d/%d/%d\n",\r
381 BusNum,\r
382 DevNum,\r
383 FuncNum\r
384 ));\r
16ec209a
DW
385\r
386 BbsTable[BbsIndex].Bus = BusNum;\r
387 BbsTable[BbsIndex].Device = DevNum;\r
388 BbsTable[BbsIndex].Function = FuncNum;\r
389 BbsTable[BbsIndex].Class = 1;\r
390 BbsTable[BbsIndex].SubClass = 0x80;\r
391 BbsTable[BbsIndex].StatusFlags.OldPosition = 0;\r
392 BbsTable[BbsIndex].StatusFlags.Reserved1 = 0;\r
393 BbsTable[BbsIndex].StatusFlags.Enabled = 0;\r
394 BbsTable[BbsIndex].StatusFlags.Failed = 0;\r
395 BbsTable[BbsIndex].StatusFlags.MediaPresent = 0;\r
396 BbsTable[BbsIndex].StatusFlags.Reserved2 = 0;\r
397 BbsTable[BbsIndex].DeviceType = BBS_HARDDISK;\r
398 BbsTable[BbsIndex].BootPriority = BBS_UNPRIORITIZED_ENTRY;\r
399 BbsIndex++;\r
400\r
401 if (BbsIndex == MAX_BBS_ENTRIES) {\r
402 Removable = 2;\r
403 break;\r
404 }\r
405 }\r
406 }\r
407\r
408 FreePool (BlockIoHandles);\r
409 }\r
410\r
411 return EFI_SUCCESS;\r
b522c77b
HW
412}\r
413\r
b522c77b
HW
414/**\r
415 Get all BBS info\r
416\r
417 @param This Protocol instance pointer.\r
418 @param HddCount Number of HDD_INFO structures\r
419 @param HddInfo Onboard IDE controller information\r
420 @param BbsCount Number of BBS_TABLE structures\r
421 @param BbsTable List BBS entries\r
422\r
423 @retval EFI_SUCCESS Tables returned\r
424 @retval EFI_NOT_FOUND resource not found\r
425 @retval EFI_DEVICE_ERROR can not get BBS table\r
426\r
427**/\r
428EFI_STATUS\r
429EFIAPI\r
430LegacyBiosGetBbsInfo (\r
ac0a286f
MK
431 IN EFI_LEGACY_BIOS_PROTOCOL *This,\r
432 OUT UINT16 *HddCount,\r
433 OUT HDD_INFO **HddInfo,\r
434 OUT UINT16 *BbsCount,\r
435 OUT BBS_TABLE **BbsTable\r
b522c77b
HW
436 )\r
437{\r
ac0a286f
MK
438 LEGACY_BIOS_INSTANCE *Private;\r
439 EFI_IA32_REGISTER_SET Regs;\r
440 EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable;\r
441 // HDD_INFO *LocalHddInfo;\r
442 // IN BBS_TABLE *LocalBbsTable;\r
443 UINTN NumHandles;\r
444 EFI_HANDLE *HandleBuffer;\r
445 UINTN Index;\r
446 UINTN TempData;\r
447 UINT32 Granularity;\r
448\r
449 HandleBuffer = NULL;\r
450\r
451 Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This);\r
452 EfiToLegacy16BootTable = &Private->IntThunk->EfiToLegacy16BootTable;\r
453 // LocalHddInfo = EfiToLegacy16BootTable->HddInfo;\r
454 // LocalBbsTable = (BBS_TABLE*)(UINTN)EfiToLegacy16BootTable->BbsTable;\r
b522c77b
HW
455\r
456 if (!mBbsTableDoneFlag) {\r
457 mBbsTable = Private->BbsTablePtr;\r
458\r
459 //\r
460 // Always enable disk controllers so 16-bit CSM code has valid information for all\r
461 // drives.\r
462 //\r
463 //\r
464 // Get PciRootBridgeIO protocol\r
465 //\r
466 gBS->LocateHandleBuffer (\r
ac0a286f
MK
467 ByProtocol,\r
468 &gEfiPciRootBridgeIoProtocolGuid,\r
469 NULL,\r
470 &NumHandles,\r
471 &HandleBuffer\r
472 );\r
b522c77b
HW
473\r
474 if (NumHandles == 0) {\r
475 return EFI_NOT_FOUND;\r
476 }\r
477\r
478 mBbsTableDoneFlag = TRUE;\r
479 for (Index = 0; Index < NumHandles; Index++) {\r
480 //\r
481 // Connect PciRootBridgeIO protocol handle with FALSE parameter to let\r
482 // PCI bus driver enumerate all subsequent handles\r
483 //\r
484 gBS->ConnectController (HandleBuffer[Index], NULL, NULL, FALSE);\r
b522c77b
HW
485 }\r
486\r
487 LegacyBiosBuildBbs (Private, mBbsTable);\r
488\r
489 Private->LegacyRegion->UnLock (Private->LegacyRegion, 0xe0000, 0x20000, &Granularity);\r
490\r
491 //\r
492 // Call into Legacy16 code to add to BBS table for non BBS compliant OPROMs.\r
493 //\r
494 ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));\r
495 Regs.X.AX = Legacy16UpdateBbs;\r
496\r
497 //\r
498 // Pass in handoff data\r
499 //\r
ac0a286f
MK
500 TempData = (UINTN)EfiToLegacy16BootTable;\r
501 Regs.X.ES = NORMALIZE_EFI_SEGMENT ((UINT32)TempData);\r
502 Regs.X.BX = NORMALIZE_EFI_OFFSET ((UINT32)TempData);\r
b522c77b
HW
503\r
504 Private->LegacyBios.FarCall86 (\r
ac0a286f
MK
505 This,\r
506 Private->Legacy16CallSegment,\r
507 Private->Legacy16CallOffset,\r
508 &Regs,\r
509 NULL,\r
510 0\r
511 );\r
b522c77b
HW
512\r
513 Private->Cpu->FlushDataCache (Private->Cpu, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate);\r
514 Private->LegacyRegion->Lock (Private->LegacyRegion, 0xe0000, 0x20000, &Granularity);\r
515\r
516 if (Regs.X.AX != 0) {\r
517 return EFI_DEVICE_ERROR;\r
518 }\r
519 }\r
520\r
521 if (HandleBuffer != NULL) {\r
522 FreePool (HandleBuffer);\r
523 }\r
524\r
525 *HddCount = MAX_IDE_CONTROLLER;\r
526 *HddInfo = EfiToLegacy16BootTable->HddInfo;\r
ac0a286f
MK
527 *BbsTable = (BBS_TABLE *)(UINTN)EfiToLegacy16BootTable->BbsTable;\r
528 *BbsCount = (UINT16)(sizeof (Private->IntThunk->BbsTable) / sizeof (BBS_TABLE));\r
b522c77b
HW
529 return EFI_SUCCESS;\r
530}\r