1 /*++
2 
3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution.  The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8 
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 
12 Module Name:
13 
14   misc.c
15 
16 Abstract:
17 
18 --*/
19 
20 #include "Tiano.h"
21 #include "pei.h"
22 #include "cpuio.h"
23 #include EFI_PPI_CONSUMER (PciCfg)
24 #include EFI_PPI_CONSUMER (PciCfg2)
25 #include EFI_PROTOCOL_CONSUMER (PciRootBridgeIo)
26 
27 //
28 // Modular variable used by common libiary in PEI phase
29 //
30 EFI_GUID              mPeiCpuIoPpiGuid  = PEI_CPU_IO_PPI_GUID;
31 #if (PI_SPECIFICATION_VERSION < 0x00010000)
32 EFI_GUID              mPeiPciCfgPpiGuid = PEI_PCI_CFG_PPI_GUID;
33 PEI_PCI_CFG_PPI       *PciCfgPpi        = NULL;
34 #else
35 EFI_GUID              mPeiPciCfgPpiGuid = EFI_PEI_PCI_CFG2_PPI_GUID;
36 EFI_PEI_PCI_CFG2_PPI  *PciCfgPpi        = NULL;
37 #endif
38 EFI_PEI_SERVICES      **mPeiServices    = NULL;
39 PEI_CPU_IO_PPI        *CpuIoPpi         = NULL;
40 
41 //
42 // Modular variable used by common libiary in DXE phase
43 //
44 EFI_SYSTEM_TABLE      *mST  = NULL;
45 EFI_BOOT_SERVICES     *mBS  = NULL;
46 EFI_RUNTIME_SERVICES  *mRT  = NULL;
47 
48 EFI_STATUS
EfiInitializeCommonDriverLib(IN EFI_HANDLE ImageHandle,IN VOID * SystemTable)49 EfiInitializeCommonDriverLib (
50   IN EFI_HANDLE           ImageHandle,
51   IN VOID                 *SystemTable
52   )
53 /*++
54 
55 Routine Description:
56 
57   Initialize lib function calling phase: PEI or DXE
58 
59 Arguments:
60 
61   ImageHandle     - The firmware allocated handle for the EFI image.
62 
63   SystemTable     - A pointer to the EFI System Table.
64 
65 Returns:
66 
67   EFI_STATUS always returns EFI_SUCCESS
68 
69 --*/
70 {
71   mPeiServices  = NULL;
72   CpuIoPpi      = NULL;
73   PciCfgPpi     = NULL;
74 
75   if (ImageHandle == NULL) {
76     //
77     // The function is called in PEI phase, use PEI interfaces
78     //
79     mPeiServices = (EFI_PEI_SERVICES **) SystemTable;
80     ASSERT (mPeiServices == NULL);
81 
82     CpuIoPpi  = (**mPeiServices).CpuIo;
83     PciCfgPpi = (**mPeiServices).PciCfg;
84 
85   } else {
86     //
87     // ImageHandle is not NULL. The function is called in DXE phase
88     //
89     mST = SystemTable;
90     ASSERT (mST != NULL);
91 
92     mBS = mST->BootServices;
93     mRT = mST->RuntimeServices;
94     ASSERT (mBS != NULL);
95     ASSERT (mRT != NULL);
96 
97     //
98     // Should be at EFI_D_INFO, but lets us know things are running
99     //
100     DEBUG ((EFI_D_INFO, "EfiInitializeCommonDriverLib: Started in DXE\n"));
101     return EFI_SUCCESS;
102   }
103 
104   return EFI_SUCCESS;
105 }
106 
107 
108 EFI_STATUS
EfiCommonIoWrite(IN UINT8 Width,IN UINTN Address,IN UINTN Count,IN OUT VOID * Buffer)109 EfiCommonIoWrite (
110   IN  UINT8       Width,
111   IN  UINTN       Address,
112   IN  UINTN       Count,
113   IN  OUT VOID    *Buffer
114   )
115 /*++
116 
117 Routine Description:
118 
119   Io write operation.
120 
121 Arguments:
122 
123   Width   - Width of write operation
124   Address - Start IO address to write
125   Count   - Write count
126   Buffer  - Buffer to write to the address
127 
128 Returns:
129 
130   Status code
131 
132 --*/
133 {
134   EFI_STATUS                      Status;
135   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo;
136 
137   if (mPeiServices != NULL) {
138     //
139     // The function is called in PEI phase, use PEI interfaces
140     //
141     Status = CpuIoPpi->Io.Write (
142                             mPeiServices,
143                             CpuIoPpi,
144                             Width,
145                             Address,
146                             Count,
147                             Buffer
148                             );
149   } else {
150     //
151     // The function is called in DXE phase
152     //
153     Status = mBS->LocateProtocol (
154                     &gEfiPciRootBridgeIoProtocolGuid,
155                     NULL,
156                     (VOID **) &RootBridgeIo
157                     );
158     if (EFI_ERROR (Status)) {
159       return Status;
160     }
161 
162     Status = RootBridgeIo->Io.Write (RootBridgeIo, Width, Address, Count, Buffer);
163   }
164 
165   return Status;
166 }
167 
168 
169 EFI_STATUS
EfiCommonIoRead(IN UINT8 Width,IN UINTN Address,IN UINTN Count,IN OUT VOID * Buffer)170 EfiCommonIoRead (
171   IN  UINT8       Width,
172   IN  UINTN       Address,
173   IN  UINTN       Count,
174   IN  OUT VOID    *Buffer
175   )
176 /*++
177 
178 Routine Description:
179 
180   Io read operation.
181 
182 Arguments:
183 
184   Width   - Width of read operation
185   Address - Start IO address to read
186   Count   - Read count
187   Buffer  - Buffer to store result
188 
189 Returns:
190 
191   Status code
192 
193 --*/
194 {
195   EFI_STATUS                      Status;
196   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo;
197 
198   if (mPeiServices != NULL) {
199     //
200     // The function is called in PEI phase, use PEI interfaces
201     //
202     Status = CpuIoPpi->Io.Read (
203                             mPeiServices,
204                             CpuIoPpi,
205                             Width,
206                             Address,
207                             Count,
208                             Buffer
209                             );
210   } else {
211     //
212     // The function is called in DXE phase
213     //
214     Status = mBS->LocateProtocol (
215                     &gEfiPciRootBridgeIoProtocolGuid,
216                     NULL,
217                     (VOID **) &RootBridgeIo
218                     );
219     if (EFI_ERROR (Status)) {
220       return Status;
221     }
222 
223     Status = RootBridgeIo->Io.Read (RootBridgeIo, Width, Address, Count, Buffer);
224   }
225 
226   return Status;
227 }
228 
229 
230 EFI_STATUS
EfiCommonPciWrite(IN UINT8 Width,IN UINT64 Address,IN UINTN Count,IN OUT VOID * Buffer)231 EfiCommonPciWrite (
232   IN  UINT8       Width,
233   IN  UINT64      Address,
234   IN  UINTN       Count,
235   IN  OUT VOID    *Buffer
236   )
237 /*++
238 
239 Routine Description:
240 
241   Pci write operation
242 
243 Arguments:
244 
245   Width   - Width of PCI write
246   Address - PCI address to write
247   Count   - Write count
248   Buffer  - Buffer to write to the address
249 
250 Returns:
251 
252   Status code
253 
254 --*/
255 {
256   EFI_STATUS                      Status;
257   UINTN                           Index;
258   UINT8                           *Buffer8;
259   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo;
260 
261   if (mPeiServices != NULL) {
262     //
263     // The function is called in PEI phase, use PEI interfaces
264     //
265     Buffer8 = Buffer;
266     for (Index = 0; Index < Count; Index++) {
267       Status = PciCfgPpi->Write (
268                             mPeiServices,
269                             PciCfgPpi,
270                             Width,
271                             Address,
272                             Buffer8
273                             );
274 
275       if (EFI_ERROR (Status)) {
276         return Status;
277       }
278 
279       Buffer8 += Width;
280     }
281 
282   } else {
283     //
284     // The function is called in DXE phase
285     //
286     Status = mBS->LocateProtocol (
287                     &gEfiPciRootBridgeIoProtocolGuid,
288                     NULL,
289                     (VOID **) &RootBridgeIo
290                     );
291     if (EFI_ERROR (Status)) {
292       return Status;
293     }
294 
295     Status = RootBridgeIo->Pci.Write (
296                                 RootBridgeIo,
297                                 Width,
298                                 Address,
299                                 Count,
300                                 Buffer
301                                 );
302   }
303 
304   return EFI_SUCCESS;
305 }
306 
307 EFI_STATUS
EfiCommonPciRead(IN UINT8 Width,IN UINT64 Address,IN UINTN Count,IN OUT VOID * Buffer)308 EfiCommonPciRead (
309   IN  UINT8       Width,
310   IN  UINT64      Address,
311   IN  UINTN       Count,
312   IN  OUT VOID    *Buffer
313   )
314 /*++
315 
316 Routine Description:
317 
318   Pci read operation
319 
320 Arguments:
321 
322   Width   - Width of PCI read
323   Address - PCI address to read
324   Count   - Read count
325   Buffer  - Output buffer for the read
326 
327 Returns:
328 
329   Status code
330 
331 --*/
332 {
333   EFI_STATUS                      Status;
334   UINTN                           Index;
335   UINT8                           *Buffer8;
336   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo;
337 
338   if (mPeiServices != NULL) {
339     //
340     // The function is called in PEI phase, use PEI interfaces
341     //
342     Buffer8 = Buffer;
343     for (Index = 0; Index < Count; Index++) {
344       Status = PciCfgPpi->Read (
345                             mPeiServices,
346                             PciCfgPpi,
347                             Width,
348                             Address,
349                             Buffer8
350                             );
351 
352       if (EFI_ERROR (Status)) {
353         return Status;
354       }
355 
356       Buffer8 += Width;
357     }
358 
359   } else {
360     //
361     // The function is called in DXE phase
362     //
363     Status = mBS->LocateProtocol (
364                     &gEfiPciRootBridgeIoProtocolGuid,
365                     NULL,
366                     (VOID **) &RootBridgeIo
367                     );
368     if (EFI_ERROR (Status)) {
369       return Status;
370     }
371 
372     Status = RootBridgeIo->Pci.Read (
373                                 RootBridgeIo,
374                                 Width,
375                                 Address,
376                                 Count,
377                                 Buffer
378                                 );
379   }
380 
381   return EFI_SUCCESS;
382 }
383