• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
HostBridgeConstructor(IN OUT PCI_HOST_BRIDGE_INSTANCE ** Instance,IN EFI_HANDLE ImageHandle)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
HostBridgeDestructor(IN PCI_HOST_BRIDGE_INSTANCE * HostBridge)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
PciHostBridgeEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)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
PciHostBridgeUnload(IN EFI_HANDLE ImageHandle)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