3 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "LegacyBiosInterface.h"
10 #include <IndustryStandard/Pci.h>
12 // Give floppy 3 states
13 // FLOPPY_PRESENT_WITH_MEDIA = Floppy controller present and media is inserted
14 // FLOPPY_NOT_PRESENT = No floppy controller present
15 // FLOPPY_PRESENT_NO_MEDIA = Floppy controller present but no media inserted
17 #define FLOPPY_NOT_PRESENT 0
18 #define FLOPPY_PRESENT_WITH_MEDIA 1
19 #define FLOPPY_PRESENT_NO_MEDIA 2
22 BOOLEAN mBbsTableDoneFlag
= FALSE
;
23 BOOLEAN IsHaveMediaInFloppy
= TRUE
;
26 Checks the state of the floppy and if media is inserted.
28 This routine checks the state of the floppy and if media is inserted.
30 No floppy present - Set BBS entry to ignore
31 Floppy present & no media - Set BBS entry to lowest priority. We cannot
32 set it to ignore since 16-bit CSM will
33 indicate no floppy and thus drive A: is
34 unusable. CSM-16 will not try floppy since
35 lowest priority and thus not incur boot
37 Floppy present & media - Set BBS entry to some priority.
39 @return State of floppy media
49 EFI_HANDLE
*HandleBuffer
;
51 EFI_ISA_IO_PROTOCOL
*IsaIo
;
52 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
57 gBS
->LocateHandleBuffer (
59 &gEfiIsaIoProtocolGuid
,
66 // If don't find any ISA/IO protocol assume no floppy. Need for floppy
69 if (HandleCount
== 0) {
70 return FLOPPY_NOT_PRESENT
;
73 ASSERT (HandleBuffer
!= NULL
);
75 for (Index
= 0; Index
< HandleCount
; Index
++) {
76 Status
= gBS
->HandleProtocol (
78 &gEfiIsaIoProtocolGuid
,
81 if (EFI_ERROR (Status
)) {
85 if (IsaIo
->ResourceList
->Device
.HID
!= EISA_PNP_ID (0x604)) {
89 // Update blockio in case the floppy is inserted in during BdsTimeout
91 Status
= gBS
->DisconnectController (HandleBuffer
[Index
], NULL
, NULL
);
93 if (EFI_ERROR (Status
)) {
97 Status
= gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
99 if (EFI_ERROR (Status
)) {
103 Status
= gBS
->HandleProtocol (
105 &gEfiBlockIoProtocolGuid
,
108 if (EFI_ERROR (Status
)) {
112 if (BlkIo
->Media
->MediaPresent
) {
113 FreePool (HandleBuffer
);
114 return FLOPPY_PRESENT_WITH_MEDIA
;
116 FreePool (HandleBuffer
);
117 return FLOPPY_PRESENT_NO_MEDIA
;
121 FreePool (HandleBuffer
);
123 return FLOPPY_NOT_PRESENT
;
129 Complete build of BBS TABLE.
131 @param Private Legacy BIOS Instance data
132 @param BbsTable BBS Table passed to 16-bit code
134 @retval EFI_SUCCESS Removable media not present
139 IN LEGACY_BIOS_INSTANCE
*Private
,
140 IN BBS_TABLE
*BbsTable
149 // First entry is floppy.
150 // Next 2*MAX_IDE_CONTROLLER entries are for onboard IDE.
151 // Next n entries are filled in after each ROM is dispatched.
152 // Entry filled in if follow BBS spec. See LegacyPci.c
153 // Next entries are for non-BBS compliant ROMS. They are filled in by
154 // 16-bit code during Legacy16UpdateBbs invocation. Final BootPriority
155 // occurs after that invocation.
158 // Set default state.
160 IsHaveMediaInFloppy
= HasMediaInFloppy ();
161 if (IsHaveMediaInFloppy
== FLOPPY_PRESENT_WITH_MEDIA
) {
162 BbsTable
[0].BootPriority
= BBS_UNPRIORITIZED_ENTRY
;
164 if (IsHaveMediaInFloppy
== FLOPPY_PRESENT_NO_MEDIA
) {
165 BbsTable
[0].BootPriority
= BBS_LOWEST_PRIORITY
;
167 BbsTable
[0].BootPriority
= BBS_IGNORE_ENTRY
;
171 BbsTable
[0].Bus
= 0xff;
172 BbsTable
[0].Device
= 0xff;
173 BbsTable
[0].Function
= 0xff;
174 BbsTable
[0].DeviceType
= BBS_FLOPPY
;
175 BbsTable
[0].Class
= 01;
176 BbsTable
[0].SubClass
= 02;
177 BbsTable
[0].StatusFlags
.OldPosition
= 0;
178 BbsTable
[0].StatusFlags
.Reserved1
= 0;
179 BbsTable
[0].StatusFlags
.Enabled
= 0;
180 BbsTable
[0].StatusFlags
.Failed
= 0;
181 BbsTable
[0].StatusFlags
.MediaPresent
= 0;
182 BbsTable
[0].StatusFlags
.Reserved2
= 0;
185 // Onboard HDD - Note Each HDD controller controls 2 drives
188 HddInfo
= &Private
->IntThunk
->EfiToLegacy16BootTable
.HddInfo
[0];
190 // Get IDE Drive Info
192 LegacyBiosBuildIdeData (Private
, &HddInfo
, 0);
194 for (HddIndex
= 0; HddIndex
< MAX_IDE_CONTROLLER
; HddIndex
++) {
196 BbsIndex
= HddIndex
* 2 + 1;
197 for (Index
= 0; Index
< 2; ++Index
) {
199 BbsTable
[BbsIndex
+ Index
].Bus
= HddInfo
[HddIndex
].Bus
;
200 BbsTable
[BbsIndex
+ Index
].Device
= HddInfo
[HddIndex
].Device
;
201 BbsTable
[BbsIndex
+ Index
].Function
= HddInfo
[HddIndex
].Function
;
202 BbsTable
[BbsIndex
+ Index
].Class
= 01;
203 BbsTable
[BbsIndex
+ Index
].SubClass
= 01;
204 BbsTable
[BbsIndex
+ Index
].StatusFlags
.OldPosition
= 0;
205 BbsTable
[BbsIndex
+ Index
].StatusFlags
.Reserved1
= 0;
206 BbsTable
[BbsIndex
+ Index
].StatusFlags
.Enabled
= 0;
207 BbsTable
[BbsIndex
+ Index
].StatusFlags
.Failed
= 0;
208 BbsTable
[BbsIndex
+ Index
].StatusFlags
.MediaPresent
= 0;
209 BbsTable
[BbsIndex
+ Index
].StatusFlags
.Reserved2
= 0;
212 // If no controller found or no device found set to ignore
213 // else set to unprioritized and set device type
215 if (HddInfo
[HddIndex
].CommandBaseAddress
== 0) {
216 BbsTable
[BbsIndex
+ Index
].BootPriority
= BBS_IGNORE_ENTRY
;
219 if ((HddInfo
[HddIndex
].Status
& (HDD_MASTER_IDE
| HDD_MASTER_ATAPI_CDROM
| HDD_MASTER_ATAPI_ZIPDISK
)) != 0) {
220 BbsTable
[BbsIndex
+ Index
].BootPriority
= BBS_UNPRIORITIZED_ENTRY
;
221 if ((HddInfo
[HddIndex
].Status
& HDD_MASTER_IDE
) != 0) {
222 BbsTable
[BbsIndex
+ Index
].DeviceType
= BBS_HARDDISK
;
223 } else if ((HddInfo
[HddIndex
].Status
& HDD_MASTER_ATAPI_CDROM
) != 0) {
224 BbsTable
[BbsIndex
+ Index
].DeviceType
= BBS_CDROM
;
229 BbsTable
[BbsIndex
+ Index
].DeviceType
= BBS_HARDDISK
;
232 BbsTable
[BbsIndex
+ Index
].BootPriority
= BBS_IGNORE_ENTRY
;
235 if ((HddInfo
[HddIndex
].Status
& (HDD_SLAVE_IDE
| HDD_SLAVE_ATAPI_CDROM
| HDD_SLAVE_ATAPI_ZIPDISK
)) != 0) {
236 BbsTable
[BbsIndex
+ Index
].BootPriority
= BBS_UNPRIORITIZED_ENTRY
;
237 if ((HddInfo
[HddIndex
].Status
& HDD_SLAVE_IDE
) != 0) {
238 BbsTable
[BbsIndex
+ Index
].DeviceType
= BBS_HARDDISK
;
239 } else if ((HddInfo
[HddIndex
].Status
& HDD_SLAVE_ATAPI_CDROM
) != 0) {
240 BbsTable
[BbsIndex
+ Index
].DeviceType
= BBS_CDROM
;
245 BbsTable
[BbsIndex
+ Index
].DeviceType
= BBS_HARDDISK
;
248 BbsTable
[BbsIndex
+ Index
].BootPriority
= BBS_IGNORE_ENTRY
;
263 @param This Protocol instance pointer.
264 @param HddCount Number of HDD_INFO structures
265 @param HddInfo Onboard IDE controller information
266 @param BbsCount Number of BBS_TABLE structures
267 @param BbsTable List BBS entries
269 @retval EFI_SUCCESS Tables returned
270 @retval EFI_NOT_FOUND resource not found
271 @retval EFI_DEVICE_ERROR can not get BBS table
276 LegacyBiosGetBbsInfo (
277 IN EFI_LEGACY_BIOS_PROTOCOL
*This
,
278 OUT UINT16
*HddCount
,
279 OUT HDD_INFO
**HddInfo
,
280 OUT UINT16
*BbsCount
,
281 OUT BBS_TABLE
**BbsTable
284 LEGACY_BIOS_INSTANCE
*Private
;
285 EFI_IA32_REGISTER_SET Regs
;
286 EFI_TO_COMPATIBILITY16_BOOT_TABLE
*EfiToLegacy16BootTable
;
287 // HDD_INFO *LocalHddInfo;
288 // IN BBS_TABLE *LocalBbsTable;
290 EFI_HANDLE
*HandleBuffer
;
297 Private
= LEGACY_BIOS_INSTANCE_FROM_THIS (This
);
298 EfiToLegacy16BootTable
= &Private
->IntThunk
->EfiToLegacy16BootTable
;
299 // LocalHddInfo = EfiToLegacy16BootTable->HddInfo;
300 // LocalBbsTable = (BBS_TABLE*)(UINTN)EfiToLegacy16BootTable->BbsTable;
302 if (!mBbsTableDoneFlag
) {
303 mBbsTable
= Private
->BbsTablePtr
;
306 // Always enable disk controllers so 16-bit CSM code has valid information for all
310 // Get PciRootBridgeIO protocol
312 gBS
->LocateHandleBuffer (
314 &gEfiPciRootBridgeIoProtocolGuid
,
320 if (NumHandles
== 0) {
321 return EFI_NOT_FOUND
;
324 mBbsTableDoneFlag
= TRUE
;
325 for (Index
= 0; Index
< NumHandles
; Index
++) {
327 // Connect PciRootBridgeIO protocol handle with FALSE parameter to let
328 // PCI bus driver enumerate all subsequent handles
330 gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, FALSE
);
334 LegacyBiosBuildBbs (Private
, mBbsTable
);
336 Private
->LegacyRegion
->UnLock (Private
->LegacyRegion
, 0xe0000, 0x20000, &Granularity
);
339 // Call into Legacy16 code to add to BBS table for non BBS compliant OPROMs.
341 ZeroMem (&Regs
, sizeof (EFI_IA32_REGISTER_SET
));
342 Regs
.X
.AX
= Legacy16UpdateBbs
;
345 // Pass in handoff data
347 TempData
= (UINTN
) EfiToLegacy16BootTable
;
348 Regs
.X
.ES
= NORMALIZE_EFI_SEGMENT ((UINT32
) TempData
);
349 Regs
.X
.BX
= NORMALIZE_EFI_OFFSET ((UINT32
) TempData
);
351 Private
->LegacyBios
.FarCall86 (
353 Private
->Legacy16CallSegment
,
354 Private
->Legacy16CallOffset
,
360 Private
->Cpu
->FlushDataCache (Private
->Cpu
, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate
);
361 Private
->LegacyRegion
->Lock (Private
->LegacyRegion
, 0xe0000, 0x20000, &Granularity
);
363 if (Regs
.X
.AX
!= 0) {
364 return EFI_DEVICE_ERROR
;
368 if (HandleBuffer
!= NULL
) {
369 FreePool (HandleBuffer
);
372 *HddCount
= MAX_IDE_CONTROLLER
;
373 *HddInfo
= EfiToLegacy16BootTable
->HddInfo
;
374 *BbsTable
= (BBS_TABLE
*)(UINTN
)EfiToLegacy16BootTable
->BbsTable
;
375 *BbsCount
= (UINT16
) (sizeof (Private
->IntThunk
->BbsTable
) / sizeof (BBS_TABLE
));