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
		
			
				
	
	
		
			301 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			301 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @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 ;
 | |
| }
 |