1 /*++
2 
3 Copyright (c) 2005 - 2006, 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   PciCommand.c
15 
16 Abstract:
17 
18   PCI Bus Driver
19 
20 Revision History
21 
22 --*/
23 
24 #include "PciBus.h"
25 
26 
27 EFI_STATUS
PciReadCommandRegister(IN PCI_IO_DEVICE * PciIoDevice,OUT UINT16 * Command)28 PciReadCommandRegister (
29   IN PCI_IO_DEVICE *PciIoDevice,
30   OUT UINT16       *Command
31 )
32 /*++
33 
34 Routine Description:
35 
36 Arguments:
37 
38 Returns:
39 
40   None
41 
42 --*/
43 {
44 
45   EFI_PCI_IO_PROTOCOL   *PciIo;
46 
47   *Command = 0;
48   PciIo = &PciIoDevice->PciIo;
49 
50   return PciIo->Pci.Read (
51                 PciIo,
52                 EfiPciIoWidthUint16,
53                 PCI_COMMAND_OFFSET,
54                 1,
55                 Command
56                 );
57 }
58 
59 EFI_STATUS
PciSetCommandRegister(IN PCI_IO_DEVICE * PciIoDevice,IN UINT16 Command)60 PciSetCommandRegister (
61   IN PCI_IO_DEVICE *PciIoDevice,
62   IN UINT16        Command
63 )
64 /*++
65 
66 Routine Description:
67 
68 Arguments:
69 
70 Returns:
71 
72   None
73 
74 --*/
75 {
76   UINT16                Temp;
77   EFI_PCI_IO_PROTOCOL   *PciIo;
78 
79   Temp = Command;
80   PciIo = &PciIoDevice->PciIo;
81 
82   return PciIo->Pci.Write (
83               PciIo,
84               EfiPciIoWidthUint16,
85               PCI_COMMAND_OFFSET,
86               1,
87               &Temp
88               );
89 
90 }
91 
92 
93 EFI_STATUS
PciEnableCommandRegister(IN PCI_IO_DEVICE * PciIoDevice,IN UINT16 Command)94 PciEnableCommandRegister (
95   IN PCI_IO_DEVICE *PciIoDevice,
96   IN UINT16        Command
97 )
98 /*++
99 
100 Routine Description:
101 
102 Arguments:
103 
104 Returns:
105 
106   None
107 
108 --*/
109 {
110   UINT16  OldCommand;
111   EFI_PCI_IO_PROTOCOL   *PciIo;
112 
113   OldCommand = 0;
114   PciIo = &PciIoDevice->PciIo;
115 
116   PciIo->Pci.Read (
117           PciIo,
118           EfiPciIoWidthUint16,
119           PCI_COMMAND_OFFSET,
120           1,
121           &OldCommand
122           );
123 
124   OldCommand = (UINT16) (OldCommand | Command);
125 
126   return PciIo->Pci.Write (
127               PciIo,
128               EfiPciIoWidthUint16,
129               PCI_COMMAND_OFFSET,
130               1,
131               &OldCommand
132               );
133 
134 }
135 
136 
137 EFI_STATUS
PciDisableCommandRegister(IN PCI_IO_DEVICE * PciIoDevice,IN UINT16 Command)138 PciDisableCommandRegister (
139   IN PCI_IO_DEVICE *PciIoDevice,
140   IN UINT16        Command
141 )
142 /*++
143 
144 Routine Description:
145 
146 Arguments:
147 
148 Returns:
149 
150   None
151 
152 --*/
153 {
154   UINT16  OldCommand;
155   EFI_PCI_IO_PROTOCOL   *PciIo;
156 
157   OldCommand = 0;
158   PciIo = &PciIoDevice->PciIo;
159 
160   PciIo->Pci.Read (
161           PciIo,
162           EfiPciIoWidthUint16,
163           PCI_COMMAND_OFFSET,
164           1,
165           &OldCommand
166           );
167 
168   OldCommand = (UINT16) (OldCommand & ~(Command));
169 
170   return PciIo->Pci.Write (
171             PciIo,
172             EfiPciIoWidthUint16,
173             PCI_COMMAND_OFFSET,
174             1,
175             &OldCommand
176            );
177 
178 }
179 
180 
181 
182 EFI_STATUS
PciSetBridgeControlRegister(IN PCI_IO_DEVICE * PciIoDevice,IN UINT16 Command)183 PciSetBridgeControlRegister (
184   IN PCI_IO_DEVICE *PciIoDevice,
185   IN UINT16        Command
186 )
187 /*++
188 
189 Routine Description:
190 
191 Arguments:
192 
193 Returns:
194 
195   None
196 
197 --*/
198 {
199   UINT16                Temp;
200   EFI_PCI_IO_PROTOCOL   *PciIo;
201 
202   Temp = Command;
203   PciIo = &PciIoDevice->PciIo;
204 
205   return PciIo->Pci.Write (
206                 PciIo,
207                 EfiPciIoWidthUint16,
208                 PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
209                 1,
210                 &Temp
211                );
212 
213 }
214 
215 
216 EFI_STATUS
PciEnableBridgeControlRegister(IN PCI_IO_DEVICE * PciIoDevice,IN UINT16 Command)217 PciEnableBridgeControlRegister (
218   IN PCI_IO_DEVICE *PciIoDevice,
219   IN UINT16        Command
220 )
221 /*++
222 
223 Routine Description:
224 
225 Arguments:
226 
227 Returns:
228 
229   None
230 
231 --*/
232 {
233   UINT16  OldCommand;
234   EFI_PCI_IO_PROTOCOL   *PciIo;
235 
236   OldCommand = 0;
237   PciIo = &PciIoDevice->PciIo;
238 
239   PciIo->Pci.Read (
240           PciIo,
241           EfiPciIoWidthUint16,
242           PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
243           1,
244           &OldCommand
245           );
246 
247   OldCommand = (UINT16) (OldCommand | Command);
248 
249   return PciIo->Pci.Write (
250               PciIo,
251               EfiPciIoWidthUint16,
252               PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
253               1,
254               &OldCommand
255              );
256 
257 }
258 
259 EFI_STATUS
PciDisableBridgeControlRegister(IN PCI_IO_DEVICE * PciIoDevice,IN UINT16 Command)260 PciDisableBridgeControlRegister (
261   IN PCI_IO_DEVICE *PciIoDevice,
262   IN UINT16        Command
263 )
264 /*++
265 
266 Routine Description:
267 
268 Arguments:
269 
270 Returns:
271 
272   None
273 
274 --*/
275 {
276   UINT16  OldCommand;
277   EFI_PCI_IO_PROTOCOL   *PciIo;
278 
279   OldCommand = 0;
280   PciIo = &PciIoDevice->PciIo;
281 
282   PciIo->Pci.Read (
283           PciIo,
284           EfiPciIoWidthUint16,
285           PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
286           1,
287           &OldCommand
288           );
289 
290   OldCommand = (UINT16) (OldCommand & ~(Command));
291 
292   return PciIo->Pci.Write (
293               PciIo,
294               EfiPciIoWidthUint16,
295               PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
296               1,
297               &OldCommand
298               );
299 
300 }
301 
302 
303 
304 EFI_STATUS
PciReadBridgeControlRegister(IN PCI_IO_DEVICE * PciIoDevice,OUT UINT16 * Command)305 PciReadBridgeControlRegister (
306   IN PCI_IO_DEVICE *PciIoDevice,
307   OUT UINT16       *Command
308 )
309 /*++
310 
311 Routine Description:
312 
313 Arguments:
314 
315 Returns:
316 
317   None
318 
319 --*/
320 {
321 
322   EFI_PCI_IO_PROTOCOL   *PciIo;
323 
324   *Command = 0;
325   PciIo = &PciIoDevice->PciIo;
326 
327   return PciIo->Pci.Read (
328                 PciIo,
329                 EfiPciIoWidthUint16,
330                 PCI_BRIDGE_CONTROL_REGISTER_OFFSET,
331                 1,
332                 Command
333                 );
334 
335 }
336 
337 BOOLEAN
PciCapabilitySupport(IN PCI_IO_DEVICE * PciIoDevice)338 PciCapabilitySupport (
339   IN PCI_IO_DEVICE  *PciIoDevice
340   )
341 /*++
342 
343 Routine Description:
344 
345 Arguments:
346 
347 Returns:
348 
349   None
350 
351 --*/
352 // TODO:    PciIoDevice - add argument and description to function comment
353 {
354 
355   if (PciIoDevice->Pci.Hdr.Status & EFI_PCI_STATUS_CAPABILITY) {
356     return TRUE;
357   }
358 
359   return FALSE;
360 }
361 
362 EFI_STATUS
LocateCapabilityRegBlock(IN PCI_IO_DEVICE * PciIoDevice,IN UINT8 CapId,IN OUT UINT8 * Offset,OUT UINT8 * NextRegBlock OPTIONAL)363 LocateCapabilityRegBlock (
364   IN     PCI_IO_DEVICE *PciIoDevice,
365   IN     UINT8         CapId,
366   IN OUT UINT8         *Offset,
367      OUT UINT8         *NextRegBlock OPTIONAL
368   )
369 /*++
370 
371 Routine Description:
372 
373   Locate Capability register.
374 
375 Arguments:
376 
377   PciIoDevice         - A pointer to the PCI_IO_DEVICE.
378   CapId               - The capability ID.
379   Offset              - A pointer to the offset.
380                         As input: the default offset;
381                         As output: the offset of the found block.
382   NextRegBlock        - An optional pointer to return the value of next block.
383 
384 Returns:
385 
386   EFI_UNSUPPORTED     - The Pci Io device is not supported.
387   EFI_NOT_FOUND       - The Pci Io device cannot be found.
388   EFI_SUCCESS         - The Pci Io device is successfully located.
389 
390 --*/
391 {
392   UINT8   CapabilityPtr;
393   UINT16  CapabilityEntry;
394   UINT8   CapabilityID;
395 
396   //
397   // To check the capability of this device supports
398   //
399   if (!PciCapabilitySupport (PciIoDevice)) {
400     return EFI_UNSUPPORTED;
401   }
402 
403   if (*Offset != 0) {
404     CapabilityPtr = *Offset;
405   } else {
406 
407     CapabilityPtr = 0;
408     if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {
409 
410       PciIoDevice->PciIo.Pci.Read (
411                                &PciIoDevice->PciIo,
412                                EfiPciIoWidthUint8,
413                                EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR,
414                                1,
415                                &CapabilityPtr
416                                );
417     } else {
418 
419       PciIoDevice->PciIo.Pci.Read (
420                                &PciIoDevice->PciIo,
421                                EfiPciIoWidthUint8,
422                                PCI_CAPBILITY_POINTER_OFFSET,
423                                1,
424                                &CapabilityPtr
425                                );
426     }
427   }
428 
429   while ((CapabilityPtr >= 0x40) && ((CapabilityPtr & 0x03) == 0x00)) {
430     PciIoDevice->PciIo.Pci.Read (
431                              &PciIoDevice->PciIo,
432                              EfiPciIoWidthUint16,
433                              CapabilityPtr,
434                              1,
435                              &CapabilityEntry
436                              );
437 
438     CapabilityID = (UINT8) CapabilityEntry;
439 
440     if (CapabilityID == CapId) {
441       *Offset = CapabilityPtr;
442       if (NextRegBlock != NULL) {
443         *NextRegBlock = (UINT8) (CapabilityEntry >> 8);
444       }
445 
446       return EFI_SUCCESS;
447     }
448 
449     CapabilityPtr = (UINT8) (CapabilityEntry >> 8);
450   }
451 
452   return EFI_NOT_FOUND;
453 }
454