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