IntelFrameworkModulePkg: Add Compatibility Support Module (CSM) drivers
Added these drivers: * LegacyBiosDxe * BlockIoDxe * KeyboardDxe * Snp16Dxe * VideoDxe Signed-off-by: jljusten Reviewed-by: mdkinney Reviewed-by: geekboy15a git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11905 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
300
IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyIde.c
Normal file
300
IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyIde.c
Normal file
@@ -0,0 +1,300 @@
|
||||
/** @file
|
||||
Collect IDE information from Native EFI Driver
|
||||
|
||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions
|
||||
of the BSD License which accompanies this distribution. The
|
||||
full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "LegacyBiosInterface.h"
|
||||
|
||||
BOOLEAN mIdeDataBuiltFlag = FALSE;
|
||||
|
||||
/**
|
||||
Collect IDE Inquiry data from the IDE disks
|
||||
|
||||
@param Private Legacy BIOS Instance data
|
||||
@param HddInfo Hdd Information
|
||||
@param Flag Reconnect IdeController or not
|
||||
|
||||
@retval EFI_SUCCESS It should always work.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
LegacyBiosBuildIdeData (
|
||||
IN LEGACY_BIOS_INSTANCE *Private,
|
||||
IN HDD_INFO **HddInfo,
|
||||
IN UINT16 Flag
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE IdeController;
|
||||
UINTN HandleCount;
|
||||
EFI_HANDLE *HandleBuffer;
|
||||
UINTN Index;
|
||||
EFI_DISK_INFO_PROTOCOL *DiskInfo;
|
||||
UINT32 IdeChannel;
|
||||
UINT32 IdeDevice;
|
||||
UINT32 Size;
|
||||
UINT8 *InquiryData;
|
||||
UINT32 InquiryDataSize;
|
||||
HDD_INFO *LocalHddInfo;
|
||||
UINT32 PciIndex;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
|
||||
EFI_DEVICE_PATH_PROTOCOL *TempDevicePathNode;
|
||||
PCI_DEVICE_PATH *PciDevicePath;
|
||||
|
||||
//
|
||||
// Only build data once
|
||||
// We have a problem with GetBbsInfo in that it can be invoked two
|
||||
// places. Once in BDS, when all EFI drivers are connected and once in
|
||||
// LegacyBoot after all EFI drivers are disconnected causing this routine
|
||||
// to hang. In LegacyBoot this function is also called before EFI drivers
|
||||
// are disconnected.
|
||||
// Cases covered
|
||||
// GetBbsInfo invoked in BDS. Both invocations in LegacyBoot ignored.
|
||||
// GetBbsInfo not invoked in BDS. First invocation of this function
|
||||
// proceeds normally and second via GetBbsInfo ignored.
|
||||
//
|
||||
PciDevicePath = NULL;
|
||||
LocalHddInfo = *HddInfo;
|
||||
Status = Private->LegacyBiosPlatform->GetPlatformHandle (
|
||||
Private->LegacyBiosPlatform,
|
||||
EfiGetPlatformIdeHandle,
|
||||
0,
|
||||
&HandleBuffer,
|
||||
&HandleCount,
|
||||
(VOID *) &LocalHddInfo
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
IdeController = HandleBuffer[0];
|
||||
//
|
||||
// Force IDE drive spin up!
|
||||
//
|
||||
if (Flag != 0) {
|
||||
gBS->DisconnectController (
|
||||
IdeController,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
gBS->ConnectController (IdeController, NULL, NULL, FALSE);
|
||||
|
||||
//
|
||||
// Do GetIdeHandle twice since disconnect/reconnect will switch to native mode
|
||||
// And GetIdeHandle will switch to Legacy mode, if required.
|
||||
//
|
||||
Private->LegacyBiosPlatform->GetPlatformHandle (
|
||||
Private->LegacyBiosPlatform,
|
||||
EfiGetPlatformIdeHandle,
|
||||
0,
|
||||
&HandleBuffer,
|
||||
&HandleCount,
|
||||
(VOID *) &LocalHddInfo
|
||||
);
|
||||
}
|
||||
|
||||
mIdeDataBuiltFlag = TRUE;
|
||||
|
||||
//
|
||||
// Get Identity command from all drives
|
||||
//
|
||||
gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiDiskInfoProtocolGuid,
|
||||
NULL,
|
||||
&HandleCount,
|
||||
&HandleBuffer
|
||||
);
|
||||
|
||||
Private->IdeDriveCount = (UINT8) HandleCount;
|
||||
for (Index = 0; Index < HandleCount; Index++) {
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiDiskInfoProtocolGuid,
|
||||
(VOID **) &DiskInfo
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
if (CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoIdeInterfaceGuid)) {
|
||||
//
|
||||
// Locate which PCI device
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
(VOID *) &DevicePath
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
DevicePathNode = DevicePath;
|
||||
while (!IsDevicePathEnd (DevicePathNode)) {
|
||||
TempDevicePathNode = NextDevicePathNode (DevicePathNode);
|
||||
if ((DevicePathType (DevicePathNode) == HARDWARE_DEVICE_PATH) &&
|
||||
( DevicePathSubType (DevicePathNode) == HW_PCI_DP) &&
|
||||
( DevicePathType(TempDevicePathNode) == MESSAGING_DEVICE_PATH) &&
|
||||
( DevicePathSubType(TempDevicePathNode) == MSG_ATAPI_DP) ) {
|
||||
PciDevicePath = (PCI_DEVICE_PATH *) DevicePathNode;
|
||||
break;
|
||||
}
|
||||
DevicePathNode = NextDevicePathNode (DevicePathNode);
|
||||
}
|
||||
|
||||
if (PciDevicePath == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Find start of PCI device in HddInfo. The assumption of the data
|
||||
// structure is 2 controllers(channels) per PCI device and each
|
||||
// controller can have 2 drives(devices).
|
||||
// HddInfo[PciIndex+0].[0] = Channel[0].Device[0] Primary Master
|
||||
// HddInfo[PciIndex+0].[1] = Channel[0].Device[1] Primary Slave
|
||||
// HddInfo[PciIndex+1].[0] = Channel[1].Device[0] Secondary Master
|
||||
// HddInfo[PciIndex+1].[1] = Channel[1].Device[1] Secondary Slave
|
||||
// @bug eventually need to pass in max number of entries
|
||||
// for end of for loop
|
||||
//
|
||||
for (PciIndex = 0; PciIndex < 8; PciIndex++) {
|
||||
if ((PciDevicePath->Device == LocalHddInfo[PciIndex].Device) &&
|
||||
(PciDevicePath->Function == LocalHddInfo[PciIndex].Function)
|
||||
) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (PciIndex == 8) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = DiskInfo->WhichIde (DiskInfo, &IdeChannel, &IdeDevice);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Size = sizeof (ATAPI_IDENTIFY);
|
||||
DiskInfo->Identify (
|
||||
DiskInfo,
|
||||
&LocalHddInfo[PciIndex + IdeChannel].IdentifyDrive[IdeDevice],
|
||||
&Size
|
||||
);
|
||||
if (IdeChannel == 0) {
|
||||
LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_PRIMARY;
|
||||
} else if (IdeChannel == 1) {
|
||||
LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SECONDARY;
|
||||
}
|
||||
|
||||
InquiryData = NULL;
|
||||
InquiryDataSize = 0;
|
||||
Status = DiskInfo->Inquiry (
|
||||
DiskInfo,
|
||||
NULL,
|
||||
&InquiryDataSize
|
||||
);
|
||||
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||
InquiryData = (UINT8 *) AllocatePool (
|
||||
InquiryDataSize
|
||||
);
|
||||
if (InquiryData != NULL) {
|
||||
Status = DiskInfo->Inquiry (
|
||||
DiskInfo,
|
||||
InquiryData,
|
||||
&InquiryDataSize
|
||||
);
|
||||
}
|
||||
} else {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// If ATAPI device then Inquiry will pass and ATA fail.
|
||||
//
|
||||
if (!EFI_ERROR (Status)) {
|
||||
ASSERT (InquiryData != NULL);
|
||||
//
|
||||
// If IdeDevice = 0 then set master bit, else slave bit
|
||||
//
|
||||
if (IdeDevice == 0) {
|
||||
if ((InquiryData[0] & 0x1f) == 0x05) {
|
||||
LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_MASTER_ATAPI_CDROM;
|
||||
} else if ((InquiryData[0] & 0x1f) == 0x00) {
|
||||
LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_MASTER_ATAPI_ZIPDISK;
|
||||
}
|
||||
} else {
|
||||
if ((InquiryData[0] & 0x1f) == 0x05) {
|
||||
LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SLAVE_ATAPI_CDROM;
|
||||
} else if ((InquiryData[0] & 0x1f) == 0x00) {
|
||||
LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SLAVE_ATAPI_ZIPDISK;
|
||||
}
|
||||
}
|
||||
FreePool (InquiryData);
|
||||
} else {
|
||||
if (IdeDevice == 0) {
|
||||
LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_MASTER_IDE;
|
||||
} else {
|
||||
LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SLAVE_IDE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (HandleBuffer != NULL) {
|
||||
FreePool (HandleBuffer);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
If the IDE channel is in compatibility (legacy) mode, remove all
|
||||
PCI I/O BAR addresses from the controller.
|
||||
|
||||
@param IdeController The handle of target IDE controller
|
||||
|
||||
|
||||
**/
|
||||
VOID
|
||||
InitLegacyIdeController (
|
||||
IN EFI_HANDLE IdeController
|
||||
)
|
||||
{
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
UINT8 Pi;
|
||||
UINT32 IOBarClear;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// If the IDE channel is in compatibility (legacy) mode, remove all
|
||||
// PCI I/O BAR addresses from the controller. Some software gets
|
||||
// confused if an IDE controller is in compatibility (legacy) mode
|
||||
// and has PCI I/O resources allocated
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
IdeController,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
(VOID **) &PciIo
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
IOBarClear = 0x00;
|
||||
PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 1, &Pi);
|
||||
if ((Pi & 0x01) == 0) {
|
||||
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x10, 1, &IOBarClear);
|
||||
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x14, 1, &IOBarClear);
|
||||
}
|
||||
if ((Pi & 0x04) == 0) {
|
||||
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x18, 1, &IOBarClear);
|
||||
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x1C, 1, &IOBarClear);
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
Reference in New Issue
Block a user