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