]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciCommand.c
af11143e92af2c66b310be2049dbbcd906572657
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / PciBusDxe / PciCommand.c
1 /** @file
2 This module implement Pci register operation interface for
3 Pci device.
4
5 Copyright (c) 2006, Intel Corporation
6 All rights reserved. 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
17 #include "PciBus.h"
18
19 /**
20 Operate the PCI register via PciIo function interface.
21
22 @param PciIoDevice Pointer to instance of PCI_IO_DEVICE
23 @param Command Operator command
24 @param Offset The address within the PCI configuration space for the PCI controller.
25 @param Operation Type of Operation
26 @param PtrCommand Return buffer holding old PCI command, if operation is not EFI_SET_REGISTER
27
28 @return status of PciIo operation
29 **/
30 EFI_STATUS
31 PciOperateRegister (
32 IN PCI_IO_DEVICE *PciIoDevice,
33 IN UINT16 Command,
34 IN UINT8 Offset,
35 IN UINT8 Operation,
36 OUT UINT16 *PtrCommand
37 )
38 {
39 UINT16 OldCommand;
40 EFI_STATUS Status;
41 EFI_PCI_IO_PROTOCOL *PciIo;
42
43 OldCommand = 0;
44 PciIo = &PciIoDevice->PciIo;
45
46 if (Operation != EFI_SET_REGISTER) {
47 Status = PciIoRead (
48 PciIo,
49 EfiPciIoWidthUint16,
50 Offset,
51 1,
52 &OldCommand
53 );
54
55 if (Operation == EFI_GET_REGISTER) {
56 *PtrCommand = OldCommand;
57 return Status;
58 }
59 }
60
61 if (Operation == EFI_ENABLE_REGISTER) {
62 OldCommand = (UINT16) (OldCommand | Command);
63 } else if (Operation == EFI_DISABLE_REGISTER) {
64 OldCommand = (UINT16) (OldCommand & ~(Command));
65 } else {
66 OldCommand = Command;
67 }
68
69 return PciIoWrite (
70 PciIo,
71 EfiPciIoWidthUint16,
72 Offset,
73 1,
74 &OldCommand
75 );
76 }
77
78 /**
79 check the cpability of this device supports
80
81 @param PciIoDevice Pointer to instance of PCI_IO_DEVICE
82
83 @retval TRUE Support
84 @retval FALSE Not support.
85 **/
86 BOOLEAN
87 PciCapabilitySupport (
88 IN PCI_IO_DEVICE *PciIoDevice
89 )
90 {
91
92 if ((PciIoDevice->Pci.Hdr.Status & EFI_PCI_STATUS_CAPABILITY) != 0) {
93 return TRUE;
94 }
95
96 return FALSE;
97 }
98
99 /**
100 Locate cap reg.
101
102 @param PciIoDevice - A pointer to the PCI_IO_DEVICE.
103 @param CapId - The cap ID.
104 @param Offset - A pointer to the offset.
105 @param NextRegBlock - A pointer to the next block.
106
107 @retval EFI_UNSUPPORTED Pci device does not support
108 @retval EFI_NOT_FOUND Pci device support but can not find register block.
109 @retval EFI_SUCCESS Success to locate capability register block
110 **/
111 EFI_STATUS
112 LocateCapabilityRegBlock (
113 IN PCI_IO_DEVICE *PciIoDevice,
114 IN UINT8 CapId,
115 IN OUT UINT8 *Offset,
116 OUT UINT8 *NextRegBlock OPTIONAL
117 )
118 {
119 UINT8 CapabilityPtr;
120 UINT16 CapabilityEntry;
121 UINT8 CapabilityID;
122
123 //
124 // To check the cpability of this device supports
125 //
126 if (!PciCapabilitySupport (PciIoDevice)) {
127 return EFI_UNSUPPORTED;
128 }
129
130 if (*Offset != 0) {
131 CapabilityPtr = *Offset;
132 } else {
133
134 CapabilityPtr = 0;
135 if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {
136
137 PciIoRead (
138 &PciIoDevice->PciIo,
139 EfiPciIoWidthUint8,
140 EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR,
141 1,
142 &CapabilityPtr
143 );
144 } else {
145
146 PciIoRead (
147 &PciIoDevice->PciIo,
148 EfiPciIoWidthUint8,
149 PCI_CAPBILITY_POINTER_OFFSET,
150 1,
151 &CapabilityPtr
152 );
153 }
154 }
155
156 while (CapabilityPtr > 0x3F) {
157 //
158 // Mask it to DWORD alignment per PCI spec
159 //
160 CapabilityPtr &= 0xFC;
161 PciIoRead (
162 &PciIoDevice->PciIo,
163 EfiPciIoWidthUint16,
164 CapabilityPtr,
165 1,
166 &CapabilityEntry
167 );
168
169 CapabilityID = (UINT8) CapabilityEntry;
170
171 if (CapabilityID == CapId) {
172 *Offset = CapabilityPtr;
173 if (NextRegBlock != NULL) {
174 *NextRegBlock = (UINT8) (CapabilityEntry >> 8);
175 }
176
177 return EFI_SUCCESS;
178 }
179
180 CapabilityPtr = (UINT8) (CapabilityEntry >> 8);
181 }
182
183 return EFI_NOT_FOUND;
184 }
185