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