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