3 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions
7 of the BSD License which accompanies this distribution. The
8 full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "LegacyBiosInterface.h"
17 #include <IndustryStandard/Pci.h>
19 // Give floppy 3 states
20 // FLOPPY_PRESENT_WITH_MEDIA = Floppy controller present and media is inserted
21 // FLOPPY_NOT_PRESENT = No floppy controller present
22 // FLOPPY_PRESENT_NO_MEDIA = Floppy controller present but no media inserted
24 #define FLOPPY_NOT_PRESENT 0
25 #define FLOPPY_PRESENT_WITH_MEDIA 1
26 #define FLOPPY_PRESENT_NO_MEDIA 2
29 BOOLEAN mBbsTableDoneFlag
= FALSE
;
30 BOOLEAN IsHaveMediaInFloppy
= TRUE
;
33 Checks the state of the floppy and if media is inserted.
35 This routine checks the state of the floppy and if media is inserted.
37 No floppy present - Set BBS entry to ignore
38 Floppy present & no media - Set BBS entry to lowest priority. We cannot
39 set it to ignore since 16-bit CSM will
40 indicate no floppy and thus drive A: is
41 unusable. CSM-16 will not try floppy since
42 lowest priority and thus not incur boot
44 Floppy present & media - Set BBS entry to some priority.
46 @return State of floppy media
56 EFI_HANDLE
*HandleBuffer
;
58 EFI_ISA_IO_PROTOCOL
*IsaIo
;
59 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
64 gBS
->LocateHandleBuffer (
66 &gEfiIsaIoProtocolGuid
,
73 // If don't find any ISA/IO protocol assume no floppy. Need for floppy
76 if (HandleCount
== 0) {
77 return FLOPPY_NOT_PRESENT
;
80 ASSERT (HandleBuffer
!= NULL
);
82 for (Index
= 0; Index
< HandleCount
; Index
++) {
83 Status
= gBS
->HandleProtocol (
85 &gEfiIsaIoProtocolGuid
,
88 if (EFI_ERROR (Status
)) {
92 if (IsaIo
->ResourceList
->Device
.HID
!= EISA_PNP_ID (0x604)) {
96 // Update blockio in case the floppy is inserted in during BdsTimeout
98 Status
= gBS
->DisconnectController (HandleBuffer
[Index
], NULL
, NULL
);
100 if (EFI_ERROR (Status
)) {
104 Status
= gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
106 if (EFI_ERROR (Status
)) {
110 Status
= gBS
->HandleProtocol (
112 &gEfiBlockIoProtocolGuid
,
115 if (EFI_ERROR (Status
)) {
119 if (BlkIo
->Media
->MediaPresent
) {
120 FreePool (HandleBuffer
);
121 return FLOPPY_PRESENT_WITH_MEDIA
;
123 FreePool (HandleBuffer
);
124 return FLOPPY_PRESENT_NO_MEDIA
;
128 FreePool (HandleBuffer
);
130 return FLOPPY_NOT_PRESENT
;
136 Complete build of BBS TABLE.
138 @param Private Legacy BIOS Instance data
139 @param BbsTable BBS Table passed to 16-bit code
141 @retval EFI_SUCCESS Removable media not present
146 IN LEGACY_BIOS_INSTANCE
*Private
,
147 IN BBS_TABLE
*BbsTable
156 // First entry is floppy.
157 // Next 2*MAX_IDE_CONTROLLER entries are for onboard IDE.
158 // Next n entries are filled in after each ROM is dispatched.
159 // Entry filled in if follow BBS spec. See LegacyPci.c
160 // Next entries are for non-BBS compliant ROMS. They are filled in by
161 // 16-bit code during Legacy16UpdateBbs invocation. Final BootPriority
162 // occurs after that invocation.
165 // Set default state.
167 IsHaveMediaInFloppy
= HasMediaInFloppy ();
168 if (IsHaveMediaInFloppy
== FLOPPY_PRESENT_WITH_MEDIA
) {
169 BbsTable
[0].BootPriority
= BBS_UNPRIORITIZED_ENTRY
;
171 if (IsHaveMediaInFloppy
== FLOPPY_PRESENT_NO_MEDIA
) {
172 BbsTable
[0].BootPriority
= BBS_LOWEST_PRIORITY
;
174 BbsTable
[0].BootPriority
= BBS_IGNORE_ENTRY
;
178 BbsTable
[0].Bus
= 0xff;
179 BbsTable
[0].Device
= 0xff;
180 BbsTable
[0].Function
= 0xff;
181 BbsTable
[0].DeviceType
= BBS_FLOPPY
;
182 BbsTable
[0].Class
= 01;
183 BbsTable
[0].SubClass
= 02;
184 BbsTable
[0].StatusFlags
.OldPosition
= 0;
185 BbsTable
[0].StatusFlags
.Reserved1
= 0;
186 BbsTable
[0].StatusFlags
.Enabled
= 0;
187 BbsTable
[0].StatusFlags
.Failed
= 0;
188 BbsTable
[0].StatusFlags
.MediaPresent
= 0;
189 BbsTable
[0].StatusFlags
.Reserved2
= 0;
192 // Onboard HDD - Note Each HDD controller controls 2 drives
195 HddInfo
= &Private
->IntThunk
->EfiToLegacy16BootTable
.HddInfo
[0];
197 // Get IDE Drive Info
199 LegacyBiosBuildIdeData (Private
, &HddInfo
, 0);
201 for (HddIndex
= 0; HddIndex
< MAX_IDE_CONTROLLER
; HddIndex
++) {
203 BbsIndex
= HddIndex
* 2 + 1;
204 for (Index
= 0; Index
< 2; ++Index
) {
206 BbsTable
[BbsIndex
+ Index
].Bus
= HddInfo
[HddIndex
].Bus
;
207 BbsTable
[BbsIndex
+ Index
].Device
= HddInfo
[HddIndex
].Device
;
208 BbsTable
[BbsIndex
+ Index
].Function
= HddInfo
[HddIndex
].Function
;
209 BbsTable
[BbsIndex
+ Index
].Class
= 01;
210 BbsTable
[BbsIndex
+ Index
].SubClass
= 01;
211 BbsTable
[BbsIndex
+ Index
].StatusFlags
.OldPosition
= 0;
212 BbsTable
[BbsIndex
+ Index
].StatusFlags
.Reserved1
= 0;
213 BbsTable
[BbsIndex
+ Index
].StatusFlags
.Enabled
= 0;
214 BbsTable
[BbsIndex
+ Index
].StatusFlags
.Failed
= 0;
215 BbsTable
[BbsIndex
+ Index
].StatusFlags
.MediaPresent
= 0;
216 BbsTable
[BbsIndex
+ Index
].StatusFlags
.Reserved2
= 0;
219 // If no controller found or no device found set to ignore
220 // else set to unprioritized and set device type
222 if (HddInfo
[HddIndex
].CommandBaseAddress
== 0) {
223 BbsTable
[BbsIndex
+ Index
].BootPriority
= BBS_IGNORE_ENTRY
;
226 if ((HddInfo
[HddIndex
].Status
& (HDD_MASTER_IDE
| HDD_MASTER_ATAPI_CDROM
| HDD_MASTER_ATAPI_ZIPDISK
)) != 0) {
227 BbsTable
[BbsIndex
+ Index
].BootPriority
= BBS_UNPRIORITIZED_ENTRY
;
228 if ((HddInfo
[HddIndex
].Status
& HDD_MASTER_IDE
) != 0) {
229 BbsTable
[BbsIndex
+ Index
].DeviceType
= BBS_HARDDISK
;
230 } else if ((HddInfo
[HddIndex
].Status
& HDD_MASTER_ATAPI_CDROM
) != 0) {
231 BbsTable
[BbsIndex
+ Index
].DeviceType
= BBS_CDROM
;
236 BbsTable
[BbsIndex
+ Index
].DeviceType
= BBS_HARDDISK
;
239 BbsTable
[BbsIndex
+ Index
].BootPriority
= BBS_IGNORE_ENTRY
;
242 if ((HddInfo
[HddIndex
].Status
& (HDD_SLAVE_IDE
| HDD_SLAVE_ATAPI_CDROM
| HDD_SLAVE_ATAPI_ZIPDISK
)) != 0) {
243 BbsTable
[BbsIndex
+ Index
].BootPriority
= BBS_UNPRIORITIZED_ENTRY
;
244 if ((HddInfo
[HddIndex
].Status
& HDD_SLAVE_IDE
) != 0) {
245 BbsTable
[BbsIndex
+ Index
].DeviceType
= BBS_HARDDISK
;
246 } else if ((HddInfo
[HddIndex
].Status
& HDD_SLAVE_ATAPI_CDROM
) != 0) {
247 BbsTable
[BbsIndex
+ Index
].DeviceType
= BBS_CDROM
;
252 BbsTable
[BbsIndex
+ Index
].DeviceType
= BBS_HARDDISK
;
255 BbsTable
[BbsIndex
+ Index
].BootPriority
= BBS_IGNORE_ENTRY
;
270 @param This Protocol instance pointer.
271 @param HddCount Number of HDD_INFO structures
272 @param HddInfo Onboard IDE controller information
273 @param BbsCount Number of BBS_TABLE structures
274 @param BbsTable List BBS entries
276 @retval EFI_SUCCESS Tables returned
277 @retval EFI_NOT_FOUND resource not found
278 @retval EFI_DEVICE_ERROR can not get BBS table
283 LegacyBiosGetBbsInfo (
284 IN EFI_LEGACY_BIOS_PROTOCOL
*This
,
285 OUT UINT16
*HddCount
,
286 OUT HDD_INFO
**HddInfo
,
287 OUT UINT16
*BbsCount
,
288 OUT BBS_TABLE
**BbsTable
291 LEGACY_BIOS_INSTANCE
*Private
;
292 EFI_IA32_REGISTER_SET Regs
;
293 EFI_TO_COMPATIBILITY16_BOOT_TABLE
*EfiToLegacy16BootTable
;
294 // HDD_INFO *LocalHddInfo;
295 // IN BBS_TABLE *LocalBbsTable;
297 EFI_HANDLE
*HandleBuffer
;
304 Private
= LEGACY_BIOS_INSTANCE_FROM_THIS (This
);
305 EfiToLegacy16BootTable
= &Private
->IntThunk
->EfiToLegacy16BootTable
;
306 // LocalHddInfo = EfiToLegacy16BootTable->HddInfo;
307 // LocalBbsTable = (BBS_TABLE*)(UINTN)EfiToLegacy16BootTable->BbsTable;
309 if (!mBbsTableDoneFlag
) {
310 mBbsTable
= Private
->BbsTablePtr
;
313 // Always enable disk controllers so 16-bit CSM code has valid information for all
317 // Get PciRootBridgeIO protocol
319 gBS
->LocateHandleBuffer (
321 &gEfiPciRootBridgeIoProtocolGuid
,
327 if (NumHandles
== 0) {
328 return EFI_NOT_FOUND
;
331 mBbsTableDoneFlag
= TRUE
;
332 for (Index
= 0; Index
< NumHandles
; Index
++) {
334 // Connect PciRootBridgeIO protocol handle with FALSE parameter to let
335 // PCI bus driver enumerate all subsequent handles
337 gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, FALSE
);
341 LegacyBiosBuildBbs (Private
, mBbsTable
);
343 Private
->LegacyRegion
->UnLock (Private
->LegacyRegion
, 0xe0000, 0x20000, &Granularity
);
346 // Call into Legacy16 code to add to BBS table for non BBS compliant OPROMs.
348 ZeroMem (&Regs
, sizeof (EFI_IA32_REGISTER_SET
));
349 Regs
.X
.AX
= Legacy16UpdateBbs
;
352 // Pass in handoff data
354 TempData
= (UINTN
) EfiToLegacy16BootTable
;
355 Regs
.X
.ES
= NORMALIZE_EFI_SEGMENT ((UINT32
) TempData
);
356 Regs
.X
.BX
= NORMALIZE_EFI_OFFSET ((UINT32
) TempData
);
358 Private
->LegacyBios
.FarCall86 (
360 Private
->Legacy16CallSegment
,
361 Private
->Legacy16CallOffset
,
367 Private
->Cpu
->FlushDataCache (Private
->Cpu
, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate
);
368 Private
->LegacyRegion
->Lock (Private
->LegacyRegion
, 0xe0000, 0x20000, &Granularity
);
370 if (Regs
.X
.AX
!= 0) {
371 return EFI_DEVICE_ERROR
;
375 if (HandleBuffer
!= NULL
) {
376 FreePool (HandleBuffer
);
379 *HddCount
= MAX_IDE_CONTROLLER
;
380 *HddInfo
= EfiToLegacy16BootTable
->HddInfo
;
381 *BbsTable
= (BBS_TABLE
*)(UINTN
)EfiToLegacy16BootTable
->BbsTable
;
382 *BbsCount
= (UINT16
) (sizeof (Private
->IntThunk
->BbsTable
) / sizeof (BBS_TABLE
));