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