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