]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1459 6f19259b...
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / PciBus / Dxe / PciIo.c
CommitLineData
878ddf1f 1/*++\r
2 \r
3Copyright (c) 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 PciIo.c\r
15 \r
16Abstract:\r
17\r
18 PCI I/O Abstraction Driver\r
19\r
20Revision History\r
21\r
22--*/\r
23\r
f0ec738d 24#include "pcibus.h"\r
878ddf1f 25\r
26//\r
27// Internal use only\r
28//\r
29STATIC\r
30EFI_STATUS\r
31ReportErrorStatusCode (\r
32 IN PCI_IO_DEVICE *PciIoDevice,\r
33 IN EFI_STATUS_CODE_VALUE Code\r
34 );\r
35\r
36//\r
37// PCI I/O Support Function Prototypes\r
38//\r
39//\r
40//\r
41// Pci Io Protocol Interface\r
42//\r
43static EFI_PCI_IO_PROTOCOL PciIoInterface = {\r
44 PciIoPollMem,\r
45 PciIoPollIo,\r
46 {\r
47 PciIoMemRead,\r
48 PciIoMemWrite\r
49 },\r
50 {\r
51 PciIoIoRead,\r
52 PciIoIoWrite\r
53 },\r
54 {\r
55 PciIoConfigRead,\r
56 PciIoConfigWrite\r
57 },\r
58 PciIoCopyMem,\r
59 PciIoMap,\r
60 PciIoUnmap,\r
61 PciIoAllocateBuffer,\r
62 PciIoFreeBuffer,\r
63 PciIoFlush,\r
64 PciIoGetLocation,\r
65 PciIoAttributes,\r
66 PciIoGetBarAttributes,\r
67 PciIoSetBarAttributes,\r
68 0,\r
69 NULL\r
70};\r
71\r
72STATIC\r
73EFI_STATUS\r
74ReportErrorStatusCode (\r
75 IN PCI_IO_DEVICE *PciIoDevice,\r
76 IN EFI_STATUS_CODE_VALUE Code\r
77 )\r
78/*++\r
79\r
80Routine Description:\r
81\r
82 report a error Status code of PCI bus driver controller\r
83\r
84Arguments:\r
85 \r
86Returns:\r
87\r
88 None\r
89\r
90--*/\r
91// TODO: PciIoDevice - add argument and description to function comment\r
92// TODO: Code - add argument and description to function comment\r
93{\r
94 return REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
95 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
96 Code,\r
97 PciIoDevice->DevicePath\r
98 );\r
99}\r
100\r
101EFI_STATUS\r
102InitializePciIoInstance (\r
103 PCI_IO_DEVICE *PciIoDevice\r
104 )\r
105/*++\r
106\r
107Routine Description:\r
108\r
109 Initializes a PCI I/O Instance\r
110\r
111Arguments:\r
112 \r
113Returns:\r
114\r
115 None\r
116\r
117--*/\r
118// TODO: PciIoDevice - add argument and description to function comment\r
119// TODO: EFI_SUCCESS - add return value to function comment\r
120{\r
121 CopyMem (&PciIoDevice->PciIo, &PciIoInterface, sizeof (EFI_PCI_IO_PROTOCOL));\r
122 return EFI_SUCCESS;\r
123}\r
124\r
125EFI_STATUS\r
126PciIoVerifyBarAccess (\r
127 PCI_IO_DEVICE *PciIoDevice,\r
128 UINT8 BarIndex,\r
129 PCI_BAR_TYPE Type,\r
130 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
131 IN UINTN Count,\r
132 UINT64 *Offset\r
133 )\r
134/*++\r
135\r
136Routine Description:\r
137\r
138 Verifies access to a PCI Base Address Register (BAR)\r
139\r
140Arguments:\r
141\r
142Returns:\r
143\r
144 None\r
145\r
146--*/\r
147// TODO: PciIoDevice - add argument and description to function comment\r
148// TODO: BarIndex - add argument and description to function comment\r
149// TODO: Type - add argument and description to function comment\r
150// TODO: Width - add argument and description to function comment\r
151// TODO: Count - add argument and description to function comment\r
152// TODO: Offset - add argument and description to function comment\r
153// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
154// TODO: EFI_SUCCESS - add return value to function comment\r
155// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
156// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
157// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
158// TODO: EFI_SUCCESS - add return value to function comment\r
159{\r
160 if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
161 return EFI_INVALID_PARAMETER;\r
162 }\r
163\r
164 if (BarIndex == EFI_PCI_IO_PASS_THROUGH_BAR) {\r
165 return EFI_SUCCESS;\r
166 }\r
167\r
168 //\r
169 // BarIndex 0-5 is legal\r
170 //\r
171 if (BarIndex >= PCI_MAX_BAR) {\r
172 return EFI_INVALID_PARAMETER;\r
173 }\r
174\r
175 if (!CheckBarType (PciIoDevice, BarIndex, Type)) {\r
176 return EFI_INVALID_PARAMETER;\r
177 }\r
178\r
179 //\r
180 // If Width is EfiPciIoWidthFifoUintX then convert to EfiPciIoWidthUintX\r
181 // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX\r
182 //\r
183 if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {\r
184 Count = 1;\r
185 }\r
186\r
187 Width &= 0x03;\r
188\r
189 if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PciIoDevice->PciBar[BarIndex].Length) {\r
190 return EFI_INVALID_PARAMETER;\r
191 }\r
192\r
193 *Offset = *Offset + PciIoDevice->PciBar[BarIndex].BaseAddress;\r
194\r
195 return EFI_SUCCESS;\r
196}\r
197\r
198EFI_STATUS\r
199PciIoVerifyConfigAccess (\r
200 PCI_IO_DEVICE *PciIoDevice,\r
201 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
202 IN UINTN Count,\r
203 IN UINT64 *Offset\r
204 )\r
205/*++\r
206\r
207Routine Description:\r
208\r
209 Verifies access to a PCI Config Header\r
210\r
211Arguments:\r
212\r
213Returns:\r
214\r
215 None\r
216\r
217--*/\r
218// TODO: PciIoDevice - add argument and description to function comment\r
219// TODO: Width - add argument and description to function comment\r
220// TODO: Count - add argument and description to function comment\r
221// TODO: Offset - add argument and description to function comment\r
222// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
223// TODO: EFI_UNSUPPORTED - add return value to function comment\r
224// TODO: EFI_UNSUPPORTED - add return value to function comment\r
225// TODO: EFI_SUCCESS - add return value to function comment\r
226{\r
227 UINT64 ExtendOffset;\r
228\r
229 if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
230 return EFI_INVALID_PARAMETER;\r
231 }\r
232\r
233 //\r
234 // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX\r
235 //\r
236 Width &= 0x03;\r
237\r
238 if (PciIoDevice->IsPciExp) {\r
239 if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_EXP_MAX_CONFIG_OFFSET) {\r
240 return EFI_UNSUPPORTED;\r
241 }\r
242\r
243 ExtendOffset = LShiftU64 (*Offset, 32);\r
244 *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0);\r
245 *Offset = (*Offset) | ExtendOffset;\r
246\r
247 } else {\r
248 if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_MAX_CONFIG_OFFSET) {\r
249 return EFI_UNSUPPORTED;\r
250 }\r
251\r
252 *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, *Offset);\r
253 }\r
254\r
255 return EFI_SUCCESS;\r
256}\r
257\r
258EFI_STATUS\r
259EFIAPI\r
260PciIoPollMem (\r
261 IN EFI_PCI_IO_PROTOCOL *This,\r
262 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
263 IN UINT8 BarIndex,\r
264 IN UINT64 Offset,\r
265 IN UINT64 Mask,\r
266 IN UINT64 Value,\r
267 IN UINT64 Delay,\r
268 OUT UINT64 *Result\r
269 )\r
270/*++\r
271\r
272Routine Description:\r
273\r
274 Poll PCI Memmory\r
275\r
276Arguments:\r
277\r
278Returns:\r
279\r
280 None\r
281\r
282--*/\r
283// TODO: This - add argument and description to function comment\r
284// TODO: Width - add argument and description to function comment\r
285// TODO: BarIndex - add argument and description to function comment\r
286// TODO: Offset - add argument and description to function comment\r
287// TODO: Mask - add argument and description to function comment\r
288// TODO: Value - add argument and description to function comment\r
289// TODO: Delay - add argument and description to function comment\r
290// TODO: Result - add argument and description to function comment\r
291// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
292// TODO: EFI_UNSUPPORTED - add return value to function comment\r
293// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
294{\r
295 EFI_STATUS Status;\r
296 PCI_IO_DEVICE *PciIoDevice;\r
297\r
298 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
299\r
300 if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
301 return EFI_INVALID_PARAMETER;\r
302 }\r
303\r
304 Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, 1, &Offset);\r
305 if (EFI_ERROR (Status)) {\r
306 return EFI_UNSUPPORTED;\r
307 }\r
308\r
309 if (Width > EfiPciIoWidthUint64) {\r
310 return EFI_INVALID_PARAMETER;\r
311 }\r
312\r
313 Status = PciIoDevice->PciRootBridgeIo->PollMem (\r
314 PciIoDevice->PciRootBridgeIo,\r
315 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
316 Offset,\r
317 Mask,\r
318 Value,\r
319 Delay,\r
320 Result\r
321 );\r
322\r
323 if (EFI_ERROR (Status)) {\r
324 ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
325 }\r
326\r
327 return Status;\r
328}\r
329\r
330EFI_STATUS\r
331EFIAPI\r
332PciIoPollIo (\r
333 IN EFI_PCI_IO_PROTOCOL *This,\r
334 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
335 IN UINT8 BarIndex,\r
336 IN UINT64 Offset,\r
337 IN UINT64 Mask,\r
338 IN UINT64 Value,\r
339 IN UINT64 Delay,\r
340 OUT UINT64 *Result\r
341 )\r
342/*++\r
343\r
344Routine Description:\r
345\r
346 Poll PCI IO\r
347\r
348Arguments:\r
349\r
350Returns:\r
351\r
352 None\r
353\r
354--*/\r
355// TODO: This - add argument and description to function comment\r
356// TODO: Width - add argument and description to function comment\r
357// TODO: BarIndex - add argument and description to function comment\r
358// TODO: Offset - add argument and description to function comment\r
359// TODO: Mask - add argument and description to function comment\r
360// TODO: Value - add argument and description to function comment\r
361// TODO: Delay - add argument and description to function comment\r
362// TODO: Result - add argument and description to function comment\r
363// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
364// TODO: EFI_UNSUPPORTED - add return value to function comment\r
365// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
366{\r
367 EFI_STATUS Status;\r
368 PCI_IO_DEVICE *PciIoDevice;\r
369\r
370 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
371\r
372 if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
373 return EFI_INVALID_PARAMETER;\r
374 }\r
375\r
376 Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, 1, &Offset);\r
377 if (EFI_ERROR (Status)) {\r
378 return EFI_UNSUPPORTED;\r
379 }\r
380\r
381 if (Width > EfiPciIoWidthUint64) {\r
382 return EFI_INVALID_PARAMETER;\r
383 }\r
384\r
385 Status = PciIoDevice->PciRootBridgeIo->PollIo (\r
386 PciIoDevice->PciRootBridgeIo,\r
387 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
388 Offset,\r
389 Mask,\r
390 Value,\r
391 Delay,\r
392 Result\r
393 );\r
394\r
395 if (EFI_ERROR (Status)) {\r
396 ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
397 }\r
398\r
399 return Status;\r
400}\r
401\r
402EFI_STATUS\r
403EFIAPI\r
404PciIoMemRead (\r
405 IN EFI_PCI_IO_PROTOCOL *This,\r
406 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
407 IN UINT8 BarIndex,\r
408 IN UINT64 Offset,\r
409 IN UINTN Count,\r
410 IN OUT VOID *Buffer\r
411 )\r
412/*++\r
413\r
414Routine Description:\r
415\r
416 Performs a PCI Memory Read Cycle\r
417\r
418Arguments:\r
419\r
420Returns:\r
421\r
422 None\r
423\r
424--*/\r
425// TODO: This - add argument and description to function comment\r
426// TODO: Width - add argument and description to function comment\r
427// TODO: BarIndex - add argument and description to function comment\r
428// TODO: Offset - add argument and description to function comment\r
429// TODO: Count - add argument and description to function comment\r
430// TODO: Buffer - add argument and description to function comment\r
431// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
432// TODO: EFI_UNSUPPORTED - add return value to function comment\r
433{\r
434 EFI_STATUS Status;\r
435 PCI_IO_DEVICE *PciIoDevice;\r
436\r
437 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
438\r
439 if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
440 return EFI_INVALID_PARAMETER;\r
441 }\r
442\r
443 Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);\r
444 if (EFI_ERROR (Status)) {\r
445 return EFI_UNSUPPORTED;\r
446 }\r
447\r
448 Status = PciIoDevice->PciRootBridgeIo->Mem.Read (\r
449 PciIoDevice->PciRootBridgeIo,\r
450 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
451 Offset,\r
452 Count,\r
453 Buffer\r
454 );\r
455\r
456 if (EFI_ERROR (Status)) {\r
457 ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);\r
458 }\r
459\r
460 return Status;\r
461}\r
462\r
463EFI_STATUS\r
464EFIAPI\r
465PciIoMemWrite (\r
466 IN EFI_PCI_IO_PROTOCOL *This,\r
467 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
468 IN UINT8 BarIndex,\r
469 IN UINT64 Offset,\r
470 IN UINTN Count,\r
471 IN OUT VOID *Buffer\r
472 )\r
473/*++\r
474\r
475Routine Description:\r
476\r
477 Performs a PCI Memory Write Cycle\r
478\r
479Arguments:\r
480\r
481Returns:\r
482\r
483 None\r
484\r
485--*/\r
486// TODO: This - add argument and description to function comment\r
487// TODO: Width - add argument and description to function comment\r
488// TODO: BarIndex - add argument and description to function comment\r
489// TODO: Offset - add argument and description to function comment\r
490// TODO: Count - add argument and description to function comment\r
491// TODO: Buffer - add argument and description to function comment\r
492// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
493// TODO: EFI_UNSUPPORTED - add return value to function comment\r
494{\r
495 EFI_STATUS Status;\r
496 PCI_IO_DEVICE *PciIoDevice;\r
497\r
498 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
499\r
500 if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
501 return EFI_INVALID_PARAMETER;\r
502 }\r
503\r
504 Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);\r
505 if (EFI_ERROR (Status)) {\r
506 return EFI_UNSUPPORTED;\r
507 }\r
508\r
509 Status = PciIoDevice->PciRootBridgeIo->Mem.Write (\r
510 PciIoDevice->PciRootBridgeIo,\r
511 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
512 Offset,\r
513 Count,\r
514 Buffer\r
515 );\r
516\r
517 if (EFI_ERROR (Status)) {\r
518 ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);\r
519 }\r
520\r
521 return Status;\r
522}\r
523\r
524EFI_STATUS\r
525EFIAPI\r
526PciIoIoRead (\r
527 IN EFI_PCI_IO_PROTOCOL *This,\r
528 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
529 IN UINT8 BarIndex,\r
530 IN UINT64 Offset,\r
531 IN UINTN Count,\r
532 IN OUT VOID *Buffer\r
533 )\r
534/*++\r
535\r
536Routine Description:\r
537\r
538 Performs a PCI I/O Read Cycle\r
539\r
540Arguments:\r
541\r
542Returns:\r
543\r
544 None\r
545\r
546--*/\r
547// TODO: This - add argument and description to function comment\r
548// TODO: Width - add argument and description to function comment\r
549// TODO: BarIndex - add argument and description to function comment\r
550// TODO: Offset - add argument and description to function comment\r
551// TODO: Count - add argument and description to function comment\r
552// TODO: Buffer - add argument and description to function comment\r
553// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
554// TODO: EFI_UNSUPPORTED - add return value to function comment\r
555{\r
556 EFI_STATUS Status;\r
557 PCI_IO_DEVICE *PciIoDevice;\r
558\r
559 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
560\r
561 if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
562 return EFI_INVALID_PARAMETER;\r
563 }\r
564\r
565 Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);\r
566 if (EFI_ERROR (Status)) {\r
567 return EFI_UNSUPPORTED;\r
568 }\r
569\r
570 Status = PciIoDevice->PciRootBridgeIo->Io.Read (\r
571 PciIoDevice->PciRootBridgeIo,\r
572 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
573 Offset,\r
574 Count,\r
575 Buffer\r
576 );\r
577\r
578 if (EFI_ERROR (Status)) {\r
579 ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);\r
580 }\r
581\r
582 return Status;\r
583}\r
584\r
585EFI_STATUS\r
586EFIAPI\r
587PciIoIoWrite (\r
588 IN EFI_PCI_IO_PROTOCOL *This,\r
589 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
590 IN UINT8 BarIndex,\r
591 IN UINT64 Offset,\r
592 IN UINTN Count,\r
593 IN OUT VOID *Buffer\r
594 )\r
595/*++\r
596\r
597Routine Description:\r
598\r
599 Performs a PCI I/O Write Cycle\r
600\r
601Arguments:\r
602\r
603Returns:\r
604\r
605 None\r
606\r
607--*/\r
608// TODO: This - add argument and description to function comment\r
609// TODO: Width - add argument and description to function comment\r
610// TODO: BarIndex - add argument and description to function comment\r
611// TODO: Offset - add argument and description to function comment\r
612// TODO: Count - add argument and description to function comment\r
613// TODO: Buffer - add argument and description to function comment\r
614// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
615// TODO: EFI_UNSUPPORTED - add return value to function comment\r
616{\r
617 EFI_STATUS Status;\r
618 PCI_IO_DEVICE *PciIoDevice;\r
619\r
620 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
621\r
622 if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
623 return EFI_INVALID_PARAMETER;\r
624 }\r
625\r
626 Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);\r
627 if (EFI_ERROR (Status)) {\r
628 return EFI_UNSUPPORTED;\r
629 }\r
630\r
631 Status = PciIoDevice->PciRootBridgeIo->Io.Write (\r
632 PciIoDevice->PciRootBridgeIo,\r
633 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
634 Offset,\r
635 Count,\r
636 Buffer\r
637 );\r
638\r
639 if (EFI_ERROR (Status)) {\r
640 ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);\r
641 }\r
642\r
643 return Status;\r
644}\r
645\r
646EFI_STATUS\r
647EFIAPI\r
648PciIoConfigRead (\r
649 IN EFI_PCI_IO_PROTOCOL *This,\r
650 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
651 IN UINT32 Offset,\r
652 IN UINTN Count,\r
653 IN OUT VOID *Buffer\r
654 )\r
655/*++\r
656\r
657Routine Description:\r
658\r
659 Performs a PCI Configuration Read Cycle\r
660\r
661Arguments:\r
662\r
663Returns:\r
664\r
665 None\r
666\r
667--*/\r
668// TODO: This - add argument and description to function comment\r
669// TODO: Width - add argument and description to function comment\r
670// TODO: Offset - add argument and description to function comment\r
671// TODO: Count - add argument and description to function comment\r
672// TODO: Buffer - add argument and description to function comment\r
673{\r
674 EFI_STATUS Status;\r
675 PCI_IO_DEVICE *PciIoDevice;\r
676 UINT64 Address;\r
677\r
678 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
679\r
680 Address = Offset;\r
681 Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);\r
682 if (EFI_ERROR (Status)) {\r
683 return Status;\r
684 }\r
685\r
686 Status = PciIoDevice->PciRootBridgeIo->Pci.Read (\r
687 PciIoDevice->PciRootBridgeIo,\r
688 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
689 Address,\r
690 Count,\r
691 Buffer\r
692 );\r
693\r
694 if (EFI_ERROR (Status)) {\r
695 ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);\r
696 }\r
697\r
698 return Status;\r
699}\r
700\r
701EFI_STATUS\r
702EFIAPI\r
703PciIoConfigWrite (\r
704 IN EFI_PCI_IO_PROTOCOL *This,\r
705 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
706 IN UINT32 Offset,\r
707 IN UINTN Count,\r
708 IN OUT VOID *Buffer\r
709 )\r
710/*++\r
711\r
712Routine Description:\r
713\r
714 Performs a PCI Configuration Write Cycle\r
715\r
716Arguments:\r
717\r
718Returns:\r
719\r
720 None\r
721\r
722--*/\r
723// TODO: This - add argument and description to function comment\r
724// TODO: Width - add argument and description to function comment\r
725// TODO: Offset - add argument and description to function comment\r
726// TODO: Count - add argument and description to function comment\r
727// TODO: Buffer - add argument and description to function comment\r
728{\r
729 EFI_STATUS Status;\r
730 PCI_IO_DEVICE *PciIoDevice;\r
731 UINT64 Address;\r
732\r
733 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
734\r
735 Address = Offset;\r
736 Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);\r
737 if (EFI_ERROR (Status)) {\r
738 return Status;\r
739 }\r
740\r
741 Status = PciIoDevice->PciRootBridgeIo->Pci.Write (\r
742 PciIoDevice->PciRootBridgeIo,\r
743 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
744 Address,\r
745 Count,\r
746 Buffer\r
747 );\r
748\r
749 if (EFI_ERROR (Status)) {\r
750 ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);\r
751 }\r
752\r
753 return Status;\r
754}\r
755\r
756EFI_STATUS\r
757EFIAPI\r
758PciIoCopyMem (\r
759 IN EFI_PCI_IO_PROTOCOL *This,\r
760 IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
761 IN UINT8 DestBarIndex,\r
762 IN UINT64 DestOffset,\r
763 IN UINT8 SrcBarIndex,\r
764 IN UINT64 SrcOffset,\r
765 IN UINTN Count\r
766 )\r
767/*++\r
768\r
769Routine Description:\r
770\r
771 Copy PCI Memory\r
772\r
773Arguments:\r
774\r
775Returns:\r
776\r
777 None\r
778\r
779--*/\r
780// TODO: This - add argument and description to function comment\r
781// TODO: Width - add argument and description to function comment\r
782// TODO: DestBarIndex - add argument and description to function comment\r
783// TODO: DestOffset - add argument and description to function comment\r
784// TODO: SrcBarIndex - add argument and description to function comment\r
785// TODO: SrcOffset - add argument and description to function comment\r
786// TODO: Count - add argument and description to function comment\r
787// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
788// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
789// TODO: EFI_UNSUPPORTED - add return value to function comment\r
790// TODO: EFI_UNSUPPORTED - add return value to function comment\r
791{\r
792 EFI_STATUS Status;\r
793 PCI_IO_DEVICE *PciIoDevice;\r
794\r
795 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
796\r
797 if (Width < 0 || Width >= EfiPciIoWidthMaximum) {\r
798 return EFI_INVALID_PARAMETER;\r
799 }\r
800\r
801 if (Width == EfiPciIoWidthFifoUint8 ||\r
802 Width == EfiPciIoWidthFifoUint16 ||\r
803 Width == EfiPciIoWidthFifoUint32 ||\r
804 Width == EfiPciIoWidthFifoUint64 ||\r
805 Width == EfiPciIoWidthFillUint8 ||\r
806 Width == EfiPciIoWidthFillUint16 ||\r
807 Width == EfiPciIoWidthFillUint32 ||\r
808 Width == EfiPciIoWidthFillUint64) {\r
809 return EFI_INVALID_PARAMETER;\r
810 }\r
811\r
812 Status = PciIoVerifyBarAccess (PciIoDevice, DestBarIndex, PciBarTypeMem, Width, Count, &DestOffset);\r
813 if (EFI_ERROR (Status)) {\r
814 return EFI_UNSUPPORTED;\r
815 }\r
816\r
817 Status = PciIoVerifyBarAccess (PciIoDevice, SrcBarIndex, PciBarTypeMem, Width, Count, &SrcOffset);\r
818 if (EFI_ERROR (Status)) {\r
819 return EFI_UNSUPPORTED;\r
820 }\r
821\r
822 Status = PciIoDevice->PciRootBridgeIo->CopyMem (\r
823 PciIoDevice->PciRootBridgeIo,\r
824 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
825 DestOffset,\r
826 SrcOffset,\r
827 Count\r
828 );\r
829\r
830 if (EFI_ERROR (Status)) {\r
831 ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
832 }\r
833\r
834 return Status;\r
835}\r
836\r
837EFI_STATUS\r
838EFIAPI\r
839PciIoMap (\r
840 IN EFI_PCI_IO_PROTOCOL *This,\r
841 IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,\r
842 IN VOID *HostAddress,\r
843 IN OUT UINTN *NumberOfBytes,\r
844 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
845 OUT VOID **Mapping\r
846 )\r
847/*++\r
848\r
849Routine Description:\r
850\r
851 Maps a memory region for DMA\r
852\r
853Arguments:\r
854\r
855Returns:\r
856\r
857 None\r
858\r
859--*/\r
860// TODO: This - add argument and description to function comment\r
861// TODO: Operation - add argument and description to function comment\r
862// TODO: HostAddress - add argument and description to function comment\r
863// TODO: NumberOfBytes - add argument and description to function comment\r
864// TODO: DeviceAddress - add argument and description to function comment\r
865// TODO: Mapping - add argument and description to function comment\r
866// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
867// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
868{\r
869 EFI_STATUS Status;\r
870 PCI_IO_DEVICE *PciIoDevice;\r
871\r
872 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
873\r
874 if (Operation < 0 || Operation >= EfiPciIoOperationMaximum) {\r
875 return EFI_INVALID_PARAMETER;\r
876 }\r
877\r
878 if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {\r
879 return EFI_INVALID_PARAMETER;\r
880 }\r
881\r
882 if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {\r
883 Operation = Operation + EfiPciOperationBusMasterRead64;\r
884 }\r
885\r
886 Status = PciIoDevice->PciRootBridgeIo->Map (\r
887 PciIoDevice->PciRootBridgeIo,\r
888 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,\r
889 HostAddress,\r
890 NumberOfBytes,\r
891 DeviceAddress,\r
892 Mapping\r
893 );\r
894\r
895 if (EFI_ERROR (Status)) {\r
896 ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
897 }\r
898\r
899 return Status;\r
900}\r
901\r
902EFI_STATUS\r
903EFIAPI\r
904PciIoUnmap (\r
905 IN EFI_PCI_IO_PROTOCOL *This,\r
906 IN VOID *Mapping\r
907 )\r
908/*++\r
909\r
910Routine Description:\r
911\r
912 Unmaps a memory region for DMA\r
913\r
914Arguments:\r
915\r
916Returns:\r
917\r
918 None\r
919\r
920--*/\r
921// TODO: This - add argument and description to function comment\r
922// TODO: Mapping - add argument and description to function comment\r
923{\r
924 EFI_STATUS Status;\r
925 PCI_IO_DEVICE *PciIoDevice;\r
926\r
927 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
928\r
929 Status = PciIoDevice->PciRootBridgeIo->Unmap (\r
930 PciIoDevice->PciRootBridgeIo,\r
931 Mapping\r
932 );\r
933\r
934 if (EFI_ERROR (Status)) {\r
935 ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
936 }\r
937\r
938 return Status;\r
939}\r
940\r
941EFI_STATUS\r
942EFIAPI\r
943PciIoAllocateBuffer (\r
944 IN EFI_PCI_IO_PROTOCOL *This,\r
945 IN EFI_ALLOCATE_TYPE Type,\r
946 IN EFI_MEMORY_TYPE MemoryType,\r
947 IN UINTN Pages,\r
948 OUT VOID **HostAddress,\r
949 IN UINT64 Attributes\r
950 )\r
951/*++\r
952\r
953Routine Description:\r
954\r
955 Allocates a common buffer for DMA\r
956\r
957Arguments:\r
958\r
959Returns:\r
960\r
961 None\r
962\r
963--*/\r
964// TODO: This - add argument and description to function comment\r
965// TODO: Type - add argument and description to function comment\r
966// TODO: MemoryType - add argument and description to function comment\r
967// TODO: Pages - add argument and description to function comment\r
968// TODO: HostAddress - add argument and description to function comment\r
969// TODO: Attributes - add argument and description to function comment\r
970// TODO: EFI_UNSUPPORTED - add return value to function comment\r
971{\r
972 EFI_STATUS Status;\r
973 PCI_IO_DEVICE *PciIoDevice;\r
974\r
975 if (Attributes &\r
976 (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED))) {\r
977 return EFI_UNSUPPORTED;\r
978 }\r
979\r
980 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
981\r
982 if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {\r
983 Attributes |= EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE;\r
984 }\r
985\r
986 Status = PciIoDevice->PciRootBridgeIo->AllocateBuffer (\r
987 PciIoDevice->PciRootBridgeIo,\r
988 Type,\r
989 MemoryType,\r
990 Pages,\r
991 HostAddress,\r
992 Attributes\r
993 );\r
994\r
995 if (EFI_ERROR (Status)) {\r
996 ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
997 }\r
998\r
999 return Status;\r
1000}\r
1001\r
1002EFI_STATUS\r
1003EFIAPI\r
1004PciIoFreeBuffer (\r
1005 IN EFI_PCI_IO_PROTOCOL *This,\r
1006 IN UINTN Pages,\r
1007 IN VOID *HostAddress\r
1008 )\r
1009/*++\r
1010\r
1011Routine Description:\r
1012\r
1013 Frees a common buffer \r
1014\r
1015Arguments:\r
1016\r
1017Returns:\r
1018\r
1019 None\r
1020\r
1021--*/\r
1022// TODO: This - add argument and description to function comment\r
1023// TODO: Pages - add argument and description to function comment\r
1024// TODO: HostAddress - add argument and description to function comment\r
1025{\r
1026 EFI_STATUS Status;\r
1027 PCI_IO_DEVICE *PciIoDevice;\r
1028\r
1029 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
1030\r
1031 Status = PciIoDevice->PciRootBridgeIo->FreeBuffer (\r
1032 PciIoDevice->PciRootBridgeIo,\r
1033 Pages,\r
1034 HostAddress\r
1035 );\r
1036\r
1037 if (EFI_ERROR (Status)) {\r
1038 ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
1039 }\r
1040\r
1041 return Status;\r
1042}\r
1043\r
1044EFI_STATUS\r
1045EFIAPI\r
1046PciIoFlush (\r
1047 IN EFI_PCI_IO_PROTOCOL *This\r
1048 )\r
1049/*++\r
1050\r
1051Routine Description:\r
1052\r
1053 Flushes a DMA buffer\r
1054\r
1055Arguments:\r
1056\r
1057Returns:\r
1058\r
1059 None\r
1060\r
1061--*/\r
1062// TODO: This - add argument and description to function comment\r
1063{\r
1064 EFI_STATUS Status;\r
1065 PCI_IO_DEVICE *PciIoDevice;\r
1066\r
1067 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
1068\r
1069 Status = PciIoDevice->PciRootBridgeIo->Flush (\r
1070 PciIoDevice->PciRootBridgeIo\r
1071 );\r
1072 if (EFI_ERROR (Status)) {\r
1073 ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
1074 }\r
1075\r
1076 return Status;\r
1077}\r
1078\r
1079EFI_STATUS\r
1080EFIAPI\r
1081PciIoGetLocation (\r
1082 IN EFI_PCI_IO_PROTOCOL *This,\r
1083 OUT UINTN *Segment,\r
1084 OUT UINTN *Bus,\r
1085 OUT UINTN *Device,\r
1086 OUT UINTN *Function\r
1087 )\r
1088/*++\r
1089\r
1090Routine Description:\r
1091\r
1092 Gets a PCI device's current bus number, device number, and function number.\r
1093\r
1094Arguments:\r
1095\r
1096Returns:\r
1097\r
1098 None\r
1099\r
1100--*/\r
1101// TODO: This - add argument and description to function comment\r
1102// TODO: Segment - add argument and description to function comment\r
1103// TODO: Bus - add argument and description to function comment\r
1104// TODO: Device - add argument and description to function comment\r
1105// TODO: Function - add argument and description to function comment\r
1106// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
1107// TODO: EFI_SUCCESS - add return value to function comment\r
1108{\r
1109 PCI_IO_DEVICE *PciIoDevice;\r
1110\r
1111 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
1112\r
1113 if (Segment == NULL || Bus == NULL || Device == NULL || Function == NULL) {\r
1114 return EFI_INVALID_PARAMETER;\r
1115 }\r
1116\r
1117 *Segment = PciIoDevice->PciRootBridgeIo->SegmentNumber;\r
1118 *Bus = PciIoDevice->BusNumber;\r
1119 *Device = PciIoDevice->DeviceNumber;\r
1120 *Function = PciIoDevice->FunctionNumber;\r
1121\r
1122 return EFI_SUCCESS;\r
1123}\r
1124\r
1125BOOLEAN\r
1126CheckBarType (\r
1127 IN PCI_IO_DEVICE *PciIoDevice,\r
1128 UINT8 BarIndex,\r
1129 PCI_BAR_TYPE BarType\r
1130 )\r
1131/*++\r
1132\r
1133Routine Description:\r
1134\r
1135 Sets a PCI controllers attributes on a resource range\r
1136\r
1137Arguments:\r
1138\r
1139Returns:\r
1140\r
1141 None\r
1142\r
1143--*/\r
1144// TODO: PciIoDevice - add argument and description to function comment\r
1145// TODO: BarIndex - add argument and description to function comment\r
1146// TODO: BarType - add argument and description to function comment\r
1147{\r
1148 switch (BarType) {\r
1149\r
1150 case PciBarTypeMem:\r
1151\r
1152 if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem32 &&\r
1153 PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem32 &&\r
1154 PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem64 &&\r
1155 PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem64 ) {\r
1156 return FALSE;\r
1157 }\r
1158\r
1159 return TRUE;\r
1160\r
1161 case PciBarTypeIo:\r
1162 if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo32 &&\r
1163 PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo16){\r
1164 return FALSE;\r
1165 }\r
1166\r
1167 return TRUE;\r
1168\r
1169 default:\r
1170 break;\r
1171 }\r
1172\r
1173 return FALSE;\r
1174}\r
1175\r
1176EFI_STATUS\r
1177ModifyRootBridgeAttributes (\r
1178 IN PCI_IO_DEVICE *PciIoDevice,\r
1179 IN UINT64 Attributes,\r
1180 IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation\r
1181 )\r
1182/*++\r
1183\r
1184Routine Description:\r
1185\r
1186 Set new attributes to a Root Bridge\r
1187\r
1188Arguments:\r
1189\r
1190Returns:\r
1191\r
1192 None\r
1193\r
1194--*/\r
1195// TODO: PciIoDevice - add argument and description to function comment\r
1196// TODO: Attributes - add argument and description to function comment\r
1197// TODO: Operation - add argument and description to function comment\r
1198// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1199// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1200// TODO: EFI_SUCCESS - add return value to function comment\r
1201{\r
1202 UINT64 PciRootBridgeSupports;\r
1203 UINT64 PciRootBridgeAttributes;\r
1204 UINT64 NewPciRootBridgeAttributes;\r
1205 EFI_STATUS Status;\r
1206\r
1207 //\r
1208 // Get the current attributes of this PCI device's PCI Root Bridge\r
1209 //\r
1210 Status = PciIoDevice->PciRootBridgeIo->GetAttributes (\r
1211 PciIoDevice->PciRootBridgeIo,\r
1212 &PciRootBridgeSupports,\r
1213 &PciRootBridgeAttributes\r
1214 );\r
1215 if (EFI_ERROR (Status)) {\r
1216 return EFI_UNSUPPORTED;\r
1217 }\r
1218 \r
1219 //\r
1220 // Record the new attribute of the Root Bridge\r
1221 //\r
1222 if (Operation == EfiPciIoAttributeOperationEnable) {\r
1223 NewPciRootBridgeAttributes = PciRootBridgeAttributes | Attributes;\r
1224 } else {\r
1225 NewPciRootBridgeAttributes = PciRootBridgeAttributes & (~Attributes);\r
1226 }\r
1227 \r
1228 //\r
1229 // Call the PCI Root Bridge to attempt to modify the attributes\r
1230 //\r
1231 if (NewPciRootBridgeAttributes ^ PciRootBridgeAttributes) {\r
1232\r
1233 Status = PciIoDevice->PciRootBridgeIo->SetAttributes (\r
1234 PciIoDevice->PciRootBridgeIo,\r
1235 NewPciRootBridgeAttributes,\r
1236 NULL,\r
1237 NULL\r
1238 );\r
1239 if (EFI_ERROR (Status)) {\r
1240 //\r
1241 // The PCI Root Bridge could not modify the attributes, so return the error.\r
1242 //\r
1243 return EFI_UNSUPPORTED;\r
1244 }\r
1245 }\r
1246 \r
1247 //\r
1248 // Also update the attributes for this Root Bridge structure\r
1249 //\r
1250 PciIoDevice->Attributes = NewPciRootBridgeAttributes;\r
1251 return EFI_SUCCESS;\r
1252\r
1253}\r
1254\r
1255EFI_STATUS\r
1256SupportPaletteSnoopAttributes (\r
1257 IN PCI_IO_DEVICE *PciIoDevice,\r
1258 IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation\r
1259 )\r
1260/*++\r
1261\r
1262Routine Description:\r
1263\r
1264 Check whether this device can be enable/disable to snoop\r
1265\r
1266Arguments:\r
1267\r
1268Returns:\r
1269\r
1270 None\r
1271\r
1272--*/\r
1273// TODO: PciIoDevice - add argument and description to function comment\r
1274// TODO: Operation - add argument and description to function comment\r
1275// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1276// TODO: EFI_SUCCESS - add return value to function comment\r
1277// TODO: EFI_SUCCESS - add return value to function comment\r
1278// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1279// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1280// TODO: EFI_SUCCESS - add return value to function comment\r
1281// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1282// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1283// TODO: EFI_SUCCESS - add return value to function comment\r
1284{\r
1285 PCI_IO_DEVICE *Temp;\r
1286 UINT16 VGACommand;\r
1287\r
1288 //\r
1289 // Snoop attribute can be only modified by GFX\r
1290 //\r
1291 if (!IS_PCI_GFX (&PciIoDevice->Pci)) {\r
1292 return EFI_UNSUPPORTED;\r
1293 }\r
1294\r
1295 //\r
1296 // Get the boot VGA on the same segement\r
1297 //\r
1298 Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);\r
1299\r
1300 if (!Temp) {\r
1301 //\r
1302 // If there is no VGA device on the segement, set\r
1303 // this graphics card to decode the palette range\r
1304 //\r
1305 return EFI_SUCCESS;\r
1306 }\r
1307 \r
1308 //\r
1309 // Check these two agents are on the same path\r
1310 //\r
1311 if (!PciDevicesOnTheSamePath (Temp, PciIoDevice)) {\r
1312 //\r
1313 // they are not on the same path, so snoop can be enabled or disabled\r
1314 //\r
1315 return EFI_SUCCESS;\r
1316 }\r
1317 //\r
1318 // Check if they are on the same bus\r
1319 //\r
1320 if (Temp->Parent == PciIoDevice->Parent) {\r
1321\r
1322 PciReadCommandRegister (Temp, &VGACommand);\r
1323\r
1324 //\r
1325 // If they are on the same bus, either one can\r
1326 // be set to snoop, the other set to decode\r
1327 //\r
1328 if (VGACommand & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {\r
1329 //\r
1330 // VGA has set to snoop, so GFX can be only set to disable snoop\r
1331 //\r
1332 if (Operation == EfiPciIoAttributeOperationEnable) {\r
1333 return EFI_UNSUPPORTED;\r
1334 }\r
1335 } else {\r
1336 //\r
1337 // VGA has disabled to snoop, so GFX can be only enabled\r
1338 //\r
1339 if (Operation == EfiPciIoAttributeOperationDisable) {\r
1340 return EFI_UNSUPPORTED;\r
1341 }\r
1342 }\r
1343\r
1344 return EFI_SUCCESS;\r
1345 }\r
1346 \r
1347 //\r
1348 // If they are on the same path but on the different bus\r
1349 // The first agent is set to snoop, the second one set to\r
1350 // decode\r
1351 //\r
1352 \r
1353 if (Temp->BusNumber > PciIoDevice->BusNumber) {\r
1354 //\r
1355 // GFX should be set to decode\r
1356 //\r
1357 if (Operation == EfiPciIoAttributeOperationDisable) {\r
1358 PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
1359 Temp->Attributes |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
1360 } else {\r
1361 return EFI_UNSUPPORTED;\r
1362 }\r
1363\r
1364 } else {\r
1365 //\r
1366 // GFX should be set to snoop\r
1367 //\r
1368 if (Operation == EfiPciIoAttributeOperationEnable) {\r
1369 PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
1370 Temp->Attributes &= (~EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);\r
1371 } else {\r
1372 return EFI_UNSUPPORTED;\r
1373 }\r
1374\r
1375 }\r
1376\r
1377 return EFI_SUCCESS;\r
1378}\r
1379\r
1380EFI_STATUS\r
1381EFIAPI\r
1382PciIoAttributes (\r
1383 IN EFI_PCI_IO_PROTOCOL * This,\r
1384 IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
1385 IN UINT64 Attributes,\r
1386 OUT UINT64 *Result OPTIONAL\r
1387 )\r
1388/*++\r
1389\r
1390Routine Description:\r
1391\r
1392\r
1393Arguments:\r
1394\r
1395Returns:\r
1396\r
1397 None\r
1398\r
1399--*/\r
1400// TODO: This - add argument and description to function comment\r
1401// TODO: Operation - add argument and description to function comment\r
1402// TODO: Attributes - add argument and description to function comment\r
1403// TODO: Result - add argument and description to function comment\r
1404// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
1405// TODO: EFI_SUCCESS - add return value to function comment\r
1406// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
1407// TODO: EFI_SUCCESS - add return value to function comment\r
1408// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1409// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1410// TODO: EFI_SUCCESS - add return value to function comment\r
1411// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
1412// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1413// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1414// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1415{\r
1416 EFI_STATUS Status;\r
1417\r
1418 PCI_IO_DEVICE *PciIoDevice;\r
1419 PCI_IO_DEVICE *UpStreamBridge;\r
1420 PCI_IO_DEVICE *Temp;\r
1421\r
1422 UINT64 Supports;\r
1423 UINT64 UpStreamAttributes;\r
1424 UINT16 BridgeControl;\r
1425 UINT16 Command;\r
1426\r
1427 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
1428\r
1429 switch (Operation) {\r
1430 case EfiPciIoAttributeOperationGet:\r
1431 if (Result == NULL) {\r
1432 return EFI_INVALID_PARAMETER;\r
1433 }\r
1434\r
1435 *Result = PciIoDevice->Attributes;\r
1436 return EFI_SUCCESS;\r
1437\r
1438 case EfiPciIoAttributeOperationSupported:\r
1439 if (Result == NULL) {\r
1440 return EFI_INVALID_PARAMETER;\r
1441 }\r
1442\r
1443 *Result = PciIoDevice->Supports;\r
1444 return EFI_SUCCESS;\r
1445\r
1446 case EfiPciIoAttributeOperationSet:\r
1447 Status = PciIoDevice->PciIo.Attributes (\r
1448 &(PciIoDevice->PciIo),\r
1449 EfiPciIoAttributeOperationEnable,\r
1450 Attributes,\r
1451 NULL\r
1452 );\r
1453 if (EFI_ERROR (Status)) {\r
1454 return EFI_UNSUPPORTED;\r
1455 }\r
1456\r
1457 Status = PciIoDevice->PciIo.Attributes (\r
1458 &(PciIoDevice->PciIo),\r
1459 EfiPciIoAttributeOperationDisable,\r
1460 (~Attributes) & (PciIoDevice->Supports),\r
1461 NULL\r
1462 );\r
1463 if (EFI_ERROR (Status)) {\r
1464 return EFI_UNSUPPORTED;\r
1465 }\r
1466\r
1467 return EFI_SUCCESS;\r
1468\r
1469 case EfiPciIoAttributeOperationEnable:\r
1470 case EfiPciIoAttributeOperationDisable:\r
1471 break;\r
1472\r
1473 default:\r
1474 return EFI_INVALID_PARAMETER;\r
1475 }\r
1476 //\r
1477 // Just a trick for ENABLE attribute\r
1478 //\r
1479 if ((Attributes & EFI_PCI_DEVICE_ENABLE) == EFI_PCI_DEVICE_ENABLE) {\r
1480 Attributes &= (PciIoDevice->Supports);\r
1481\r
1482 //\r
1483 // Raise the EFI_P_PC_ENABLE Status code\r
1484 //\r
1485 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
1486 EFI_PROGRESS_CODE,\r
1487 EFI_IO_BUS_PCI | EFI_P_PC_ENABLE,\r
1488 PciIoDevice->DevicePath\r
1489 );\r
1490 }\r
1491\r
1492 //\r
1493 // If no attributes can be supported, then return.\r
1494 // Otherwise, set the attributes that it can support.\r
1495 //\r
1496 Supports = (PciIoDevice->Supports) & Attributes;\r
1497 if (Supports != Attributes) {\r
1498 return EFI_UNSUPPORTED;\r
1499 }\r
1500 \r
1501 //\r
1502 // For Root Bridge, just call RootBridgeIo to set attributes;\r
1503 //\r
1504 if (!PciIoDevice->Parent) {\r
1505 Status = ModifyRootBridgeAttributes (PciIoDevice, Attributes, Operation);\r
1506 return Status;\r
1507 }\r
1508\r
1509 Command = 0;\r
1510 BridgeControl = 0;\r
1511\r
1512 //\r
1513 // For PPB & P2C, set relevant attribute bits\r
1514 //\r
1515 if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
1516\r
1517 if (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) {\r
1518 BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA;\r
1519 }\r
1520\r
1521 if (Attributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO) {\r
1522 BridgeControl |= EFI_PCI_BRIDGE_CONTROL_ISA;\r
1523 }\r
1524\r
1525 if (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) {\r
1526 Command |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
1527 }\r
1528\r
1529 } else {\r
1530 //\r
1531 // Do with the attributes on VGA\r
1532 //\r
1533 if ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) || \r
1534 (IS_PCI_VGA(&PciIoDevice->Pci) && \r
1535 ((Attributes & EFI_PCI_IO_ATTRIBUTE_IO) || \r
1536 (Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY)))) {\r
1537 //\r
1538 // Check if a VGA has been enabled before enabling a new one\r
1539 //\r
1540 if (Operation == EfiPciIoAttributeOperationEnable) {\r
1541 //\r
1542 // Check if there have been an active VGA device on the same segment\r
1543 //\r
1544 Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);\r
1545 if (Temp && Temp != PciIoDevice) {\r
1546 //\r
1547 // An active VGA has been detected, so can not enable another\r
1548 //\r
1549 return EFI_UNSUPPORTED;\r
1550 }\r
1551 }\r
1552 }\r
1553 \r
1554 //\r
1555 // Do with the attributes on GFX\r
1556 //\r
1557 if (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) {\r
1558\r
1559 if (Operation == EfiPciIoAttributeOperationEnable) {\r
1560 //\r
1561 // Check if snoop can be enabled in current configuration\r
1562 //\r
1563 Status = SupportPaletteSnoopAttributes (PciIoDevice, Operation);\r
1564\r
1565 if (EFI_ERROR (Status)) {\r
1566 \r
1567 //\r
1568 // Enable operation is forbidden, so mask the bit in attributes\r
1569 // so as to keep consistent with the actual Status\r
1570 //\r
1571 // Attributes &= (~EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO);\r
1572 //\r
1573 //\r
1574 //\r
1575 return EFI_UNSUPPORTED;\r
1576\r
1577 }\r
1578 }\r
1579\r
1580 //\r
1581 // It can be supported, so get ready to set the bit\r
1582 //\r
1583 Command |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;\r
1584 }\r
1585 }\r
1586\r
1587 if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) {\r
1588 Command |= EFI_PCI_COMMAND_IO_SPACE;\r
1589 }\r
1590\r
1591 if (Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) {\r
1592 Command |= EFI_PCI_COMMAND_MEMORY_SPACE;\r
1593 }\r
1594\r
1595 if (Attributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) {\r
1596 Command |= EFI_PCI_COMMAND_BUS_MASTER;\r
1597 }\r
1598 //\r
1599 // The upstream bridge should be also set to revelant attribute\r
1600 // expect for IO, Mem and BusMaster\r
1601 //\r
1602 UpStreamAttributes = Attributes & \r
1603 (~(EFI_PCI_IO_ATTRIBUTE_IO |\r
1604 EFI_PCI_IO_ATTRIBUTE_MEMORY |\r
1605 EFI_PCI_IO_ATTRIBUTE_BUS_MASTER\r
1606 )\r
1607 );\r
1608 UpStreamBridge = PciIoDevice->Parent;\r
1609\r
1610 if (Operation == EfiPciIoAttributeOperationEnable) {\r
1611 //\r
1612 // Enable relevant attributes to command register and bridge control register\r
1613 //\r
1614 Status = PciEnableCommandRegister (PciIoDevice, Command);\r
1615 if (BridgeControl) {\r
1616 Status = PciEnableBridgeControlRegister (PciIoDevice, BridgeControl);\r
1617 }\r
1618\r
1619 PciIoDevice->Attributes |= Attributes;\r
1620\r
1621 //\r
1622 // Enable attributes of the upstream bridge\r
1623 //\r
1624 Status = UpStreamBridge->PciIo.Attributes (\r
1625 &(UpStreamBridge->PciIo),\r
1626 EfiPciIoAttributeOperationEnable,\r
1627 UpStreamAttributes,\r
1628 NULL\r
1629 );\r
1630 } else {\r
1631 \r
1632 //\r
1633 // Disable relevant attributes to command register and bridge control register\r
1634 //\r
1635 Status = PciDisableCommandRegister (PciIoDevice, Command);\r
1636 if (BridgeControl) {\r
1637 Status = PciDisableBridgeControlRegister (PciIoDevice, BridgeControl);\r
1638 }\r
1639\r
1640 PciIoDevice->Attributes &= (~Attributes);\r
1641 Status = EFI_SUCCESS;\r
1642\r
1643 }\r
1644\r
1645 if (EFI_ERROR (Status)) {\r
1646 ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);\r
1647 }\r
1648\r
1649 return Status;\r
1650}\r
1651\r
1652EFI_STATUS\r
1653EFIAPI\r
1654PciIoGetBarAttributes (\r
1655 IN EFI_PCI_IO_PROTOCOL * This,\r
1656 IN UINT8 BarIndex,\r
1657 OUT UINT64 *Supports, OPTIONAL\r
1658 OUT VOID **Resources OPTIONAL\r
1659 )\r
1660/*++\r
1661\r
1662Routine Description:\r
1663\r
1664\r
1665Arguments:\r
1666\r
1667Returns:\r
1668\r
1669 None\r
1670\r
1671--*/\r
1672// TODO: This - add argument and description to function comment\r
1673// TODO: BarIndex - add argument and description to function comment\r
1674// TODO: Supports - add argument and description to function comment\r
1675// TODO: Resources - add argument and description to function comment\r
1676// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
1677// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1678// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
1679// TODO: EFI_SUCCESS - add return value to function comment\r
1680{\r
1681\r
1682 UINT8 *Configuration;\r
1683 UINT8 NumConfig;\r
1684 PCI_IO_DEVICE *PciIoDevice;\r
1685 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
1686 EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;\r
1687\r
1688 NumConfig = 0;\r
1689\r
1690 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
1691\r
1692 if (Supports == NULL && Resources == NULL) {\r
1693 return EFI_INVALID_PARAMETER;\r
1694 }\r
1695\r
1696 if (BarIndex >= PCI_MAX_BAR) {\r
1697 return EFI_UNSUPPORTED;\r
1698 }\r
1699\r
1700 //\r
1701 // This driver does not support modifications to the WRITE_COMBINE or\r
1702 // CACHED attributes for BAR ranges.\r
1703 //\r
1704 if (Supports != NULL) {\r
1705 *Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;\r
1706 }\r
1707\r
1708 if (Resources != NULL) {\r
1709\r
1710 if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeUnknown) {\r
1711 NumConfig = 1;\r
1712 }\r
1713\r
1714 Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
1715 if (Configuration == NULL) {\r
1716 return EFI_OUT_OF_RESOURCES;\r
1717 }\r
1718\r
1719 ZeroMem (\r
1720 Configuration,\r
1721 sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)\r
1722 );\r
1723\r
1724 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
1725\r
1726 if (NumConfig == 1) {\r
1727 Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
1728 Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
1729\r
1730 Ptr->AddrRangeMin = PciIoDevice->PciBar[BarIndex].BaseAddress;\r
1731 Ptr->AddrLen = PciIoDevice->PciBar[BarIndex].Length;\r
1732 Ptr->AddrRangeMax = PciIoDevice->PciBar[BarIndex].Alignment;\r
1733\r
1734 switch (PciIoDevice->PciBar[BarIndex].BarType) {\r
1735 case PciBarTypeIo16:\r
1736 case PciBarTypeIo32:\r
1737 //\r
1738 // Io\r
1739 //\r
1740 Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;\r
1741 break;\r
1742\r
1743 case PciBarTypeMem32:\r
1744 //\r
1745 // Mem\r
1746 //\r
1747 Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
1748 //\r
1749 // 32 bit\r
1750 //\r
1751 Ptr->AddrSpaceGranularity = 32;\r
1752 break;\r
1753\r
1754 case PciBarTypePMem32:\r
1755 //\r
1756 // Mem\r
1757 //\r
1758 Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
1759 //\r
1760 // prefechable\r
1761 //\r
1762 Ptr->SpecificFlag = 0x6;\r
1763 //\r
1764 // 32 bit\r
1765 //\r
1766 Ptr->AddrSpaceGranularity = 32;\r
1767 break;\r
1768\r
1769 case PciBarTypeMem64:\r
1770 //\r
1771 // Mem\r
1772 //\r
1773 Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
1774 //\r
1775 // 64 bit\r
1776 //\r
1777 Ptr->AddrSpaceGranularity = 64;\r
1778 break;\r
1779\r
1780 case PciBarTypePMem64:\r
1781 //\r
1782 // Mem\r
1783 //\r
1784 Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
1785 //\r
1786 // prefechable\r
1787 //\r
1788 Ptr->SpecificFlag = 0x6;\r
1789 //\r
1790 // 64 bit\r
1791 //\r
1792 Ptr->AddrSpaceGranularity = 64;\r
1793 break;\r
1794\r
1795 default:\r
1796 break;\r
1797 }\r
1798\r
1799 Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));\r
1800 }\r
1801 \r
1802 //\r
1803 // put the checksum\r
1804 //\r
1805 PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);\r
1806 PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR;\r
1807 PtrEnd->Checksum = 0;\r
1808\r
1809 *Resources = Configuration;\r
1810 }\r
1811\r
1812 return EFI_SUCCESS;\r
1813}\r
1814\r
1815EFI_STATUS\r
1816EFIAPI\r
1817PciIoSetBarAttributes (\r
1818 IN EFI_PCI_IO_PROTOCOL *This,\r
1819 IN UINT64 Attributes,\r
1820 IN UINT8 BarIndex,\r
1821 IN OUT UINT64 *Offset,\r
1822 IN OUT UINT64 *Length\r
1823 )\r
1824/*++\r
1825\r
1826Routine Description:\r
1827\r
1828\r
1829Arguments:\r
1830\r
1831Returns:\r
1832\r
1833 None\r
1834\r
1835--*/\r
1836// TODO: This - add argument and description to function comment\r
1837// TODO: Attributes - add argument and description to function comment\r
1838// TODO: BarIndex - add argument and description to function comment\r
1839// TODO: Offset - add argument and description to function comment\r
1840// TODO: Length - add argument and description to function comment\r
1841// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
1842// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1843// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1844// TODO: EFI_UNSUPPORTED - add return value to function comment\r
1845// TODO: EFI_SUCCESS - add return value to function comment\r
1846{\r
1847 EFI_STATUS Status;\r
1848 PCI_IO_DEVICE *PciIoDevice;\r
1849 UINT64 NonRelativeOffset;\r
1850 UINT64 Supports;\r
1851\r
1852 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
1853\r
1854 //\r
1855 // Make sure Offset and Length are not NULL\r
1856 //\r
1857 if (Offset == NULL || Length == NULL) {\r
1858 return EFI_INVALID_PARAMETER;\r
1859 }\r
1860\r
1861 if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeUnknown) {\r
1862 return EFI_UNSUPPORTED;\r
1863 }\r
1864 //\r
1865 // This driver does not support setting the WRITE_COMBINE or the CACHED attributes.\r
1866 // If Attributes is not 0, then return EFI_UNSUPPORTED.\r
1867 //\r
1868 Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;\r
1869\r
1870 if (Attributes != (Attributes & Supports)) {\r
1871 return EFI_UNSUPPORTED;\r
1872 }\r
1873 //\r
1874 // Attributes must be supported. Make sure the BAR range describd by BarIndex, Offset, and\r
1875 // Length are valid for this PCI device.\r
1876 //\r
1877 NonRelativeOffset = *Offset;\r
1878 Status = PciIoVerifyBarAccess (\r
1879 PciIoDevice,\r
1880 BarIndex,\r
1881 PciBarTypeMem,\r
1882 EfiPciIoWidthUint8,\r
1883 (UINT32) *Length,\r
1884 &NonRelativeOffset\r
1885 );\r
1886 if (EFI_ERROR (Status)) {\r
1887 return EFI_UNSUPPORTED;\r
1888 }\r
1889\r
1890 return EFI_SUCCESS;\r
1891}\r
1892\r
1893EFI_STATUS\r
1894UpStreamBridgesAttributes (\r
1895 IN PCI_IO_DEVICE *PciIoDevice,\r
1896 IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
1897 IN UINT64 Attributes\r
1898 )\r
1899/*++\r
1900\r
1901Routine Description:\r
1902\r
1903Arguments:\r
1904\r
1905Returns:\r
1906\r
1907 None\r
1908\r
1909--*/\r
1910// TODO: PciIoDevice - add argument and description to function comment\r
1911// TODO: Operation - add argument and description to function comment\r
1912// TODO: Attributes - add argument and description to function comment\r
1913// TODO: EFI_SUCCESS - add return value to function comment\r
1914{\r
1915 PCI_IO_DEVICE *Parent;\r
1916 EFI_PCI_IO_PROTOCOL *PciIo;\r
1917\r
1918 Parent = PciIoDevice->Parent;\r
1919\r
1920 while (Parent && IS_PCI_BRIDGE (&Parent->Pci)) {\r
1921\r
1922 //\r
1923 // Get the PciIo Protocol\r
1924 //\r
1925 PciIo = &Parent->PciIo;\r
1926\r
1927 PciIo->Attributes (PciIo, Operation, Attributes, NULL);\r
1928\r
1929 Parent = Parent->Parent;\r
1930 }\r
1931\r
1932 return EFI_SUCCESS;\r
1933}\r
1934\r
1935BOOLEAN\r
1936PciDevicesOnTheSamePath (\r
1937 IN PCI_IO_DEVICE *PciDevice1,\r
1938 IN PCI_IO_DEVICE *PciDevice2\r
1939 )\r
1940/*++\r
1941\r
1942Routine Description:\r
1943\r
1944Arguments:\r
1945\r
1946Returns:\r
1947\r
1948 None\r
1949\r
1950--*/\r
1951// TODO: PciDevice1 - add argument and description to function comment\r
1952// TODO: PciDevice2 - add argument and description to function comment\r
1953{\r
1954\r
1955 if (PciDevice1->Parent == PciDevice2->Parent) {\r
1956 return TRUE;\r
1957 }\r
1958\r
1959 if (PciDevice1->BusNumber > PciDevice2->BusNumber) {\r
1960 return PciDeviceExisted (PciDevice1->Parent, PciDevice2);\r
1961 }\r
1962\r
1963 return PciDeviceExisted (PciDevice2->Parent, PciDevice1);\r
1964}\r