Home | History | Annotate | Download | only in PciHostBridgeDxe
      1 /** @file
      2 *  Pci Host Bridge support for the Xpress-RICH3 PCIe Root Complex
      3 *
      4 *  Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
      5 *
      6 *  This program and the accompanying materials
      7 *  are licensed and made available under the terms and conditions of the BSD License
      8 *  which accompanies this distribution.  The full text of the license may be found at
      9 *  http://opensource.org/licenses/bsd-license.php
     10 *
     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.
     13 *
     14 **/
     15 
     16 #include "PciHostBridge.h"
     17 
     18 #include <Guid/EventGroup.h>
     19 
     20 /**
     21  * PCI Root Bridge Description
     22  */
     23 typedef struct {
     24   UINT32  AcpiUid;
     25   UINT64  MemAllocAttributes;
     26 } PCI_ROOT_BRIDGE_DESC;
     27 
     28 PCI_ROOT_BRIDGE_DESC PciRbDescriptions = {
     29     0,                                  // AcpiUid
     30     PCI_MEMORY_ALLOCATION_ATTRIBUTES    // MemAllocAttributes
     31 };
     32 
     33 /**
     34  * Template for PCI Host Bridge Instance
     35  **/
     36 STATIC CONST PCI_HOST_BRIDGE_INSTANCE
     37 gPciHostBridgeInstanceTemplate = {
     38   PCI_HOST_BRIDGE_SIGNATURE,      //Signature
     39   NULL,                           // Handle
     40   NULL,                           // ImageHandle
     41   NULL,                           // RootBridge
     42   TRUE,                           // CanRestarted
     43   NULL,                           // CpuIo
     44   NULL,                           // Metronome
     45   {                               // ResAlloc
     46     PciHbRaNotifyPhase,           //   ResAlloc.NotifyPhase
     47     PciHbRaGetNextRootBridge,     //   ResAlloc.GetNextRootBridge
     48     PciHbRaGetAllocAttributes,    //   ResAlloc.GetAllocAttributes
     49     PciHbRaStartBusEnumeration,   //   ResAlloc.StartBusEnumeration
     50     PciHbRaSetBusNumbers,         //   ResAlloc.SetBusNumbers
     51     PciHbRaSubmitResources,       //   ResAlloc.SubmitResources
     52     PciHbRaGetProposedResources,  //   ResAlloc.GetProposedResources
     53     PciHbRaPreprocessController   //   ResAlloc.PreprocessController
     54   }
     55 };
     56 PCI_HOST_BRIDGE_INSTANCE* gpPciHostBridgeInstance;
     57 
     58 EFI_STATUS
     59 HostBridgeConstructor (
     60   IN OUT PCI_HOST_BRIDGE_INSTANCE** Instance,
     61   IN  EFI_HANDLE                    ImageHandle
     62   )
     63 {
     64   EFI_STATUS                  Status;
     65   PCI_HOST_BRIDGE_INSTANCE*   HostBridge;
     66 
     67   PCI_TRACE ("HostBridgeConstructor()");
     68 
     69   if (Instance == NULL) {
     70     return EFI_INVALID_PARAMETER;
     71   }
     72 
     73   HostBridge = AllocateCopyPool (sizeof (PCI_HOST_BRIDGE_INSTANCE), &gPciHostBridgeInstanceTemplate);
     74   if (HostBridge == NULL) {
     75     PCI_TRACE ("HostBridgeConstructor(): FAIL to allocate resources");
     76     return EFI_OUT_OF_RESOURCES;
     77   }
     78 
     79   // It will also create a device handle for the PCI Host Bridge (as HostBridge->Handle == NULL)
     80   Status = gBS->InstallMultipleProtocolInterfaces (
     81                     &HostBridge->Handle,
     82                     &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,
     83                     NULL
     84                     );
     85   if (EFI_ERROR (Status)) {
     86     PCI_TRACE ("HostBridgeConstructor(): FAIL to install resource allocator");
     87     FreePool (HostBridge);
     88     return EFI_DEVICE_ERROR;
     89   } else {
     90     PCI_TRACE ("HostBridgeConstructor(): SUCCEED to install resource allocator");
     91   }
     92 
     93   Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **)(&(HostBridge->CpuIo)));
     94   ASSERT_EFI_ERROR (Status);
     95 
     96   Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **)(&(HostBridge->Metronome)));
     97   ASSERT_EFI_ERROR (Status);
     98 
     99   HostBridge->ImageHandle = ImageHandle;
    100 
    101   *Instance = HostBridge;
    102   return EFI_SUCCESS;
    103 }
    104 
    105 EFI_STATUS
    106 HostBridgeDestructor (
    107   IN PCI_HOST_BRIDGE_INSTANCE* HostBridge
    108   )
    109 {
    110   EFI_STATUS Status;
    111 
    112   Status = gBS->UninstallMultipleProtocolInterfaces (
    113                       HostBridge->Handle,
    114                       &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,
    115                       NULL
    116                       );
    117 
    118   if (HostBridge->RootBridge) {
    119     PciRbDestructor (HostBridge->RootBridge);
    120   }
    121 
    122   FreePool (HostBridge);
    123 
    124   return Status;
    125 }
    126 
    127 /**
    128   Entry point of this driver
    129 
    130   @param ImageHandle     Handle of driver image
    131   @param SystemTable     Point to EFI_SYSTEM_TABLE
    132 
    133   @retval EFI_OUT_OF_RESOURCES  Can not allocate memory resource
    134   @retval EFI_DEVICE_ERROR      Can not install the protocol instance
    135   @retval EFI_SUCCESS           Success to initialize the Pci host bridge.
    136 **/
    137 EFI_STATUS
    138 EFIAPI
    139 PciHostBridgeEntryPoint (
    140   IN EFI_HANDLE        ImageHandle,
    141   IN EFI_SYSTEM_TABLE  *SystemTable
    142   )
    143 {
    144   EFI_STATUS                  Status;
    145 
    146   PCI_TRACE ("PciHostBridgeEntryPoint()");
    147 
    148   // Creation of the PCI Host Bridge Instance
    149   Status = HostBridgeConstructor (&gpPciHostBridgeInstance, ImageHandle);
    150   if (EFI_ERROR (Status)) {
    151     PCI_TRACE ("PciHostBridgeEntryPoint(): ERROR: Fail to construct PCI Host Bridge.");
    152     return Status;
    153   }
    154 
    155   // Creation of the PCIe Root Bridge
    156   Status = PciRbConstructor (gpPciHostBridgeInstance, PciRbDescriptions.AcpiUid, PciRbDescriptions.MemAllocAttributes);
    157   if (EFI_ERROR (Status)) {
    158     PCI_TRACE ("PciHostBridgeEntryPoint(): ERROR: Fail to construct PCI Root Bridge.");
    159     return Status;
    160   }
    161   ASSERT (gpPciHostBridgeInstance->RootBridge->Signature == PCI_ROOT_BRIDGE_SIGNATURE);
    162 
    163   // PCI 32bit Memory Space
    164   Status = gDS->AddMemorySpace (
    165     EfiGcdMemoryTypeMemoryMappedIo,
    166     PCI_MEM32_BASE,
    167     PCI_MEM32_SIZE,
    168     0
    169   );
    170 
    171   // PCI 64bit Memory Space
    172   Status = gDS->AddMemorySpace (
    173     EfiGcdMemoryTypeMemoryMappedIo,
    174     PCI_MEM64_BASE,
    175     PCI_MEM64_SIZE,
    176     0
    177   );
    178 
    179   return EFI_SUCCESS;
    180 }
    181 
    182 EFI_STATUS
    183 EFIAPI
    184 PciHostBridgeUnload (
    185   IN EFI_HANDLE  ImageHandle
    186   )
    187 {
    188   EFI_STATUS Status;
    189 
    190   // Free Reserved memory space in GCD
    191   gDS->RemoveMemorySpace (PCI_MEM32_BASE, PCI_MEM32_SIZE);
    192   gDS->RemoveMemorySpace (PCI_MEM64_BASE, PCI_MEM64_SIZE);
    193 
    194   // Free the allocated memory
    195   Status = HostBridgeDestructor (gpPciHostBridgeInstance);
    196   ASSERT_EFI_ERROR (Status);
    197 
    198   return Status;
    199 }
    200