isabus.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 707 行 · 第 1/2 页

C
707
字号
/*++

Copyright (c) 2006, Intel Corporation                                                         
All rights reserved. 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.


Module Name:

  IsaBus.c
  
Abstract:

  Discovers all the ISA Controllers and their resources by using the ISA PnP 
  Protocol, produces an instance of the ISA I/O Protocol for every ISA 
  Controller found, loads and initializes all ISA Device Drivers, matches ISA
  Device Drivers with their respective ISA Controllers in a deterministic 
  manner, and informs a ISA Device Driver when it is to start managing an ISA
  Controller. 

Revision History:

--*/

#include "IsaBus.h"
#include EFI_PROTOCOL_DEFINITION (GenericMemoryTest)

//
// ISA Bus Driver Global Variables
//
EFI_DRIVER_BINDING_PROTOCOL gIsaBusControllerDriver = {
  IsaBusControllerDriverSupported,
  IsaBusControllerDriverStart,
  IsaBusControllerDriverStop,
  0x10,
  NULL,
  NULL
};

//
// ISA Bus Driver Entry Point
//
EFI_DRIVER_ENTRY_POINT (IsaBusControllerDriverEntryPoint)

EFI_STATUS
EFIAPI
IsaBusControllerDriverEntryPoint (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
/*++

  Routine Description:
  
    The entry point for an ISA Bus Driver simply allocates space for an  
    EFI_DRIVER_BINDING_PROTOCOL protocol instance, initializes its contents, 
    and attaches this protocol instance to the image handle of the ISA Bus
    Driver. It also attaches the bus identifier protocol to the same handle.  
    For an ISA Bus Driver for a PCI to ISA Bridge controller, 
    this would be the EFI_PCI_BUS_IDENTIFIER_PROTOCOL.  
  
  Arguments:
  
    ImageHandle             - EFI_HANDLE: The firmware allocated handle for 
                              the EFI Driver(PCI/ISA Bridge) image.
    SystemTable             - EFI_SYSTEM_TABLE: A pointer to the EFI system table        

  Returns:
  
    EFI_SUCCESS:            - The ISA bus driver was initialized.
    EFI_ALREADY_STARTED:    - The driver has already been initialized.
    EFI_INVALID_PARAMETER:  - One of the parameters has an invalid value.
    EFI_OUT_OF_RESOURCES:   - The request could not be completed due to 
                              a lack of resources.
 
--*/
{
  return INSTALL_ALL_DRIVER_PROTOCOLS (
           ImageHandle,
           SystemTable,
           &gIsaBusControllerDriver,
           ImageHandle,
           &gIsaBusComponentName,
           NULL,
           NULL
           );
}

EFI_STATUS
EFIAPI
IsaBusControllerDriverSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  * This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     * RemainingDevicePath OPTIONAL
  )
/*++

  Routine Description:
  
    This function checks to see if a controller can be managed by the ISA Bus 
    Driver. This is done by checking to see if the controller supports the 
    EFI_PCI_IO_PROTOCOL protocol, and then looking at the PCI Configuration 
    Header to see if the device is a PCI to ISA bridge. The class code of 
    PCI to ISA bridge: Base class 06h, Sub class 01h Interface 00h 
  
  Arguments:
  
    This                 - The EFI_DRIVER_BINDING_PROTOCOL instance.
    Controller           - The handle of the device to check.
    RemainingDevicePath  - A pointer to the remaining portion of a device path.

  Returns:
  
    EFI_SUCCESS          - The device is supported by this driver.
    EFI_UNSUPPORTED      - The device is not supported by this driver.

--*/
{
  EFI_STATUS            Status;
  EFI_ISA_ACPI_PROTOCOL *IsaAcpi;

  //
  // If RemainingDevicePath is not NULL, it should verify that the first device
  // path node in RemainingDevicePath is an ACPI Device path node
  //
  if (RemainingDevicePath != NULL) {
    if (RemainingDevicePath->Type != ACPI_DEVICE_PATH) {
      return EFI_UNSUPPORTED;
    } else if (RemainingDevicePath->SubType == ACPI_DP) {
      if (DevicePathNodeLength (RemainingDevicePath) != sizeof (ACPI_HID_DEVICE_PATH)) {
        return EFI_UNSUPPORTED;
      }
    } else if (RemainingDevicePath->SubType == ACPI_EXTENDED_DP) {
      if (DevicePathNodeLength (RemainingDevicePath) != sizeof (ACPI_EXTENDED_HID_DEVICE_PATH)) {
        return EFI_UNSUPPORTED;
      }
    } else {
      return EFI_UNSUPPORTED;
    }
  }
  //
  // Test the existence of DEVICE_PATH protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  NULL,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Get the Isa Acpi protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiIsaAcpiProtocolGuid,
                  (VOID **) &IsaAcpi,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  gBS->CloseProtocol (
         Controller,
         &gEfiIsaAcpiProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  return Status;
}

EFI_STATUS
EFIAPI
IsaBusControllerDriverStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  * This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     * RemainingDevicePath OPTIONAL
  )
/*++

  Routine Description:
  
    This function tells the ISA Bus Driver to start managing a PCI to ISA 
    Bridge controller. 
  
  Arguments:
  
    This                  - The EFI_DRIVER_BINDING_PROTOCOL instance.
    Controller            - A handle to the device being started. 
    RemainingDevicePath   - A pointer to the remaining portion of a device path.

  Returns:
  
    EFI_SUCCESS           - The device was started.
    EFI_UNSUPPORTED       - The device is not supported.
    EFI_DEVICE_ERROR      - The device could not be started due to a device error.
    EFI_ALREADY_STARTED   - The device has already been started.
    EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
    EFI_OUT_OF_RESOURCES  - The request could not be completed due to a lack of 
                            resources.
  
--*/
{
  EFI_STATUS                            Status;
  EFI_PCI_IO_PROTOCOL                   *PciIo;
  EFI_DEVICE_PATH_PROTOCOL              *ParentDevicePath;
  EFI_ISA_ACPI_PROTOCOL                 *IsaAcpi;
  EFI_ISA_ACPI_DEVICE_ID                *IsaDevice;
  EFI_ISA_ACPI_RESOURCE_LIST            *ResourceList;
  EFI_GENERIC_MEMORY_TEST_PROTOCOL      *GenMemoryTest;

  //
  // Local variables declaration for StatusCode reporting
  //
  EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA AllocFailExtendedData;

  //
  // Initialize status code structure
  //
  AllocFailExtendedData.DataHeader.HeaderSize = sizeof (EFI_STATUS_CODE_DATA);
  AllocFailExtendedData.DataHeader.Size = sizeof (EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA) - sizeof (EFI_STATUS_CODE_DATA);
  EfiCommonLibCopyMem (
    &AllocFailExtendedData.DataHeader.Type,
    &gEfiStatusCodeSpecificDataGuid,
    sizeof (EFI_GUID)
    );

  //
  // Open Device Path Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    return Status;
  }
  //
  // Open Pci IO Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID **) &PciIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    //
    // Close opened protocol
    //
    gBS->CloseProtocol (
           Controller,
           &gEfiDevicePathProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
    return Status;
  }
  //
  // Open ISA Acpi Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiIsaAcpiProtocolGuid,
                  (VOID **) &IsaAcpi,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    //
    // Close opened protocol
    //
    gBS->CloseProtocol (
           Controller,
           &gEfiDevicePathProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
    gBS->CloseProtocol (
           Controller,
           &gEfiPciIoProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
    return Status;
  }
  //
  // The IsaBus driver will use memory below 16M, which is not tested yet,
  // so call CompatibleRangeTest to test them. Since memory below 1M should
  // be reserved to CSM, and 15M~16M might be reserved for Isa hole, test 1M
  // ~15M here
  //
  Status = gBS->LocateProtocol (
                  &gEfiGenericMemTestProtocolGuid,
                  NULL,
                  &GenMemoryTest
                  );

  if (!EFI_ERROR (Status)) {
    Status = GenMemoryTest->CompatibleRangeTest (
                              GenMemoryTest,
                              0x100000,
                              0xE00000
                              );
  }
  //
  // Report Status Code here since we will initialize the host controller
  //
  ReportStatusCodeWithDevicePath (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_LPC | EFI_IOB_PC_INIT),
    0,
    &gEfiCallerIdGuid,
    ParentDevicePath
    );

  //
  // first init ISA interface
  //
  IsaAcpi->InterfaceInit (IsaAcpi);

  //
  // Report Status Code here since we will enable the host controller
  //
  ReportStatusCodeWithDevicePath (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_LPC | EFI_IOB_PC_ENABLE),
    0,
    &gEfiCallerIdGuid,
    ParentDevicePath

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?