]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBbs.c
IntelFrameworkModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / IntelFrameworkModulePkg / Csm / LegacyBiosDxe / LegacyBbs.c
CommitLineData
bcecde14 1/** @file\r
2\r
0a6f4824 3Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
bcecde14 4\r
c0a00b14 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
bcecde14 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
17#define FLOPPY_NOT_PRESENT 0\r
18#define FLOPPY_PRESENT_WITH_MEDIA 1\r
19#define FLOPPY_PRESENT_NO_MEDIA 2\r
20\r
21BBS_TABLE *mBbsTable;\r
22BOOLEAN mBbsTableDoneFlag = FALSE;\r
23BOOLEAN IsHaveMediaInFloppy = TRUE;\r
24\r
25/**\r
26 Checks the state of the floppy and if media is inserted.\r
0a6f4824 27\r
bcecde14 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
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
53\r
54 HandleBuffer = NULL;\r
55 HandleCount = 0;\r
56\r
57 gBS->LocateHandleBuffer (\r
58 ByProtocol,\r
59 &gEfiIsaIoProtocolGuid,\r
60 NULL,\r
61 &HandleCount,\r
62 &HandleBuffer\r
63 );\r
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
79 (VOID **) &IsaIo\r
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
88 //\r
89 // Update blockio in case the floppy is inserted in during BdsTimeout\r
90 //\r
91 Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);\r
92\r
93 if (EFI_ERROR (Status)) {\r
94 continue;\r
95 }\r
96\r
97 Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);\r
98\r
99 if (EFI_ERROR (Status)) {\r
100 continue;\r
101 }\r
102\r
103 Status = gBS->HandleProtocol (\r
104 HandleBuffer[Index],\r
105 &gEfiBlockIoProtocolGuid,\r
106 (VOID **) &BlkIo\r
107 );\r
108 if (EFI_ERROR (Status)) {\r
109 continue;\r
110 }\r
111\r
112 if (BlkIo->Media->MediaPresent) {\r
113 FreePool (HandleBuffer);\r
114 return FLOPPY_PRESENT_WITH_MEDIA;\r
115 } else {\r
116 FreePool (HandleBuffer);\r
117 return FLOPPY_PRESENT_NO_MEDIA;\r
118 }\r
119 }\r
120\r
121 FreePool (HandleBuffer);\r
122\r
123 return FLOPPY_NOT_PRESENT;\r
124\r
125}\r
126\r
127\r
128/**\r
129 Complete build of BBS TABLE.\r
130\r
131 @param Private Legacy BIOS Instance data\r
132 @param BbsTable BBS Table passed to 16-bit code\r
133\r
134 @retval EFI_SUCCESS Removable media not present\r
135\r
136**/\r
137EFI_STATUS\r
138LegacyBiosBuildBbs (\r
139 IN LEGACY_BIOS_INSTANCE *Private,\r
140 IN BBS_TABLE *BbsTable\r
141 )\r
142{\r
143 UINTN BbsIndex;\r
144 HDD_INFO *HddInfo;\r
145 UINTN HddIndex;\r
146 UINTN Index;\r
147\r
148 //\r
149 // First entry is floppy.\r
150 // Next 2*MAX_IDE_CONTROLLER entries are for onboard IDE.\r
151 // Next n entries are filled in after each ROM is dispatched.\r
152 // Entry filled in if follow BBS spec. See LegacyPci.c\r
153 // Next entries are for non-BBS compliant ROMS. They are filled in by\r
154 // 16-bit code during Legacy16UpdateBbs invocation. Final BootPriority\r
155 // occurs after that invocation.\r
156 //\r
157 // Floppy\r
158 // Set default state.\r
159 //\r
160 IsHaveMediaInFloppy = HasMediaInFloppy ();\r
161 if (IsHaveMediaInFloppy == FLOPPY_PRESENT_WITH_MEDIA) {\r
162 BbsTable[0].BootPriority = BBS_UNPRIORITIZED_ENTRY;\r
163 } else {\r
164 if (IsHaveMediaInFloppy == FLOPPY_PRESENT_NO_MEDIA) {\r
165 BbsTable[0].BootPriority = BBS_LOWEST_PRIORITY;\r
166 } else {\r
167 BbsTable[0].BootPriority = BBS_IGNORE_ENTRY;\r
168 }\r
169 }\r
170\r
171 BbsTable[0].Bus = 0xff;\r
172 BbsTable[0].Device = 0xff;\r
173 BbsTable[0].Function = 0xff;\r
174 BbsTable[0].DeviceType = BBS_FLOPPY;\r
175 BbsTable[0].Class = 01;\r
176 BbsTable[0].SubClass = 02;\r
177 BbsTable[0].StatusFlags.OldPosition = 0;\r
178 BbsTable[0].StatusFlags.Reserved1 = 0;\r
179 BbsTable[0].StatusFlags.Enabled = 0;\r
180 BbsTable[0].StatusFlags.Failed = 0;\r
181 BbsTable[0].StatusFlags.MediaPresent = 0;\r
182 BbsTable[0].StatusFlags.Reserved2 = 0;\r
183\r
184 //\r
185 // Onboard HDD - Note Each HDD controller controls 2 drives\r
186 // Master & Slave\r
187 //\r
188 HddInfo = &Private->IntThunk->EfiToLegacy16BootTable.HddInfo[0];\r
189 //\r
190 // Get IDE Drive Info\r
191 //\r
192 LegacyBiosBuildIdeData (Private, &HddInfo, 0);\r
193\r
194 for (HddIndex = 0; HddIndex < MAX_IDE_CONTROLLER; HddIndex++) {\r
195\r
196 BbsIndex = HddIndex * 2 + 1;\r
197 for (Index = 0; Index < 2; ++Index) {\r
198\r
199 BbsTable[BbsIndex + Index].Bus = HddInfo[HddIndex].Bus;\r
200 BbsTable[BbsIndex + Index].Device = HddInfo[HddIndex].Device;\r
201 BbsTable[BbsIndex + Index].Function = HddInfo[HddIndex].Function;\r
202 BbsTable[BbsIndex + Index].Class = 01;\r
203 BbsTable[BbsIndex + Index].SubClass = 01;\r
204 BbsTable[BbsIndex + Index].StatusFlags.OldPosition = 0;\r
205 BbsTable[BbsIndex + Index].StatusFlags.Reserved1 = 0;\r
206 BbsTable[BbsIndex + Index].StatusFlags.Enabled = 0;\r
207 BbsTable[BbsIndex + Index].StatusFlags.Failed = 0;\r
208 BbsTable[BbsIndex + Index].StatusFlags.MediaPresent = 0;\r
209 BbsTable[BbsIndex + Index].StatusFlags.Reserved2 = 0;\r
210\r
211 //\r
212 // If no controller found or no device found set to ignore\r
213 // else set to unprioritized and set device type\r
214 //\r
215 if (HddInfo[HddIndex].CommandBaseAddress == 0) {\r
216 BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY;\r
217 } else {\r
218 if (Index == 0) {\r
219 if ((HddInfo[HddIndex].Status & (HDD_MASTER_IDE | HDD_MASTER_ATAPI_CDROM | HDD_MASTER_ATAPI_ZIPDISK)) != 0) {\r
220 BbsTable[BbsIndex + Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;\r
221 if ((HddInfo[HddIndex].Status & HDD_MASTER_IDE) != 0) {\r
222 BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK;\r
223 } else if ((HddInfo[HddIndex].Status & HDD_MASTER_ATAPI_CDROM) != 0) {\r
224 BbsTable[BbsIndex + Index].DeviceType = BBS_CDROM;\r
225 } else {\r
226 //\r
227 // for ZIPDISK\r
228 //\r
229 BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK;\r
230 }\r
231 } else {\r
232 BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY;\r
233 }\r
234 } else {\r
235 if ((HddInfo[HddIndex].Status & (HDD_SLAVE_IDE | HDD_SLAVE_ATAPI_CDROM | HDD_SLAVE_ATAPI_ZIPDISK)) != 0) {\r
236 BbsTable[BbsIndex + Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;\r
237 if ((HddInfo[HddIndex].Status & HDD_SLAVE_IDE) != 0) {\r
238 BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK;\r
239 } else if ((HddInfo[HddIndex].Status & HDD_SLAVE_ATAPI_CDROM) != 0) {\r
240 BbsTable[BbsIndex + Index].DeviceType = BBS_CDROM;\r
241 } else {\r
242 //\r
243 // for ZIPDISK\r
244 //\r
245 BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK;\r
246 }\r
247 } else {\r
248 BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY;\r
249 }\r
250 }\r
251 }\r
252 }\r
253 }\r
254\r
255 return EFI_SUCCESS;\r
256\r
257}\r
258\r
259\r
260/**\r
261 Get all BBS info\r
262\r
263 @param This Protocol instance pointer.\r
264 @param HddCount Number of HDD_INFO structures\r
265 @param HddInfo Onboard IDE controller information\r
266 @param BbsCount Number of BBS_TABLE structures\r
267 @param BbsTable List BBS entries\r
268\r
269 @retval EFI_SUCCESS Tables returned\r
270 @retval EFI_NOT_FOUND resource not found\r
271 @retval EFI_DEVICE_ERROR can not get BBS table\r
272\r
273**/\r
274EFI_STATUS\r
275EFIAPI\r
276LegacyBiosGetBbsInfo (\r
277 IN EFI_LEGACY_BIOS_PROTOCOL *This,\r
278 OUT UINT16 *HddCount,\r
279 OUT HDD_INFO **HddInfo,\r
280 OUT UINT16 *BbsCount,\r
281 OUT BBS_TABLE **BbsTable\r
282 )\r
283{\r
284 LEGACY_BIOS_INSTANCE *Private;\r
285 EFI_IA32_REGISTER_SET Regs;\r
286 EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable;\r
287// HDD_INFO *LocalHddInfo;\r
288// IN BBS_TABLE *LocalBbsTable;\r
289 UINTN NumHandles;\r
290 EFI_HANDLE *HandleBuffer;\r
291 UINTN Index;\r
292 UINTN TempData;\r
293 UINT32 Granularity;\r
294\r
295 HandleBuffer = NULL;\r
296\r
297 Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This);\r
298 EfiToLegacy16BootTable = &Private->IntThunk->EfiToLegacy16BootTable;\r
299// LocalHddInfo = EfiToLegacy16BootTable->HddInfo;\r
300// LocalBbsTable = (BBS_TABLE*)(UINTN)EfiToLegacy16BootTable->BbsTable;\r
301\r
302 if (!mBbsTableDoneFlag) {\r
303 mBbsTable = Private->BbsTablePtr;\r
304\r
305 //\r
306 // Always enable disk controllers so 16-bit CSM code has valid information for all\r
307 // drives.\r
308 //\r
309 //\r
310 // Get PciRootBridgeIO protocol\r
311 //\r
312 gBS->LocateHandleBuffer (\r
313 ByProtocol,\r
314 &gEfiPciRootBridgeIoProtocolGuid,\r
315 NULL,\r
316 &NumHandles,\r
317 &HandleBuffer\r
318 );\r
319\r
320 if (NumHandles == 0) {\r
321 return EFI_NOT_FOUND;\r
322 }\r
323\r
324 mBbsTableDoneFlag = TRUE;\r
325 for (Index = 0; Index < NumHandles; Index++) {\r
326 //\r
327 // Connect PciRootBridgeIO protocol handle with FALSE parameter to let\r
328 // PCI bus driver enumerate all subsequent handles\r
329 //\r
330 gBS->ConnectController (HandleBuffer[Index], NULL, NULL, FALSE);\r
331\r
332 }\r
333\r
334 LegacyBiosBuildBbs (Private, mBbsTable);\r
335\r
336 Private->LegacyRegion->UnLock (Private->LegacyRegion, 0xe0000, 0x20000, &Granularity);\r
337\r
338 //\r
339 // Call into Legacy16 code to add to BBS table for non BBS compliant OPROMs.\r
340 //\r
341 ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));\r
342 Regs.X.AX = Legacy16UpdateBbs;\r
343\r
344 //\r
345 // Pass in handoff data\r
346 //\r
347 TempData = (UINTN) EfiToLegacy16BootTable;\r
81c0d6e9 348 Regs.X.ES = NORMALIZE_EFI_SEGMENT ((UINT32) TempData);\r
349 Regs.X.BX = NORMALIZE_EFI_OFFSET ((UINT32) TempData);\r
bcecde14 350\r
351 Private->LegacyBios.FarCall86 (\r
352 This,\r
353 Private->Legacy16CallSegment,\r
354 Private->Legacy16CallOffset,\r
355 &Regs,\r
356 NULL,\r
357 0\r
358 );\r
359\r
360 Private->Cpu->FlushDataCache (Private->Cpu, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate);\r
361 Private->LegacyRegion->Lock (Private->LegacyRegion, 0xe0000, 0x20000, &Granularity);\r
362\r
363 if (Regs.X.AX != 0) {\r
364 return EFI_DEVICE_ERROR;\r
365 }\r
366 }\r
367\r
368 if (HandleBuffer != NULL) {\r
369 FreePool (HandleBuffer);\r
370 }\r
371\r
372 *HddCount = MAX_IDE_CONTROLLER;\r
373 *HddInfo = EfiToLegacy16BootTable->HddInfo;\r
374 *BbsTable = (BBS_TABLE*)(UINTN)EfiToLegacy16BootTable->BbsTable;\r
375 *BbsCount = (UINT16) (sizeof (Private->IntThunk->BbsTable) / sizeof (BBS_TABLE));\r
376 return EFI_SUCCESS;\r
377}\r