8fbd45d3ec1bf4e929f7eb897c2508bc5b47d34a
[efi/shell/.git] / pci / pci.c
1 /*++
2
3 Copyright (c) 2005 - 2009, Intel Corporation                                                         
4 All rights reserved. This program and the accompanying materials                          
5 are licensed and made available under the terms and conditions of the BSD License         
6 which accompanies this distribution. The full text of the license may be found at         
7 http://opensource.org/licenses/bsd-license.php                                            
8                                                                                           
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
11
12 Module Name:
13
14   pci.c
15   
16 Abstract: 
17   EFI shell command "pci"
18
19 Revision History
20
21 --*/
22
23 #include "EfiShellLib.h"
24 #include "pci22.h"
25 #include "pci_class.h"
26 #include "pci.h"
27 #include "Acpi.h"
28
29 extern UINT8      STRING_ARRAY_NAME[];
30
31 //
32 // This is the generated header file which includes whatever needs to be exported (strings + IFR)
33 //
34 #include STRING_DEFINES_FILE
35
36 #include EFI_PROTOCOL_DEFINITION (PciRootBridgeIo)
37
38 EFI_STATUS
39 PciDump (
40   IN EFI_HANDLE                             ImageHandle,
41   IN EFI_SYSTEM_TABLE                       *SystemTable
42   );
43
44 EFI_STATUS
45 PciFindProtocolInterface (
46   IN  EFI_HANDLE                            *HandleBuf,
47   IN  UINTN                                 HandleCount,
48   IN  UINT16                                Segment,
49   IN  UINT16                                Bus,
50   OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       **IoDev
51   );
52
53 EFI_STATUS
54 PciGetProtocolAndResource (
55   IN  EFI_HANDLE                            Handle,
56   OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       **IoDev,
57   OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     **Descriptors
58   );
59
60 EFI_STATUS
61 PciGetNextBusRange (
62   IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  **Descriptors,
63   OUT    UINT16                             *MinBus,
64   OUT    UINT16                             *MaxBus,
65   OUT    BOOLEAN                            *IsEnd
66   );
67
68 EFI_STATUS
69 PciExplainData (
70   IN PCI_CONFIG_SPACE                       *ConfigSpace,
71   IN UINT64                                 Address,
72   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev
73   );
74
75 EFI_STATUS
76 PciExplainDeviceData (
77   IN PCI_DEVICE_HEADER                      *Device,
78   IN UINT64                                 Address,
79   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev
80   );
81
82 EFI_STATUS
83 PciExplainBridgeData (
84   IN PCI_BRIDGE_HEADER                      *Bridge,
85   IN UINT64                                 Address,
86   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev
87   );
88
89 EFI_STATUS
90 PciExplainBar (
91   IN UINT32                                 *Bar,
92   IN UINT16                                 *Command,
93   IN UINT64                                 Address,
94   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev,
95   IN OUT UINTN                              *Index
96   );
97
98 EFI_STATUS
99 PciExplainCardBusData (
100   IN PCI_CARDBUS_HEADER                     *CardBus,
101   IN UINT64                                 Address,
102   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev
103   );
104
105 EFI_STATUS
106 PciExplainStatus (
107   IN UINT16                                 *Status,
108   IN BOOLEAN                                MainStatus,
109   IN PCI_HEADER_TYPE                        HeaderType
110   );
111
112 EFI_STATUS
113 PciExplainCommand (
114   IN UINT16                                 *Command
115   );
116
117 EFI_STATUS
118 PciExplainBridgeControl (
119   IN UINT16                                 *BridgeControl,
120   IN PCI_HEADER_TYPE                        HeaderType
121   );
122
123 EFI_STATUS
124 PciExplainCapabilityStruct (
125   IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         *IoDev,
126   IN UINT64                                   Address,
127   IN  UINT8                                   CapPtr
128   );
129
130 EFI_STATUS
131 PciExplainPciExpress (
132   IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         *IoDev,
133   IN  UINT64                                  Address,
134   IN  UINT8                                   CapabilityPtr
135   );
136
137 EFI_STATUS
138 ExplainPcieCapReg (
139   IN PCIE_CAP_STURCTURE *PciExpressCap
140 );
141
142 EFI_STATUS
143 ExplainPcieDeviceCap (
144   IN PCIE_CAP_STURCTURE *PciExpressCap
145 );
146
147 EFI_STATUS
148 ExplainPcieDeviceControl (
149   IN PCIE_CAP_STURCTURE *PciExpressCap
150 );
151
152 EFI_STATUS
153 ExplainPcieDeviceStatus (
154   IN PCIE_CAP_STURCTURE *PciExpressCap
155 );
156
157 EFI_STATUS
158 ExplainPcieLinkCap (
159   IN PCIE_CAP_STURCTURE *PciExpressCap
160 );
161
162 EFI_STATUS
163 ExplainPcieLinkControl (
164   IN PCIE_CAP_STURCTURE *PciExpressCap
165 );
166
167 EFI_STATUS
168 ExplainPcieLinkStatus (
169   IN PCIE_CAP_STURCTURE *PciExpressCap
170 );
171
172 EFI_STATUS
173 ExplainPcieSlotCap (
174   IN PCIE_CAP_STURCTURE *PciExpressCap
175 );
176
177 EFI_STATUS
178 ExplainPcieSlotControl (
179   IN PCIE_CAP_STURCTURE *PciExpressCap
180 );
181
182 EFI_STATUS
183 ExplainPcieSlotStatus (
184   IN PCIE_CAP_STURCTURE *PciExpressCap
185 );
186
187 EFI_STATUS
188 ExplainPcieRootControl (
189   IN PCIE_CAP_STURCTURE *PciExpressCap
190 );
191
192 EFI_STATUS
193 ExplainPcieRootCap (
194   IN PCIE_CAP_STURCTURE *PciExpressCap
195 );
196
197 EFI_STATUS
198 ExplainPcieRootStatus (
199   IN PCIE_CAP_STURCTURE *PciExpressCap
200 );
201
202 typedef EFI_STATUS (*PCIE_EXPLAIN_FUNCTION) (IN PCIE_CAP_STURCTURE *PciExpressCap);
203
204 typedef enum {
205   FieldWidthUINT8,
206   FieldWidthUINT16,
207   FieldWidthUINT32
208 } PCIE_CAPREG_FIELD_WIDTH;
209
210 typedef enum {
211   PcieExplainTypeCommon,
212   PcieExplainTypeDevice,
213   PcieExplainTypeLink,
214   PcieExplainTypeSlot,
215   PcieExplainTypeRoot,
216   PcieExplainTypeMax
217 } PCIE_EXPLAIN_TYPE;
218
219 typedef struct
220 {
221   UINT16                  Token;
222   UINTN                   Offset;
223   PCIE_CAPREG_FIELD_WIDTH Width;
224   PCIE_EXPLAIN_FUNCTION   Func;
225   PCIE_EXPLAIN_TYPE       Type;
226 } PCIE_EXPLAIN_STRUCT;
227
228 PCIE_EXPLAIN_STRUCT PcieExplainList[] = {
229   {
230     STRING_TOKEN (STR_PCIEX_CAPABILITY_CAPID),
231     0x00,
232     FieldWidthUINT8,
233     NULL,
234     PcieExplainTypeCommon
235   },
236   {
237     STRING_TOKEN (STR_PCIEX_NEXTCAP_PTR),
238     0x01,
239     FieldWidthUINT8,
240     NULL,
241     PcieExplainTypeCommon
242   },
243   {
244     STRING_TOKEN (STR_PCIEX_CAP_REGISTER),
245     0x02,
246     FieldWidthUINT16,
247     ExplainPcieCapReg,
248     PcieExplainTypeCommon
249   },
250   {
251     STRING_TOKEN (STR_PCIEX_DEVICE_CAP),
252     0x04,
253     FieldWidthUINT32,
254     ExplainPcieDeviceCap,
255     PcieExplainTypeDevice
256   },
257   {
258     STRING_TOKEN (STR_PCIEX_DEVICE_CONTROL),
259     0x08,
260     FieldWidthUINT16,
261     ExplainPcieDeviceControl,
262     PcieExplainTypeDevice
263   },
264   {
265     STRING_TOKEN (STR_PCIEX_DEVICE_STATUS),
266     0x0a,
267     FieldWidthUINT16,
268     ExplainPcieDeviceStatus,
269     PcieExplainTypeDevice
270   },
271   {
272     STRING_TOKEN (STR_PCIEX_LINK_CAPABILITIES),
273     0x0c,
274     FieldWidthUINT32,
275     ExplainPcieLinkCap,
276     PcieExplainTypeLink
277   },
278   {
279     STRING_TOKEN (STR_PCIEX_LINK_CONTROL),
280     0x10,
281     FieldWidthUINT16,
282     ExplainPcieLinkControl,
283     PcieExplainTypeLink
284   },
285   {
286     STRING_TOKEN (STR_PCIEX_LINK_STATUS),
287     0x12,
288     FieldWidthUINT16,
289     ExplainPcieLinkStatus,
290     PcieExplainTypeLink
291   },
292   {
293     STRING_TOKEN (STR_PCIEX_SLOT_CAPABILITIES),
294     0x14,
295     FieldWidthUINT32,
296     ExplainPcieSlotCap,
297     PcieExplainTypeSlot
298   },
299   {
300     STRING_TOKEN (STR_PCIEX_SLOT_CONTROL),
301     0x18,
302     FieldWidthUINT16,
303     ExplainPcieSlotControl,
304     PcieExplainTypeSlot
305   },
306   {
307     STRING_TOKEN (STR_PCIEX_SLOT_STATUS),
308     0x1a,
309     FieldWidthUINT16,
310     ExplainPcieSlotStatus,
311     PcieExplainTypeSlot
312   },
313   {
314     STRING_TOKEN (STR_PCIEX_ROOT_CONTROL),
315     0x1c,
316     FieldWidthUINT16,
317     ExplainPcieRootControl,
318     PcieExplainTypeRoot
319   },
320   {
321     STRING_TOKEN (STR_PCIEX_RSVDP),
322     0x1e,
323     FieldWidthUINT16,
324     ExplainPcieRootCap,
325     PcieExplainTypeRoot
326   },
327   {
328     STRING_TOKEN (STR_PCIEX_ROOT_STATUS),
329     0x20,
330     FieldWidthUINT32,
331     ExplainPcieRootStatus,
332     PcieExplainTypeRoot
333   },
334   {
335     0,
336     0,
337     0,
338     NULL,
339     PcieExplainTypeMax
340   }
341 };
342
343 //
344 // Global Variables
345 //
346 PCI_CONFIG_SPACE  *mConfigSpace;
347 EFI_HII_HANDLE    HiiHandle;
348 EFI_GUID          EfiPciGuid = EFI_PCI_GUID;
349 SHELL_VAR_CHECK_ITEM    PciCheckList[] = {
350   {
351     L"-s",
352     0x01,
353     0,
354     FlagTypeNeedVar
355   },
356   {
357     L"-i",
358     0x02,
359     0,
360     FlagTypeSingle
361   },
362   {
363     L"-b",
364     0x04,
365     0,
366     FlagTypeSingle
367   },
368   {
369     L"-?",
370     0x08,
371     0,
372     FlagTypeSingle
373   },
374   {
375     NULL,
376     0,
377     0,
378     0
379   }
380 };
381
382 CHAR16 *DevicePortTypeTable[] = {
383   L"PCI Express Endpoint",
384   L"Legacy PCI Express Endpoint",
385   L"Unknown Type",
386   L"Unknonw Type",
387   L"Root Port of PCI Express Root Complex",
388   L"Upstream Port of PCI Express Switch",
389   L"Downstream Port of PCI Express Switch",
390   L"PCI Express to PCI/PCI-X Bridge",
391   L"PCI/PCI-X to PCI Express Bridge",
392   L"Root Complex Integrated Endpoint",
393   L"Root Complex Event Collector"
394 };
395
396 CHAR16 *L0sLatencyStrTable[] = {
397   L"Less than 64ns",
398   L"64ns to less than 128ns",
399   L"128ns to less than 256ns",
400   L"256ns to less than 512ns",
401   L"512ns to less than 1us",
402   L"1us to less than 2us",
403   L"2us-4us",
404   L"More than 4us"
405 };
406
407 CHAR16 *L1LatencyStrTable[] = {
408   L"Less than 1us",
409   L"1us to less than 2us",
410   L"2us to less than 4us",
411   L"4us to less than 8us",
412   L"8us to less than 16us",
413   L"16us to less than 32us",
414   L"32us-64us",
415   L"More than 64us"
416 };
417
418 CHAR16 *ASPMCtrlStrTable[] = {
419   L"Disabled",
420   L"L0s Entry Enabled",
421   L"L1 Entry Enabled",
422   L"L0s and L1 Entry Enabled"
423 };
424
425 CHAR16 *SlotPwrLmtScaleTable[] = {
426   L"1.0x",
427   L"0.1x",
428   L"0.01x",
429   L"0.001x"
430 };
431
432 CHAR16 *IndicatorTable[] = {
433   L"Reserved",
434   L"On",
435   L"Blink",
436   L"Off"
437 };
438
439 EFI_BOOTSHELL_CODE(
440   EFI_APPLICATION_ENTRY_POINT(PciDump)
441 )
442
443 EFI_STATUS
444 PciDump (
445   IN EFI_HANDLE                             ImageHandle,
446   IN EFI_SYSTEM_TABLE                       *SystemTable
447   )
448 /*++
449
450 Routine Description:
451
452   Command entry point. Parses command line arguments and execute it. If 
453   needed, calls internal function to perform certain operation.
454
455 Arguments:
456
457   ImageHandle     The image handle.
458   SystemTable     The system table.
459
460 Returns:
461
462   EFI_SUCCESS           - The command completed successfully
463   EFI_INVALID_PARAMETER - Invalid parameter
464   EFI_OUT_OF_RESOURCES  - Out of resources
465
466 --*/
467 {
468   UINT16                            Segment;
469   UINT16                            Bus;
470   UINT16                            Device;
471   UINT16                            Func;
472   UINT64                            Address;
473   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL   *IoDev;
474   EFI_STATUS                        Status;
475   PCI_COMMON_HEADER                 PciHeader;
476   PCI_CONFIG_SPACE                  ConfigSpace;
477   UINTN                             ScreenCount;
478   UINTN                             TempColumn;
479   UINTN                             ScreenSize;
480   BOOLEAN                           ExplainData;
481   UINTN                             Index;
482   UINTN                             SizeOfHeader;
483   BOOLEAN                           PrintTitle;
484   UINTN                             HandleBufSize;
485   EFI_HANDLE                        *HandleBuf;
486   UINTN                             HandleCount;
487   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
488   UINT16                            MinBus;
489   UINT16                            MaxBus;
490   BOOLEAN                           IsEnd;
491
492   SHELL_VAR_CHECK_CODE              RetCode;
493   CHAR16                            *Useful;
494   SHELL_ARG_LIST                    *Item;
495   SHELL_VAR_CHECK_PACKAGE           ChkPck;
496
497   IoDev = NULL;
498   HandleBuf = NULL;
499   ZeroMem (&ChkPck, sizeof (SHELL_VAR_CHECK_PACKAGE));
500   EFI_SHELL_APP_INIT (ImageHandle, SystemTable);
501   
502   //
503   // Enable tab key which can pause the output
504   //
505   EnableOutputTabPause();
506
507   Status = LibInitializeStrings (&HiiHandle, STRING_ARRAY_NAME, &EfiPciGuid);
508
509   if (EFI_ERROR (Status)) {
510     return Status;
511   }
512
513   if (!EFI_PROPER_VERSION (0, 99)) {
514     PrintToken (
515       STRING_TOKEN (STR_SHELLENV_GNC_COMMAND_NOT_SUPPORT),
516       HiiHandle,
517       L"pci",
518       EFI_VERSION_0_99 
519       );
520     Status = EFI_UNSUPPORTED;
521     goto Done;
522   }
523
524   RetCode = LibCheckVariables (SI, PciCheckList, &ChkPck, &Useful);
525   if (VarCheckOk != RetCode) {
526     switch (RetCode) {
527     case VarCheckUnknown:
528       PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_UNKNOWN_FLAG), HiiHandle, L"pci", Useful);
529       break;
530
531     case VarCheckDuplicate:
532       PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_DUP_FLAG), HiiHandle, L"pci", Useful);
533       break;
534
535     case VarCheckLackValue:
536       PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_LACK_ARG), HiiHandle, L"pci", Useful);
537       break;
538
539     default:
540       break;
541     }
542
543     Status = EFI_INVALID_PARAMETER;
544     goto Done;
545   }
546   //
547   // Out put help.
548   //
549   if (LibCheckVarGetFlag (&ChkPck, L"-b") != NULL) {
550     EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF);
551   }
552
553   if (LibCheckVarGetFlag (&ChkPck, L"-?") != NULL) {
554     if (ChkPck.ValueCount > 0 ||
555         ChkPck.FlagCount > 2 ||
556         (2 == ChkPck.FlagCount && !LibCheckVarGetFlag (&ChkPck, L"-b"))
557         ) {
558       PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_MANY), HiiHandle, L"pci");
559       Status = EFI_INVALID_PARAMETER;
560     } else {
561       PrintToken (STRING_TOKEN (STR_HELPINFO_PCI_VERBOSEHELP), HiiHandle);
562       Status = EFI_SUCCESS;
563     }
564
565     goto Done;
566   }
567   //
568   // Get all instances of PciRootBridgeIo. Allocate space for 1 EFI_HANDLE and
569   // call LibLocateHandle(), if EFI_BUFFER_TOO_SMALL is returned, allocate enough
570   // space for handles and call it again.
571   //
572   HandleBufSize = sizeof (EFI_HANDLE);
573   HandleBuf     = (EFI_HANDLE *) AllocatePool (HandleBufSize);
574   if (HandleBuf == NULL) {
575     PrintToken (STRING_TOKEN (STR_PCI2_OUT_RESOURCES), HiiHandle);
576     Status = EFI_OUT_OF_RESOURCES;
577     goto Done;
578   }
579
580   Status = BS->LocateHandle (
581                 ByProtocol,
582                 &gEfiPciRootBridgeIoProtocolGuid,
583                 NULL,
584                 &HandleBufSize,
585                 HandleBuf
586                 );
587
588   if (Status == EFI_BUFFER_TOO_SMALL) {
589     HandleBuf = ReallocatePool (HandleBuf, sizeof (EFI_HANDLE), HandleBufSize);
590     if (HandleBuf == NULL) {
591       PrintToken (STRING_TOKEN (STR_PCI2_OUT_RESOURCES), HiiHandle);
592       Status = EFI_OUT_OF_RESOURCES;
593       goto Done;
594     }
595
596     Status = BS->LocateHandle (
597                   ByProtocol,
598                   &gEfiPciRootBridgeIoProtocolGuid,
599                   NULL,
600                   &HandleBufSize,
601                   HandleBuf
602                   );
603   }
604
605   if (EFI_ERROR (Status)) {
606     PrintToken (STRING_TOKEN (STR_PCI2_LOCATE_HANDLE), HiiHandle, Status);
607     goto Done;
608   }
609
610   HandleCount = HandleBufSize / sizeof (EFI_HANDLE);
611   //
612   // Argument Count == 1(no other argument): enumerate all pci functions
613   //
614   if (ChkPck.ValueCount == 0) {
615     ST->ConOut->QueryMode (
616                   ST->ConOut,
617                   ST->ConOut->Mode->Mode,
618                   &TempColumn,
619                   &ScreenSize
620                   );
621
622     ScreenCount = 0;
623     ScreenSize -= 4;
624     if ((ScreenSize & 1) == 1) {
625       ScreenSize -= 1;
626     }
627
628     PrintTitle = TRUE;
629
630     //
631     // For each handle, which decides a segment and a bus number range,
632     // enumerate all devices on it.
633     //
634     for (Index = 0; Index < HandleCount; Index++) {
635       Status = PciGetProtocolAndResource (
636                 HandleBuf[Index],
637                 &IoDev,
638                 &Descriptors
639                 );
640       if (EFI_ERROR (Status)) {
641         PrintToken (STRING_TOKEN (STR_PCI2_HANDLE_PROTOCOL), HiiHandle, Status);
642         goto Done;
643       }
644       //
645       // No document say it's impossible for a RootBridgeIo protocol handle
646       // to have more than one address space descriptors, so find out every
647       // bus range and for each of them do device enumeration.
648       //
649       while (TRUE) {
650         Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd);
651
652         if (EFI_ERROR (Status)) {
653           PrintToken (STRING_TOKEN (STR_PCI2_BUS), HiiHandle, Status);
654           goto Done;
655         }
656
657         if (IsEnd) {
658           break;
659         }
660
661         for (Bus = MinBus; Bus <= MaxBus; Bus++) {
662           //
663           // For each devices, enumerate all functions it contains
664           //
665           for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
666             //
667             // For each function, read its configuration space and print summary
668             //
669             for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
670               if (GetExecutionBreak ()) {
671                 Status = EFI_SUCCESS;
672                 goto Done;
673               }
674               Address = CALC_EFI_PCI_ADDRESS (Bus, Device, Func, 0);
675               IoDev->Pci.Read (
676                           IoDev,
677                           EfiPciWidthUint16,
678                           Address,
679                           1,
680                           &PciHeader.VendorId
681                           );
682
683               //
684               // If VendorId = 0xffff, there does not exist a device at this
685               // location. For each device, if there is any function on it,
686               // there must be 1 function at Function 0. So if Func = 0, there
687               // will be no more functions in the same device, so we can break
688               // loop to deal with the next device.
689               //
690               if (PciHeader.VendorId == 0xffff && Func == 0) {
691                 break;
692               }
693
694               if (PciHeader.VendorId != 0xffff) {
695
696                 if (PrintTitle) {
697                   PrintToken (STRING_TOKEN (STR_PCI2_SEG_BUS), HiiHandle);
698                   Print (L"   ---  ---  ---  ----\n");
699                   PrintTitle = FALSE;
700                 }
701
702                 IoDev->Pci.Read (
703                             IoDev,
704                             EfiPciWidthUint32,
705                             Address,
706                             sizeof (PciHeader) / sizeof (UINT32),
707                             &PciHeader
708                             );
709
710                 PrintToken (
711                   STRING_TOKEN (STR_PCI2_FOUR_VARS),
712                   HiiHandle,
713                   IoDev->SegmentNumber,
714                   Bus,
715                   Device,
716                   Func
717                   );
718
719                 PciPrintClassCode (PciHeader.ClassCode, FALSE);
720                 PrintToken (
721                   STRING_TOKEN (STR_PCI2_VENDOR),
722                   HiiHandle,
723                   PciHeader.VendorId,
724                   PciHeader.DeviceId,
725                   PciHeader.ClassCode[0]
726                   );
727
728                 ScreenCount += 2;
729                 if (ScreenCount >= ScreenSize && ScreenSize != 0) {
730                   //
731                   // If ScreenSize == 0 we have the console redirected so don't
732                   //  block updates
733                   //
734                   ScreenCount = 0;
735                 }
736                 //
737                 // If this is not a multi-function device, we can leave the loop
738                 // to deal with the next device.
739                 //
740                 if (Func == 0 && ((PciHeader.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00)) {
741                   break;
742                 }
743               }
744             }
745           }
746         }
747         //
748         // If Descriptor is NULL, Configuration() returns EFI_UNSUPPRORED,
749         // we assume the bus range is 0~PCI_MAX_BUS. After enumerated all
750         // devices on all bus, we can leave loop.
751         //
752         if (Descriptors == NULL) {
753           break;
754         }
755       }
756     }
757
758     Status = EFI_SUCCESS;
759     goto Done;
760   }
761
762   if (ChkPck.ValueCount == 1) {
763     PrintToken (STRING_TOKEN (STR_PCI2_TOO_FEW_ARGS), HiiHandle);
764     Status = EFI_INVALID_PARAMETER;
765     goto Done;
766   }
767   //
768   // Arg count >= 3, dump binary of specified function, interpret if necessary
769   //
770   if (ChkPck.ValueCount > 3) {
771     PrintToken (STRING_TOKEN (STR_PCI2_TOO_MANY_ARGS), HiiHandle);
772     Status = EFI_INVALID_PARAMETER;
773     goto Done;
774   }
775
776   ExplainData                   = FALSE;
777   Segment                       = 0;
778   Bus                           = 0;
779   Device                        = 0;
780   Func                          = 0;
781   if (LibCheckVarGetFlag (&ChkPck, L"-i") != NULL) {
782     ExplainData = TRUE;
783   }
784
785   Item = LibCheckVarGetFlag (&ChkPck, L"-s");
786   if (NULL != Item) {
787     Segment = (UINT16) StrToUIntegerBase (Item->VarStr, 16, &Status);
788     if (EFI_ERROR (Status)) {
789       PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, L"pci", Item->VarStr);
790       Status = EFI_INVALID_PARAMETER;
791       goto Done;
792     }
793   }
794
795   //
796   // The first Argument(except "-i") is assumed to be Bus number, second
797   // to be Device number, and third to be Func number.
798   //
799   Item = ChkPck.VarList;
800   if (NULL != Item) {
801     Bus = (UINT16) StrToUIntegerBase (Item->VarStr, 16, &Status);
802     if (EFI_ERROR (Status) || Bus > MAX_BUS_NUMBER) {
803       PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, L"pci", Item->VarStr);
804       Status = EFI_INVALID_PARAMETER;
805       goto Done;
806     }
807
808     Item = Item->Next;
809   }
810
811   if (NULL != Item) {
812     Device = (UINT16) StrToUIntegerBase (Item->VarStr, 16, &Status);
813     if (EFI_ERROR (Status) || Device > MAX_DEVICE_NUMBER) {
814       PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, L"pci", Item->VarStr);
815       Status = EFI_INVALID_PARAMETER;
816       goto Done;
817     }
818
819     Item = Item->Next;
820   }
821
822   if (NULL != Item) {
823     Func = (UINT16) StrToUIntegerBase (Item->VarStr, 16, &Status);
824     if (EFI_ERROR (Status) || Func > MAX_FUNCTION_NUMBER) {
825       PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, L"pci", Item->VarStr);
826       Status = EFI_INVALID_PARAMETER;
827       goto Done;
828     }
829   }
830
831
832   //
833   // Find the protocol interface who's in charge of current segment, and its
834   // bus range covers the current bus
835   //
836   Status = PciFindProtocolInterface (
837             HandleBuf,
838             HandleCount,
839             Segment,
840             Bus,
841             &IoDev
842             );
843
844   if (EFI_ERROR (Status)) {
845     PrintToken (
846       STRING_TOKEN (STR_PCI2_CANNOT_FIND_PROTOCOL),
847       HiiHandle,
848       Segment,
849       Bus
850       );
851
852     goto Done;
853   }
854
855   Address = CALC_EFI_PCI_ADDRESS (Bus, Device, Func, 0);
856   Status = IoDev->Pci.Read (
857                         IoDev,
858                         EfiPciWidthUint8,
859                         Address,
860                         sizeof (ConfigSpace),
861                         &ConfigSpace
862                         );
863
864   if (EFI_ERROR (Status)) {
865     PrintToken (STRING_TOKEN (STR_PCI2_CANNOT_READ_CONFIG), HiiHandle, Status);
866     goto Done;
867   }
868
869   mConfigSpace = &ConfigSpace;
870   PrintToken (
871     STRING_TOKEN (STR_PCI2_SEGMENT_BUS),
872     HiiHandle,
873     Segment,
874     Bus,
875     Device,
876     Func,
877     Segment,
878     Bus,
879     Device,
880     Func
881     );
882
883   //
884   // Dump standard header of configuration space
885   //
886   SizeOfHeader = sizeof (ConfigSpace.Common) + sizeof (ConfigSpace.NonCommon);
887
888   PrivateDumpHex (2, 0, SizeOfHeader, &ConfigSpace);
889   Print (L"\n");
890
891   //
892   // Dump device dependent Part of configuration space
893   //
894   PrivateDumpHex (
895     2,
896     SizeOfHeader,
897     sizeof (ConfigSpace) - SizeOfHeader,
898     ConfigSpace.Data
899     );
900
901   //
902   // If "-i" appears in command line, interpret data in configuration space
903   //
904   if (ExplainData) {
905     Status = PciExplainData (&ConfigSpace, Address, IoDev);
906   }
907 Done:
908   if (HandleBuf != NULL) {
909     FreePool (HandleBuf);
910   }
911   LibCheckVarFreeVarList (&ChkPck);
912   LibUnInitializeStrings ();
913   return Status;
914 }
915
916 EFI_STATUS
917 PciFindProtocolInterface (
918   IN  EFI_HANDLE                            *HandleBuf,
919   IN  UINTN                                 HandleCount,
920   IN  UINT16                                Segment,
921   IN  UINT16                                Bus,
922   OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       **IoDev
923   )
924 /*++
925
926 Routine Description:
927
928   This function finds out the protocol which is in charge of the given 
929   segment, and its bus range covers the current bus number. It lookes 
930   each instances of RootBridgeIoProtocol handle, until the one meets the
931   criteria is found. 
932
933 Arguments:
934
935   HandleBuf       Buffer which holds all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles
936   HandleCount     Count of all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles
937   Segment         Segment number of device we are dealing with
938   Bus             Bus number of device we are dealing with
939   IoDev           Handle used to access configuration space of PCI device
940
941 Returns:
942
943   EFI_SUCCESS           - The command completed successfully
944   EFI_INVALID_PARAMETER - Invalid parameter
945
946 --*/
947 {
948   UINTN                             Index;
949   EFI_STATUS                        Status;
950   BOOLEAN                           FoundInterface;
951   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
952   UINT16                            MinBus;
953   UINT16                            MaxBus;
954   BOOLEAN                           IsEnd;
955
956   FoundInterface = FALSE;
957   //
958   // Go through all handles, until the one meets the criteria is found
959   //
960   for (Index = 0; Index < HandleCount; Index++) {
961     Status = PciGetProtocolAndResource (HandleBuf[Index], IoDev, &Descriptors);
962     if (EFI_ERROR (Status)) {
963       return Status;
964     }
965     //
966     // When Descriptors == NULL, the Configuration() is not implemented,
967     // so we only check the Segment number
968     //
969     if (Descriptors == NULL && Segment == (*IoDev)->SegmentNumber) {
970       return EFI_SUCCESS;
971     }
972
973     if ((*IoDev)->SegmentNumber != Segment) {
974       continue;
975     }
976
977     while (TRUE) {
978       Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd);
979       if (EFI_ERROR (Status)) {
980         return Status;
981       }
982
983       if (IsEnd) {
984         break;
985       }
986
987       if (MinBus <= Bus && MaxBus >= Bus) {
988         FoundInterface = TRUE;
989         break;
990       }
991     }
992   }
993
994   if (FoundInterface) {
995     return EFI_SUCCESS;
996   } else {
997     return EFI_INVALID_PARAMETER;
998   }
999 }
1000
1001 EFI_STATUS
1002 PciGetProtocolAndResource (
1003   IN  EFI_HANDLE                            Handle,
1004   OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       **IoDev,
1005   OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     **Descriptors
1006   )
1007 /*++
1008
1009 Routine Description:
1010
1011   This function gets the protocol interface from the given handle, and
1012   obtains its address space descriptors.
1013
1014 Arguments:
1015
1016   Handle          The PCI_ROOT_BRIDIGE_IO_PROTOCOL handle
1017   IoDev           Handle used to access configuration space of PCI device
1018   Descriptors     Points to the address space descriptors
1019
1020 Returns:
1021
1022   EFI_SUCCESS     The command completed successfully
1023
1024 --*/
1025 {
1026   EFI_STATUS  Status;
1027
1028   //
1029   // Get inferface from protocol
1030   //
1031   Status = BS->HandleProtocol (
1032                 Handle,
1033                 &gEfiPciRootBridgeIoProtocolGuid,
1034                 IoDev
1035                 );
1036
1037   if (EFI_ERROR (Status)) {
1038     return Status;
1039   }
1040   //
1041   // Call Configuration() to get address space descriptors
1042   //
1043   Status = (*IoDev)->Configuration (*IoDev, Descriptors);
1044   if (Status == EFI_UNSUPPORTED) {
1045     *Descriptors = NULL;
1046     return EFI_SUCCESS;
1047
1048   } else {
1049     return Status;
1050   }
1051 }
1052
1053 EFI_STATUS
1054 PciGetNextBusRange (
1055   IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  **Descriptors,
1056   OUT    UINT16                             *MinBus,
1057   OUT    UINT16                             *MaxBus,
1058   OUT    BOOLEAN                            *IsEnd
1059   )
1060 /*++
1061
1062 Routine Description:
1063
1064   This function get the next bus range of given address space descriptors.
1065   It also moves the pointer backward a node, to get prepared to be called
1066   again.
1067
1068 Arguments:
1069
1070   Descriptors     points to current position of a serial of address space 
1071                   descriptors
1072   MinBus          The lower range of bus number
1073   ManBus          The upper range of bus number
1074   IsEnd           Meet end of the serial of descriptors 
1075   
1076 Returns:
1077
1078   EFI_SUCCESS     The command completed successfully
1079
1080 --*/
1081 {
1082   *IsEnd = FALSE;
1083
1084   //
1085   // When *Descriptors is NULL, Configuration() is not implemented, so assume
1086   // range is 0~PCI_MAX_BUS
1087   //
1088   if ((*Descriptors) == NULL) {
1089     *MinBus = 0;
1090     *MaxBus = PCI_MAX_BUS;
1091     return EFI_SUCCESS;
1092   }
1093   //
1094   // *Descriptors points to one or more address space descriptors, which
1095   // ends with a end tagged descriptor. Examine each of the descriptors,
1096   // if a bus typed one is found and its bus range covers bus, this handle
1097   // is the handle we are looking for.
1098   //
1099   if ((*Descriptors)->Desc == ACPI_END_TAG_DESCRIPTOR) {
1100     *IsEnd = TRUE;
1101   }
1102
1103   while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {
1104     if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {
1105       *MinBus = (UINT16) (*Descriptors)->AddrRangeMin;
1106       *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax;
1107       (*Descriptors)++;
1108       break;
1109     }
1110
1111     (*Descriptors)++;
1112   }
1113
1114   return EFI_SUCCESS;
1115 }
1116
1117 EFI_STATUS
1118 PciExplainData (
1119   IN PCI_CONFIG_SPACE                       *ConfigSpace,
1120   IN UINT64                                 Address,
1121   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev
1122   )
1123 /*++
1124
1125 Routine Description:
1126
1127   Explain the data in PCI configuration space. The part which is common for
1128   PCI device and bridge is interpreted in this function. It calls other 
1129   functions to interpret data unique for device or bridge.
1130
1131 Arguments:
1132
1133   ConfigSpace     Data in PCI configuration space
1134   Address         Address used to access configuration space of this PCI device
1135   IoDev           Handle used to access configuration space of PCI device
1136
1137 Returns:
1138
1139   EFI_SUCCESS     The command completed successfully
1140
1141 --*/
1142 {
1143   PCI_COMMON_HEADER *Common;
1144   PCI_HEADER_TYPE   HeaderType;
1145   EFI_STATUS        Status;
1146   UINT8             CapPtr;
1147
1148   Common = &(ConfigSpace->Common);
1149
1150   Print (L"\n");
1151
1152   //
1153   // Print Vendor Id and Device Id
1154   //
1155   PrintToken (
1156     STRING_TOKEN (STR_PCI2_VENDOR_ID),
1157     HiiHandle,
1158     INDEX_OF (&(Common->VendorId)),
1159     Common->VendorId
1160     );
1161
1162   PrintToken (
1163     STRING_TOKEN (STR_PCI2_DEVICE_ID),
1164     HiiHandle,
1165     INDEX_OF (&(Common->DeviceId)),
1166     Common->DeviceId
1167     );
1168
1169   //
1170   // Print register Command
1171   //
1172   PciExplainCommand (&(Common->Command));
1173
1174   //
1175   // Print register Status
1176   //
1177   PciExplainStatus (&(Common->Status), TRUE, PciUndefined);
1178
1179   //
1180   // Print register Revision ID
1181   //
1182   PrintToken (
1183     STRING_TOKEN (STR_PCI2_REVISION_ID),
1184     HiiHandle,
1185     INDEX_OF (&(Common->RevisionId)),
1186     Common->RevisionId
1187     );
1188
1189   //
1190   // Print register BIST
1191   //
1192   PrintToken (STRING_TOKEN (STR_PCI2_BIST), HiiHandle, INDEX_OF (&(Common->BIST)));
1193   if ((Common->BIST & PCI_BIT_7) != 0) {
1194     PrintToken (STRING_TOKEN (STR_PCI2_CAPABLE_RETURN), HiiHandle, 0x0f & Common->BIST);
1195
1196   } else {
1197     PrintToken (STRING_TOKEN (STR_PCI2_INCAPABLE), HiiHandle);
1198   }
1199   //
1200   // Print register Cache Line Size
1201   //
1202   PrintToken (
1203     STRING_TOKEN (STR_PCI2_CACHE_LINE_SIZE),
1204     HiiHandle,
1205     INDEX_OF (&(Common->CacheLineSize)),
1206     Common->CacheLineSize
1207     );
1208
1209   //
1210   // Print register Latency Timer
1211   //
1212   PrintToken (
1213     STRING_TOKEN (STR_PCI2_LATENCY_TIMER),
1214     HiiHandle,
1215     INDEX_OF (&(Common->PrimaryLatencyTimer)),
1216     Common->PrimaryLatencyTimer
1217     );
1218
1219   //
1220   // Print register Header Type
1221   //
1222   PrintToken (
1223     STRING_TOKEN (STR_PCI2_HEADER_TYPE),
1224     HiiHandle,
1225     INDEX_OF (&(Common->HeaderType)),
1226     Common->HeaderType
1227     );
1228
1229   if ((Common->HeaderType & PCI_BIT_7) != 0) {
1230     PrintToken (STRING_TOKEN (STR_PCI2_MULTI_FUNCTION), HiiHandle);
1231
1232   } else {
1233     PrintToken (STRING_TOKEN (STR_PCI2_SINGLE_FUNCTION), HiiHandle);
1234   }
1235
1236   HeaderType = (UINT8) (Common->HeaderType & 0x7f);
1237   switch (HeaderType) {
1238   case PciDevice:
1239     PrintToken (STRING_TOKEN (STR_PCI2_PCI_DEVICE), HiiHandle);
1240     break;
1241
1242   case PciP2pBridge:
1243     PrintToken (STRING_TOKEN (STR_PCI2_P2P_BRIDGE), HiiHandle);
1244     break;
1245
1246   case PciCardBusBridge:
1247     PrintToken (STRING_TOKEN (STR_PCI2_CARDBUS_BRIDGE), HiiHandle);
1248     break;
1249
1250   default:
1251     PrintToken (STRING_TOKEN (STR_PCI2_RESERVED), HiiHandle);
1252     HeaderType = PciUndefined;
1253   }
1254
1255   //
1256   // Print register Class Code
1257   //
1258   PrintToken (STRING_TOKEN (STR_PCI2_CLASS), HiiHandle);
1259   PciPrintClassCode ((UINT8 *) Common->ClassCode, TRUE);
1260   Print (L"\n");
1261
1262   if (GetExecutionBreak ()) {
1263     return EFI_SUCCESS;
1264   }
1265
1266   //
1267   // Interpret remaining part of PCI configuration header depending on
1268   // HeaderType
1269   //
1270   CapPtr  = 0;
1271   Status  = EFI_SUCCESS;
1272   switch (HeaderType) {
1273   case PciDevice:
1274     Status = PciExplainDeviceData (
1275               &(ConfigSpace->NonCommon.Device),
1276               Address,
1277               IoDev
1278               );
1279     CapPtr = ConfigSpace->NonCommon.Device.CapabilitiesPtr;
1280     break;
1281
1282   case PciP2pBridge:
1283     Status = PciExplainBridgeData (
1284               &(ConfigSpace->NonCommon.Bridge),
1285               Address,
1286               IoDev
1287               );
1288     CapPtr = ConfigSpace->NonCommon.Bridge.CapabilitiesPtr;
1289     break;
1290
1291   case PciCardBusBridge:
1292     Status = PciExplainCardBusData (
1293               &(ConfigSpace->NonCommon.CardBus),
1294               Address,
1295               IoDev
1296               );
1297     CapPtr = ConfigSpace->NonCommon.CardBus.CapabilitiesPtr;
1298     break;
1299   }
1300   //
1301   // If Status bit4 is 1, dump or explain capability structure
1302   //
1303   if ((Common->Status) & EFI_PCI_STATUS_CAPABILITY) {
1304     PciExplainCapabilityStruct (IoDev, Address, CapPtr);
1305   }
1306
1307   return Status;
1308 }
1309
1310 EFI_STATUS
1311 PciExplainDeviceData (
1312   IN PCI_DEVICE_HEADER                      *Device,
1313   IN UINT64                                 Address,
1314   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev
1315   )
1316 /*++
1317
1318 Routine Description:
1319
1320   Explain the device specific part of data in PCI configuration space.
1321
1322 Arguments:
1323
1324   Device          Data in PCI configuration space
1325   Address         Address used to access configuration space of this PCI device
1326   IoDev           Handle used to access configuration space of PCI device
1327
1328 Returns:
1329
1330   EFI_SUCCESS     The command completed successfully
1331
1332 --*/
1333 {
1334   UINTN       Index;
1335   BOOLEAN     BarExist;
1336   EFI_STATUS  Status;
1337   UINTN       BarCount;
1338
1339   //
1340   // Print Base Address Registers(Bar). When Bar = 0, this Bar does not
1341   // exist. If these no Bar for this function, print "none", otherwise
1342   // list detail information about this Bar.
1343   //
1344   PrintToken (STRING_TOKEN (STR_PCI2_BASE_ADDR), HiiHandle, INDEX_OF (Device->Bar));
1345
1346   BarExist  = FALSE;
1347   BarCount  = sizeof (Device->Bar) / sizeof (Device->Bar[0]);
1348   for (Index = 0; Index < BarCount; Index++) {
1349     if (Device->Bar[Index] == 0) {
1350       continue;
1351     }
1352
1353     if (!BarExist) {
1354       BarExist = TRUE;
1355       PrintToken (STRING_TOKEN (STR_PCI2_START_TYPE), HiiHandle);
1356       Print (L"  --------------------------------------------------------------------------");
1357     }
1358
1359     Status = PciExplainBar (
1360               &(Device->Bar[Index]),
1361               &(mConfigSpace->Common.Command),
1362               Address,
1363               IoDev,
1364               &Index
1365               );
1366
1367     if (EFI_ERROR (Status)) {
1368       break;
1369     }
1370   }
1371
1372   if (!BarExist) {
1373     PrintToken (STRING_TOKEN (STR_PCI2_NONE), HiiHandle);
1374
1375   } else {
1376     Print (L"\n  --------------------------------------------------------------------------");
1377   }
1378
1379   //
1380   // Print register Expansion ROM Base Address
1381   //
1382   if ((Device->ROMBar & PCI_BIT_0) == 0) {
1383     PrintToken (STRING_TOKEN (STR_PCI2_EXPANSION_ROM_DISABLED), HiiHandle, INDEX_OF (&(Device->ROMBar)));
1384
1385   } else {
1386     PrintToken (
1387       STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE),
1388       HiiHandle,
1389       INDEX_OF (&(Device->ROMBar)),
1390       Device->ROMBar
1391       );
1392   }
1393   //
1394   // Print register Cardbus CIS ptr
1395   //
1396   PrintToken (
1397     STRING_TOKEN (STR_PCI2_CARDBUS_CIS),
1398     HiiHandle,
1399     INDEX_OF (&(Device->CardBusCISPtr)),
1400     Device->CardBusCISPtr
1401     );
1402
1403   //
1404   // Print register Sub-vendor ID and subsystem ID
1405   //
1406   PrintToken (
1407     STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID),
1408     HiiHandle,
1409     INDEX_OF (&(Device->SubVendorId)),
1410     Device->SubVendorId
1411     );
1412
1413   PrintToken (
1414     STRING_TOKEN (STR_PCI2_SUBSYSTEM_ID),
1415     HiiHandle,
1416     INDEX_OF (&(Device->SubSystemId)),
1417     Device->SubSystemId
1418     );
1419
1420   //
1421   // Print register Capabilities Ptr
1422   //
1423   PrintToken (
1424     STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR),
1425     HiiHandle,
1426     INDEX_OF (&(Device->CapabilitiesPtr)),
1427     Device->CapabilitiesPtr
1428     );
1429
1430   //
1431   // Print register Interrupt Line and interrupt pin
1432   //
1433   PrintToken (
1434     STRING_TOKEN (STR_PCI2_INTERRUPT_LINE),
1435     HiiHandle,
1436     INDEX_OF (&(Device->InterruptLine)),
1437     Device->InterruptLine
1438     );
1439
1440   PrintToken (
1441     STRING_TOKEN (STR_PCI2_INTERRUPT_PIN),
1442     HiiHandle,
1443     INDEX_OF (&(Device->InterruptPin)),
1444     Device->InterruptPin
1445     );
1446
1447   //
1448   // Print register Min_Gnt and Max_Lat
1449   //
1450   PrintToken (
1451     STRING_TOKEN (STR_PCI2_MIN_GNT),
1452     HiiHandle,
1453     INDEX_OF (&(Device->MinGnt)),
1454     Device->MinGnt
1455     );
1456
1457   PrintToken (
1458     STRING_TOKEN (STR_PCI2_MAX_LAT),
1459     HiiHandle,
1460     INDEX_OF (&(Device->MaxLat)),
1461     Device->MaxLat
1462     );
1463
1464   return EFI_SUCCESS;
1465 }
1466
1467 EFI_STATUS
1468 PciExplainBridgeData (
1469   IN  PCI_BRIDGE_HEADER                     *Bridge,
1470   IN  UINT64                                Address,
1471   IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *IoDev
1472   )
1473 /*++
1474
1475 Routine Description:
1476
1477   Explain the bridge specific part of data in PCI configuration space.
1478
1479 Arguments:
1480
1481   Bridge          Bridge specific data region in PCI configuration space
1482   Address         Address used to access configuration space of this PCI device
1483   IoDev           Handle used to access configuration space of PCI device
1484
1485 Returns:
1486
1487   EFI_SUCCESS     The command completed successfully
1488
1489 --*/
1490 {
1491   UINTN       Index;
1492   BOOLEAN     BarExist;
1493   UINTN       BarCount;
1494   UINT32      IoAddress32;
1495   EFI_STATUS  Status;
1496
1497   //
1498   // Print Base Address Registers. When Bar = 0, this Bar does not
1499   // exist. If these no Bar for this function, print "none", otherwise
1500   // list detail information about this Bar.
1501   //
1502   PrintToken (STRING_TOKEN (STR_PCI2_BASE_ADDRESS), HiiHandle, INDEX_OF (&(Bridge->Bar)));
1503
1504   BarExist  = FALSE;
1505   BarCount  = sizeof (Bridge->Bar) / sizeof (Bridge->Bar[0]);
1506
1507   for (Index = 0; Index < BarCount; Index++) {
1508     if (Bridge->Bar[Index] == 0) {
1509       continue;
1510     }
1511
1512     if (!BarExist) {
1513       BarExist = TRUE;
1514       PrintToken (STRING_TOKEN (STR_PCI2_START_TYPE_2), HiiHandle);
1515       Print (L"  --------------------------------------------------------------------------");
1516     }
1517
1518     Status = PciExplainBar (
1519               &(Bridge->Bar[Index]),
1520               &(mConfigSpace->Common.Command),
1521               Address,
1522               IoDev,
1523               &Index
1524               );
1525
1526     if (EFI_ERROR (Status)) {
1527       break;
1528     }
1529   }
1530
1531   if (!BarExist) {
1532     PrintToken (STRING_TOKEN (STR_PCI2_NONE), HiiHandle);
1533   } else {
1534     Print (L"\n  --------------------------------------------------------------------------");
1535   }
1536
1537   //
1538   // Expansion register ROM Base Address
1539   //
1540   if ((Bridge->ROMBar & PCI_BIT_0) == 0) {
1541     PrintToken (STRING_TOKEN (STR_PCI2_NO_EXPANSION_ROM), HiiHandle, INDEX_OF (&(Bridge->ROMBar)));
1542
1543   } else {
1544     PrintToken (
1545       STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE_2),
1546       HiiHandle,
1547       INDEX_OF (&(Bridge->ROMBar)),
1548       Bridge->ROMBar
1549       );
1550   }
1551   //
1552   // Print Bus Numbers(Primary, Secondary, and Subordinate
1553   //
1554   PrintToken (
1555     STRING_TOKEN (STR_PCI2_BUS_NUMBERS),
1556     HiiHandle,
1557     INDEX_OF (&(Bridge->PrimaryBus)),
1558     INDEX_OF (&(Bridge->SecondaryBus)),
1559     INDEX_OF (&(Bridge->SubordinateBus))
1560     );
1561
1562   Print (L"               ------------------------------------------------------\n");
1563
1564   PrintToken (STRING_TOKEN (STR_PCI2_BRIDGE), HiiHandle, Bridge->PrimaryBus);
1565   PrintToken (STRING_TOKEN (STR_PCI2_BRIDGE), HiiHandle, Bridge->SecondaryBus);
1566   PrintToken (STRING_TOKEN (STR_PCI2_BRIDGE), HiiHandle, Bridge->SubordinateBus);
1567
1568   //
1569   // Print register Secondary Latency Timer
1570   //
1571   PrintToken (
1572     STRING_TOKEN (STR_PCI2_SECONDARY_TIMER),
1573     HiiHandle,
1574     INDEX_OF (&(Bridge->SecondaryLatencyTimer)),
1575     Bridge->SecondaryLatencyTimer
1576     );
1577
1578   //
1579   // Print register Secondary Status
1580   //
1581   PciExplainStatus (&(Bridge->SecondaryStatus), FALSE, PciP2pBridge);
1582
1583   //
1584   // Print I/O and memory ranges this bridge forwards. There are 3 resource
1585   // types: I/O, memory, and pre-fetchable memory. For each resource type,
1586   // base and limit address are listed.
1587   //
1588   PrintToken (STRING_TOKEN (STR_PCI2_RESOURCE_TYPE), HiiHandle);
1589   Print (L"----------------------------------------------------------------------\n");
1590
1591   //
1592   // IO Base & Limit
1593   //
1594   IoAddress32 = (Bridge->IoBaseUpper << 16 | Bridge->IoBase << 8);
1595   IoAddress32 &= 0xfffff000;
1596   PrintToken (
1597     STRING_TOKEN (STR_PCI2_TWO_VARS),
1598     HiiHandle,
1599     INDEX_OF (&(Bridge->IoBase)),
1600     IoAddress32
1601     );
1602
1603   IoAddress32 = (Bridge->IoLimitUpper << 16 | Bridge->IoLimit << 8);
1604   IoAddress32 |= 0x00000fff;
1605   PrintToken (STRING_TOKEN (STR_PCI2_ONE_VAR), HiiHandle, IoAddress32);
1606
1607   //
1608   // Memory Base & Limit
1609   //
1610   PrintToken (
1611     STRING_TOKEN (STR_PCI2_MEMORY),
1612     HiiHandle,
1613     INDEX_OF (&(Bridge->MemoryBase)),
1614     (Bridge->MemoryBase << 16) & 0xfff00000
1615     );
1616
1617   PrintToken (
1618     STRING_TOKEN (STR_PCI2_ONE_VAR),
1619     HiiHandle,
1620     (Bridge->MemoryLimit << 16) | 0x000fffff
1621     );
1622
1623   //
1624   // Pre-fetch-able Memory Base & Limit
1625   //
1626   PrintToken (
1627     STRING_TOKEN (STR_PCI2_PREFETCHABLE),
1628     HiiHandle,
1629     INDEX_OF (&(Bridge->PrefetchableMemBase)),
1630     Bridge->PrefetchableBaseUpper,
1631     (Bridge->PrefetchableMemBase << 16) & 0xfff00000
1632     );
1633
1634   PrintToken (
1635     STRING_TOKEN (STR_PCI2_TWO_VARS_2),
1636     HiiHandle,
1637     Bridge->PrefetchableLimitUpper,
1638     (Bridge->PrefetchableMemLimit << 16) | 0x000fffff
1639     );
1640
1641   //
1642   // Print register Capabilities Pointer
1643   //
1644   PrintToken (
1645     STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR_2),
1646     HiiHandle,
1647     INDEX_OF (&(Bridge->CapabilitiesPtr)),
1648     Bridge->CapabilitiesPtr
1649     );
1650
1651   //
1652   // Print register Bridge Control
1653   //
1654   PciExplainBridgeControl (&(Bridge->BridgeControl), PciP2pBridge);
1655
1656   //
1657   // Print register Interrupt Line & PIN
1658   //
1659   PrintToken (
1660     STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_2),
1661     HiiHandle,
1662     INDEX_OF (&(Bridge->InterruptLine)),
1663     Bridge->InterruptLine
1664     );
1665
1666   PrintToken (
1667     STRING_TOKEN (STR_PCI2_INTERRUPT_PIN),
1668     HiiHandle,
1669     INDEX_OF (&(Bridge->InterruptPin)),
1670     Bridge->InterruptPin
1671     );
1672
1673   return EFI_SUCCESS;
1674 }
1675
1676 EFI_STATUS
1677 PciExplainBar (
1678   IN UINT32                                 *Bar,
1679   IN UINT16                                 *Command,
1680   IN UINT64                                 Address,
1681   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev,
1682   IN OUT UINTN                              *Index
1683   )
1684 /*++
1685
1686 Routine Description:
1687
1688   Explain the Base Address Register(Bar) in PCI configuration space.
1689
1690 Arguments:
1691
1692   Bar             Points to the Base Address Register intended to interpret
1693   Command         Points to the register Command
1694   Address         Address used to access configuration space of this PCI device
1695   IoDev           Handle used to access configuration space of PCI device
1696   Index           The Index
1697
1698 Returns:
1699
1700   EFI_SUCCESS     The command completed successfully
1701
1702 --*/
1703 {
1704   UINT16  OldCommand;
1705   UINT16  NewCommand;
1706   UINT64  Bar64;
1707   UINT32  OldBar32;
1708   UINT32  NewBar32;
1709   UINT64  OldBar64;
1710   UINT64  NewBar64;
1711   BOOLEAN IsMem;
1712   BOOLEAN IsBar32;
1713   UINT64  RegAddress;
1714
1715   IsBar32   = TRUE;
1716   Bar64     = 0;
1717   NewBar32  = 0;
1718   NewBar64  = 0;
1719
1720   //
1721   // According the bar type, list detail about this bar, for example: 32 or
1722   // 64 bits; pre-fetchable or not.
1723   //
1724   if ((*Bar & PCI_BIT_0) == 0) {
1725     //
1726     // This bar is of memory type
1727     //
1728     IsMem = TRUE;
1729
1730     if ((*Bar & PCI_BIT_1) == 0 && (*Bar & PCI_BIT_2) == 0) {
1731       PrintToken (STRING_TOKEN (STR_PCI2_BAR), HiiHandle, *Bar & 0xfffffff0);
1732       PrintToken (STRING_TOKEN (STR_PCI2_MEM), HiiHandle);
1733       PrintToken (STRING_TOKEN (STR_PCI2_32_BITS), HiiHandle);
1734
1735     } else if ((*Bar & PCI_BIT_1) == 0 && (*Bar & PCI_BIT_2) != 0) {
1736       Bar64 = 0x0;
1737       CopyMem (&Bar64, Bar, sizeof (UINT32));
1738       PrintToken (STRING_TOKEN (STR_PCI2_ONE_VAR_2), HiiHandle, RShiftU64 ((Bar64 & 0xfffffffffffffff0), 32));
1739       PrintToken (STRING_TOKEN (STR_PCI2_ONE_VAR_3), HiiHandle, Bar64 & 0xfffffffffffffff0);
1740       PrintToken (STRING_TOKEN (STR_PCI2_MEM), HiiHandle);
1741       PrintToken (STRING_TOKEN (STR_PCI2_64_BITS), HiiHandle);
1742       IsBar32 = FALSE;
1743       *Index += 1;
1744
1745     } else {
1746       //
1747       // Reserved
1748       //
1749       PrintToken (STRING_TOKEN (STR_PCI2_BAR), HiiHandle, *Bar & 0xfffffff0);
1750       PrintToken (STRING_TOKEN (STR_PCI2_MEM_2), HiiHandle);
1751     }
1752
1753     if ((*Bar & PCI_BIT_3) == 0) {
1754       PrintToken (STRING_TOKEN (STR_PCI2_NO), HiiHandle);
1755
1756     } else {
1757       PrintToken (STRING_TOKEN (STR_PCI2_YES), HiiHandle);
1758     }
1759
1760   } else {
1761     //
1762     // This bar is of io type
1763     //
1764     IsMem = FALSE;
1765     PrintToken (STRING_TOKEN (STR_PCI2_ONE_VAR_4), HiiHandle, *Bar & 0xfffffffc);
1766     Print (L"I/O                               ");
1767   }
1768
1769   //
1770   // Get BAR length(or the amount of resource this bar demands for). To get
1771   // Bar length, first we should temporarily disable I/O and memory access
1772   // of this function(by set bits in the register Command), then write all
1773   // "1"s to this bar. The bar value read back is the amount of resource
1774   // this bar demands for.
1775   //
1776   //
1777   // Disable io & mem access
1778   //
1779   OldCommand  = *Command;
1780   NewCommand  = (UINT16) (OldCommand & 0xfffc);
1781   RegAddress  = Address | INDEX_OF (Command);
1782   IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &NewCommand);
1783
1784   RegAddress = Address | INDEX_OF (Bar);
1785
1786   //
1787   // Read after write the BAR to get the size
1788   //
1789   if (IsBar32) {
1790     OldBar32  = *Bar;
1791     NewBar32  = 0xffffffff;
1792
1793     IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32);
1794     IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32);
1795     IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &OldBar32);
1796
1797     if (IsMem) {
1798       NewBar32  = NewBar32 & 0xfffffff0;
1799       NewBar32  = (~NewBar32) + 1;
1800
1801     } else {
1802       NewBar32  = NewBar32 & 0xfffffffc;
1803       NewBar32  = (~NewBar32) + 1;
1804       NewBar32  = NewBar32 & 0x0000ffff;
1805     }
1806   } else {
1807
1808     OldBar64 = 0x0;
1809     CopyMem (&OldBar64, Bar, sizeof (UINT32));
1810     NewBar64 = 0xffffffffffffffff;
1811
1812     IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64);
1813     IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64);
1814     IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &OldBar64);
1815
1816     if (IsMem) {
1817       NewBar64  = NewBar64 & 0xfffffffffffffff0;
1818       NewBar64  = (~NewBar64) + 1;
1819
1820     } else {
1821       NewBar64  = NewBar64 & 0xfffffffffffffffc;
1822       NewBar64  = (~NewBar64) + 1;
1823       NewBar64  = NewBar64 & 0x000000000000ffff;
1824     }
1825   }
1826   //
1827   // Enable io & mem access
1828   //
1829   RegAddress = Address | INDEX_OF (Command);
1830   IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &OldCommand);
1831
1832   if (IsMem) {
1833     if (IsBar32) {
1834       PrintToken (STRING_TOKEN (STR_PCI2_NEWBAR_32), HiiHandle, NewBar32);
1835       PrintToken (STRING_TOKEN (STR_PCI2_NEWBAR_32_2), HiiHandle, NewBar32 + (*Bar & 0xfffffff0) - 1);
1836
1837     } else {
1838       PrintToken (STRING_TOKEN (STR_PCI2_RSHIFT), HiiHandle, RShiftU64 (NewBar64, 32));
1839       PrintToken (STRING_TOKEN (STR_PCI2_RSHIFT), HiiHandle, (UINT32) NewBar64);
1840       Print (L"  ");
1841       PrintToken (
1842         STRING_TOKEN (STR_PCI2_RSHIFT),
1843         HiiHandle,
1844         RShiftU64 ((NewBar64 + (Bar64 & 0xfffffffffffffff0) - 1), 32)
1845         );
1846       PrintToken (STRING_TOKEN (STR_PCI2_RSHIFT), HiiHandle, (UINT32) (NewBar64 + (Bar64 & 0xfffffffffffffff0) - 1));
1847
1848     }
1849   } else {
1850     PrintToken (STRING_TOKEN (STR_PCI2_NEWBAR_32_3), HiiHandle, NewBar32);
1851     PrintToken (STRING_TOKEN (STR_PCI2_NEWBAR_32_4), HiiHandle, NewBar32 + (*Bar & 0xfffffffc) - 1);
1852   }
1853
1854   return EFI_SUCCESS;
1855 }
1856
1857 EFI_STATUS
1858 PciExplainCardBusData (
1859   IN PCI_CARDBUS_HEADER                     *CardBus,
1860   IN UINT64                                 Address,
1861   IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev
1862   )
1863 /*++
1864
1865 Routine Description:
1866
1867   Explain the cardbus specific part of data in PCI configuration space.
1868
1869 Arguments:
1870
1871   CardBus         CardBus specific region of PCI configuration space
1872   Address         Address used to access configuration space of this PCI device
1873   IoDev           Handle used to access configuration space of PCI device
1874
1875 Returns:
1876
1877   EFI_SUCCESS     The command completed successfully
1878
1879 --*/
1880 {
1881   BOOLEAN           Io32Bit;
1882   PCI_CARDBUS_DATA  *CardBusData;
1883
1884   PrintToken (
1885     STRING_TOKEN (STR_PCI2_CARDBUS_SOCKET),
1886     HiiHandle,
1887     INDEX_OF (&(CardBus->CardBusSocketReg)),
1888     CardBus->CardBusSocketReg
1889     );
1890
1891   //
1892   // Print Secondary Status
1893   //
1894   PciExplainStatus (&(CardBus->SecondaryStatus), FALSE, PciCardBusBridge);
1895
1896   //
1897   // Print Bus Numbers(Primary bus number, CardBus bus number, and
1898   // Subordinate bus number
1899   //
1900   PrintToken (
1901     STRING_TOKEN (STR_PCI2_BUS_NUMBERS_2),
1902     HiiHandle,
1903     INDEX_OF (&(CardBus->PciBusNumber)),
1904     INDEX_OF (&(CardBus->CardBusBusNumber)),
1905     INDEX_OF (&(CardBus->SubordinateBusNumber))
1906     );
1907
1908   Print (L"               ------------------------------------------------------\n");
1909
1910   PrintToken (STRING_TOKEN (STR_PCI2_CARDBUS), HiiHandle, CardBus->PciBusNumber);
1911   PrintToken (STRING_TOKEN (STR_PCI2_CARDBUS_2), HiiHandle, CardBus->CardBusBusNumber);
1912   PrintToken (STRING_TOKEN (STR_PCI2_CARDBUS_3), HiiHandle, CardBus->SubordinateBusNumber);
1913
1914   //
1915   // Print CardBus Latency Timer
1916   //
1917   PrintToken (
1918     STRING_TOKEN (STR_PCI2_CARDBUS_LATENCY),
1919     HiiHandle,
1920     INDEX_OF (&(CardBus->CardBusLatencyTimer)),
1921     CardBus->CardBusLatencyTimer
1922     );
1923
1924   //
1925   // Print Memory/Io ranges this cardbus bridge forwards
1926   //
1927   PrintToken (STRING_TOKEN (STR_PCI2_RESOURCE_TYPE_2), HiiHandle);
1928   Print (L"----------------------------------------------------------------------\n");
1929
1930   PrintToken (
1931     STRING_TOKEN (STR_PCI2_MEM_3),
1932     HiiHandle,
1933     INDEX_OF (&(CardBus->MemoryBase0)),
1934     CardBus->BridgeControl & PCI_BIT_8 ? L"    Prefetchable" : L"Non-Prefetchable",
1935     CardBus->MemoryBase0 & 0xfffff000,
1936     CardBus->MemoryLimit0 | 0x00000fff
1937     );
1938
1939   PrintToken (
1940     STRING_TOKEN (STR_PCI2_MEM_3),
1941     HiiHandle,
1942     INDEX_OF (&(CardBus->MemoryBase1)),
1943     CardBus->BridgeControl & PCI_BIT_9 ? L"    Prefetchable" : L"Non-Prefetchable",
1944     CardBus->MemoryBase1 & 0xfffff000,
1945     CardBus->MemoryLimit1 | 0x00000fff
1946     );
1947
1948   Io32Bit = (BOOLEAN) (CardBus->IoBase0 & PCI_BIT_0);
1949   PrintToken (
1950     STRING_TOKEN (STR_PCI2_IO_2),
1951     HiiHandle,
1952     INDEX_OF (&(CardBus->IoBase0)),
1953     Io32Bit ? L"          32 bit" : L"          16 bit",
1954     CardBus->IoBase0 & (Io32Bit ? 0xfffffffc : 0x0000fffc),
1955     CardBus->IoLimit0 & (Io32Bit ? 0xffffffff : 0x0000ffff) | 0x00000003
1956     );
1957
1958   Io32Bit = (BOOLEAN) (CardBus->IoBase1 & PCI_BIT_0);
1959   PrintToken (
1960     STRING_TOKEN (STR_PCI2_IO_2),
1961     HiiHandle,
1962     INDEX_OF (&(CardBus->IoBase1)),
1963     Io32Bit ? L"          32 bit" : L"          16 bit",
1964     CardBus->IoBase1 & (Io32Bit ? 0xfffffffc : 0x0000fffc),
1965     CardBus->IoLimit1 & (Io32Bit ? 0xffffffff : 0x0000ffff) | 0x00000003
1966     );
1967
1968   //
1969   // Print register Interrupt Line & PIN
1970   //
1971   PrintToken (
1972     STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_3),
1973     HiiHandle,
1974     INDEX_OF (&(CardBus->InterruptLine)),
1975     CardBus->InterruptLine,
1976     INDEX_OF (&(CardBus->InterruptPin)),
1977     CardBus->InterruptPin
1978     );
1979
1980   //
1981   // Print register Bridge Control
1982   //
1983   PciExplainBridgeControl (&(CardBus->BridgeControl), PciCardBusBridge);
1984
1985   //
1986   // Print some registers in data region of PCI configuration space for cardbus
1987   // bridge. Fields include: Sub VendorId, Subsystem ID, and Legacy Mode Base
1988   // Address.
1989   //
1990   CardBusData = (PCI_CARDBUS_DATA *) ((UINT8 *) CardBus + sizeof (PCI_CARDBUS_HEADER));
1991
1992   PrintToken (
1993     STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID_2),
1994     HiiHandle,
1995     INDEX_OF (&(CardBusData->SubVendorId)),
1996     CardBusData->SubVendorId,
1997     INDEX_OF (&(CardBusData->SubSystemId)),
1998     CardBusData->SubSystemId
1999     );
2000
2001   PrintToken (
2002     STRING_TOKEN (STR_PCI2_OPTIONAL),
2003     HiiHandle,
2004     INDEX_OF (&(CardBusData->LegacyBase)),
2005     CardBusData->LegacyBase
2006     );
2007
2008   return EFI_SUCCESS;
2009 }
2010
2011 EFI_STATUS
2012 PciExplainStatus (
2013   IN UINT16                                 *Status,
2014   IN BOOLEAN                                MainStatus,
2015   IN PCI_HEADER_TYPE                        HeaderType
2016   )
2017 /*++
2018
2019 Routine Description:
2020
2021   Explain each meaningful bit of register Status. The definition of Status is
2022   slightly different depending on the PCI header type.
2023
2024 Arguments:
2025
2026   Status          Points to the content of register Status
2027   MainStatus      Indicates if this register is main status(not secondary 
2028                   status)
2029   HeaderType      Header type of this PCI device
2030   
2031 Returns:
2032
2033   EFI_SUCCESS     The command completed successfully
2034
2035 --*/
2036 {
2037   if (MainStatus) {
2038     PrintToken (STRING_TOKEN (STR_PCI2_STATUS), HiiHandle, INDEX_OF (Status), *Status);
2039
2040   } else {
2041     PrintToken (STRING_TOKEN (STR_PCI2_SECONDARY_STATUS), HiiHandle, INDEX_OF (Status), *Status);
2042   }
2043
2044   PrintToken (STRING_TOKEN (STR_PCI2_NEW_CAPABILITIES), HiiHandle, (*Status & PCI_BIT_4) != 0);
2045
2046   //
2047   // Bit 5 is meaningless for CardBus Bridge
2048   //
2049   if (HeaderType == PciCardBusBridge) {
2050     PrintToken (STRING_TOKEN (STR_PCI2_66_CAPABLE), HiiHandle, (*Status & PCI_BIT_5) != 0);
2051
2052   } else {
2053     PrintToken (STRING_TOKEN (STR_PCI2_66_CAPABLE_2), HiiHandle, (*Status & PCI_BIT_5) != 0);
2054   }
2055
2056   PrintToken (STRING_TOKEN (STR_PCI2_FAST_BACK), HiiHandle, (*Status & PCI_BIT_7) != 0);
2057
2058   PrintToken (STRING_TOKEN (STR_PCI2_MASTER_DATA), HiiHandle, (*Status & PCI_BIT_8) != 0);
2059   //
2060   // Bit 9 and bit 10 together decides the DEVSEL timing
2061   //
2062   PrintToken (STRING_TOKEN (STR_PCI2_DEVSEL_TIMING), HiiHandle);
2063   if ((*Status & PCI_BIT_9) == 0 && (*Status & PCI_BIT_10) == 0) {
2064     PrintToken (STRING_TOKEN (STR_PCI2_FAST), HiiHandle);
2065
2066   } else if ((*Status & PCI_BIT_9) != 0 && (*Status & PCI_BIT_10) == 0) {
2067     PrintToken (STRING_TOKEN (STR_PCI2_MEDIUM), HiiHandle);
2068
2069   } else if ((*Status & PCI_BIT_9) == 0 && (*Status & PCI_BIT_10) != 0) {
2070     PrintToken (STRING_TOKEN (STR_PCI2_SLOW), HiiHandle);
2071
2072   } else {
2073     PrintToken (STRING_TOKEN (STR_PCI2_RESERVED_2), HiiHandle);
2074   }
2075
2076   PrintToken (
2077     STRING_TOKEN (STR_PCI2_SIGNALED_TARGET),
2078     HiiHandle,
2079     (*Status & PCI_BIT_11) != 0
2080     );
2081
2082   PrintToken (
2083     STRING_TOKEN (STR_PCI2_RECEIVED_TARGET),
2084     HiiHandle,
2085     (*Status & PCI_BIT_12) != 0
2086     );
2087
2088   PrintToken (
2089     STRING_TOKEN (STR_PCI2_RECEIVED_MASTER),
2090     HiiHandle,
2091     (*Status & PCI_BIT_13) != 0
2092     );
2093
2094   if (MainStatus) {
2095     PrintToken (
2096       STRING_TOKEN (STR_PCI2_SIGNALED_ERROR),
2097       HiiHandle,
2098       (*Status & PCI_BIT_14) != 0
2099       );
2100
2101   } else {
2102     PrintToken (
2103       STRING_TOKEN (STR_PCI2_RECEIVED_ERROR),
2104       HiiHandle,
2105       (*Status & PCI_BIT_14) != 0
2106       );
2107   }
2108
2109   PrintToken (
2110     STRING_TOKEN (STR_PCI2_DETECTED_ERROR),
2111     HiiHandle,
2112     (*Status & PCI_BIT_15) != 0
2113     );
2114
2115   return EFI_SUCCESS;
2116 }
2117
2118 EFI_STATUS
2119 PciExplainCommand (
2120   IN UINT16                                 *Command
2121   )
2122 /*++
2123
2124 Routine Description:
2125
2126   Explain each meaningful bit of register Command. 
2127
2128 Arguments:
2129
2130   Command         Points to the content of register Command
2131   
2132 Returns:
2133
2134   EFI_SUCCESS     The command completed successfully
2135
2136 --*/
2137 {
2138   //
2139   // Print the binary value of register Command
2140   //
2141   PrintToken (STRING_TOKEN (STR_PCI2_COMMAND), HiiHandle, INDEX_OF (Command), *Command);
2142
2143   //
2144   // Explain register Command bit by bit
2145   //
2146   PrintToken (
2147     STRING_TOKEN (STR_PCI2_SPACE_ACCESS_DENIED),
2148     HiiHandle,
2149     (*Command & PCI_BIT_0) != 0
2150     );
2151
2152   PrintToken (
2153     STRING_TOKEN (STR_PCI2_MEMORY_SPACE),
2154     HiiHandle,
2155     (*Command & PCI_BIT_1) != 0
2156     );
2157
2158   PrintToken (
2159     STRING_TOKEN (STR_PCI2_BEHAVE_BUS_MASTER),
2160     HiiHandle,
2161     (*Command & PCI_BIT_2) != 0
2162     );
2163
2164   PrintToken (
2165     STRING_TOKEN (STR_PCI2_MONITOR_SPECIAL_CYCLE),
2166     HiiHandle,
2167     (*Command & PCI_BIT_3) != 0
2168     );
2169
2170   PrintToken (
2171     STRING_TOKEN (STR_PCI2_MEM_WRITE_INVALIDATE),
2172     HiiHandle,
2173     (*Command & PCI_BIT_4) != 0
2174     );
2175
2176   PrintToken (
2177     STRING_TOKEN (STR_PCI2_PALETTE_SNOOPING),
2178     HiiHandle,
2179     (*Command & PCI_BIT_5) != 0
2180     );
2181
2182   PrintToken (
2183     STRING_TOKEN (STR_PCI2_ASSERT_PERR),
2184     HiiHandle,
2185     (*Command & PCI_BIT_6) != 0
2186     );
2187
2188   PrintToken (
2189     STRING_TOKEN (STR_PCI2_DO_ADDR_STEPPING),
2190     HiiHandle,
2191     (*Command & PCI_BIT_7) != 0
2192     );
2193
2194   PrintToken (
2195     STRING_TOKEN (STR_PCI2_SERR_DRIVER),
2196     HiiHandle,
2197     (*Command & PCI_BIT_8) != 0
2198     );
2199
2200   PrintToken (
2201     STRING_TOKEN (STR_PCI2_FAST_BACK_2),
2202     HiiHandle,
2203     (*Command & PCI_BIT_9) != 0
2204     );
2205
2206   return EFI_SUCCESS;
2207 }
2208
2209 EFI_STATUS
2210 PciExplainBridgeControl (
2211   IN UINT16                                 *BridgeControl,
2212   IN PCI_HEADER_TYPE                        HeaderType
2213   )
2214 /*++
2215
2216 Routine Description:
2217
2218   Explain each meaningful bit of register Bridge Control. 
2219
2220 Arguments:
2221
2222   BridgeControl   Points to the content of register Bridge Control
2223   HeaderType      The headertype
2224   
2225 Returns:
2226
2227   EFI_SUCCESS     The command completed successfully
2228
2229 --*/
2230 {
2231   PrintToken (
2232     STRING_TOKEN (STR_PCI2_BRIDGE_CONTROL),
2233     HiiHandle,
2234     INDEX_OF (BridgeControl),
2235     *BridgeControl
2236     );
2237
2238   PrintToken (
2239     STRING_TOKEN (STR_PCI2_PARITY_ERROR),
2240     HiiHandle,
2241     (*BridgeControl & PCI_BIT_0) != 0
2242     );
2243   PrintToken (
2244     STRING_TOKEN (STR_PCI2_SERR_ENABLE),
2245     HiiHandle,
2246     (*BridgeControl & PCI_BIT_1) != 0
2247     );
2248   PrintToken (
2249     STRING_TOKEN (STR_PCI2_ISA_ENABLE),
2250     HiiHandle,
2251     (*BridgeControl & PCI_BIT_2) != 0
2252     );
2253   PrintToken (
2254     STRING_TOKEN (STR_PCI2_VGA_ENABLE),
2255     HiiHandle,
2256     (*BridgeControl & PCI_BIT_3) != 0
2257     );
2258   PrintToken (
2259     STRING_TOKEN (STR_PCI2_MASTER_ABORT),
2260     HiiHandle,
2261     (*BridgeControl & PCI_BIT_5) != 0
2262     );
2263
2264   //
2265   // Register Bridge Control has some slight differences between P2P bridge
2266   // and Cardbus bridge from bit 6 to bit 11.
2267   //
2268   if (HeaderType == PciP2pBridge) {
2269     PrintToken (
2270       STRING_TOKEN (STR_PCI2_SECONDARY_BUS_RESET),
2271       HiiHandle,
2272       (*BridgeControl & PCI_BIT_6) != 0
2273       );
2274     PrintToken (
2275       STRING_TOKEN (STR_PCI2_FAST_ENABLE),
2276       HiiHandle,
2277       (*BridgeControl & PCI_BIT_7) != 0
2278       );
2279     PrintToken (
2280       STRING_TOKEN (STR_PCI2_PRIMARY_DISCARD_TIMER),
2281       HiiHandle,
2282       (*BridgeControl & PCI_BIT_8) ? L"2^10" : L"2^15"
2283       );
2284     PrintToken (
2285       STRING_TOKEN (STR_PCI2_SECONDARY_DISCARD_TIMER),
2286       HiiHandle,
2287       (*BridgeControl & PCI_BIT_9) ? L"2^10" : L"2^15"
2288       );
2289     PrintToken (
2290       STRING_TOKEN (STR_PCI2_DISCARD_TIMER_STATUS),
2291       HiiHandle,
2292       (*BridgeControl & PCI_BIT_10) != 0
2293       );
2294     PrintToken (
2295       STRING_TOKEN (STR_PCI2_DISCARD_TIMER_SERR),
2296       HiiHandle,
2297       (*BridgeControl & PCI_BIT_11) != 0
2298       );
2299
2300   } else {
2301     PrintToken (
2302       STRING_TOKEN (STR_PCI2_CARDBUS_RESET),
2303       HiiHandle,
2304       (*BridgeControl & PCI_BIT_6) != 0
2305       );
2306     PrintToken (
2307       STRING_TOKEN (STR_PCI2_IREQ_ENABLE),
2308       HiiHandle,
2309       (*BridgeControl & PCI_BIT_7) != 0
2310       );
2311     PrintToken (
2312       STRING_TOKEN (STR_PCI2_WRITE_POSTING_ENABLE),
2313       HiiHandle,
2314       (*BridgeControl & PCI_BIT_10) != 0
2315       );
2316   }
2317
2318   return EFI_SUCCESS;
2319 }
2320
2321 EFI_STATUS
2322 PciExplainCapabilityStruct (
2323   IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         *IoDev,
2324   IN UINT64                                   Address,
2325   IN  UINT8                                   CapPtr
2326   )
2327 {
2328   UINT8   CapabilityPtr;
2329   UINT16  CapabilityEntry;
2330   UINT8   CapabilityID;
2331   UINT64  RegAddress;
2332
2333   CapabilityPtr = CapPtr;
2334
2335   //
2336   // Go through the Capability list
2337   //
2338   while ((CapabilityPtr >= 0x40) && ((CapabilityPtr & 0x03) == 0x00)) { 
2339     RegAddress = Address + CapabilityPtr;
2340     IoDev->Pci.Read (IoDev, EfiPciWidthUint16, RegAddress, 1, &CapabilityEntry);
2341
2342     CapabilityID = (UINT8) CapabilityEntry;
2343
2344     //
2345     // Explain PciExpress data
2346     //
2347     if (EFI_PCI_CAPABILITY_ID_PCIEXP == CapabilityID) {
2348       PciExplainPciExpress (IoDev, Address, CapabilityPtr);
2349       return EFI_SUCCESS;
2350     }
2351     //
2352     // Explain other capabilities here
2353     //
2354     CapabilityPtr = (UINT8) (CapabilityEntry >> 8);
2355   }
2356
2357   return EFI_SUCCESS;
2358 }
2359
2360 EFI_STATUS
2361 ExplainPcieCapReg (
2362   IN PCIE_CAP_STURCTURE *PciExpressCap
2363 )
2364 {
2365   UINT16 PcieCapReg;
2366   CHAR16 *DevicePortType;
2367
2368   PcieCapReg = PciExpressCap->PcieCapReg;
2369   Print (
2370     L"  Capability Version(3:0):          %E0x%04x%N\n",
2371     PCIE_CAP_VERSION (PcieCapReg)
2372     );
2373   if ((UINT8) PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) < PCIE_DEVICE_PORT_TYPE_MAX) {
2374     DevicePortType = DevicePortTypeTable[PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg)];
2375   } else {
2376     DevicePortType = L"Unknown Type";
2377   }
2378   Print (
2379     L"  Device/PortType(7:4):             %E%s%N\n",
2380     DevicePortType
2381     );
2382   //
2383   // 'Slot Implemented' is only valid for:
2384   // a) Root Port of PCI Express Root Complex, or
2385   // b) Downstream Port of PCI Express Switch
2386   //
2387   if (PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_ROOT_COMPLEX_ROOT_PORT ||
2388       PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_SWITCH_DOWNSTREAM_PORT) {
2389     Print (
2390       L"  Slot Implemented(8):              %E%d%N\n",
2391       PCIE_CAP_SLOT_IMPLEMENTED (PcieCapReg)
2392       );
2393   }
2394   Print (
2395     L"  Interrupt Message Number(13:9):   %E0x%05x%N\n",
2396     PCIE_CAP_INT_MSG_NUM (PcieCapReg)
2397     );
2398   return EFI_SUCCESS;
2399 }
2400
2401 EFI_STATUS
2402 ExplainPcieDeviceCap (
2403   IN PCIE_CAP_STURCTURE *PciExpressCap
2404 )
2405 {
2406   UINT16 PcieCapReg;
2407   UINT32 PcieDeviceCap;
2408   UINT8  DevicePortType;
2409   UINT8  L0sLatency;
2410   UINT8  L1Latency;
2411
2412   PcieCapReg     = PciExpressCap->PcieCapReg;
2413   PcieDeviceCap  = PciExpressCap->PcieDeviceCap;
2414   DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg);
2415   Print (L"  Max_Payload_Size Supported(2:0):          ");
2416   if (PCIE_CAP_MAX_PAYLOAD (PcieDeviceCap) < 6) {
2417     Print (L"%E%d bytes%N\n", 1 << (PCIE_CAP_MAX_PAYLOAD (PcieDeviceCap) + 7));
2418   } else {
2419     Print (L"%EUnknown%N\n");
2420   }
2421   Print (
2422     L"  Phantom Functions Supported(4:3):         %E%d%N\n",
2423     PCIE_CAP_PHANTOM_FUNC (PcieDeviceCap)
2424     );
2425   Print (
2426     L"  Extended Tag Field Supported(5):          %E%d-bit Tag field supported%N\n",
2427     PCIE_CAP_EXTENDED_TAG (PcieDeviceCap) ? 8 : 5
2428     );
2429   //
2430   // Endpoint L0s and L1 Acceptable Latency is only valid for Endpoint
2431   //
2432   if (IS_PCIE_ENDPOINT (DevicePortType)) {
2433     L0sLatency = (UINT8) PCIE_CAP_L0sLatency (PcieDeviceCap);
2434     L1Latency  = (UINT8) PCIE_CAP_L1Latency (PcieDeviceCap);
2435     Print (L"  Endpoint L0s Acceptable Latency(8:6):     ");
2436     if (L0sLatency < 4) {
2437       Print (L"%EMaximum of %d ns%N\n", 1 << (L0sLatency + 6));
2438     } else {
2439       if (L0sLatency < 7) {
2440         Print (L"%EMaximum of %d us%N\n", 1 << (L0sLatency - 3));
2441       } else {
2442         Print (L"%ENo limit%N\n");
2443       }
2444     }
2445     Print (L"  Endpoint L1 Acceptable Latency(11:9):     ");
2446     if (L1Latency < 7) {
2447       Print (L"%EMaximum of %d us%N\n", 1 << (L1Latency + 1));
2448     } else {
2449       Print (L"%ENo limit%N\n");
2450     }
2451   }
2452   Print (
2453     L"  Role-based Error Reporting(15):           %E%d%N\n",
2454     PCIE_CAP_ERR_REPORTING (PcieDeviceCap)
2455     );
2456   //
2457   // Only valid for Upstream Port:
2458   // a) Captured Slot Power Limit Value
2459   // b) Captured Slot Power Scale
2460   //
2461   if (DevicePortType == PCIE_SWITCH_UPSTREAM_PORT) {
2462     Print (
2463       L"  Captured Slot Power Limit Value(25:18):   %E0x%02x%N\n",
2464       PCIE_CAP_SLOT_POWER_VALUE (PcieDeviceCap)
2465       );
2466     Print (
2467       L"  Captured Slot Power Limit Scale(27:26):   %E%s%N\n",
2468       SlotPwrLmtScaleTable[PCIE_CAP_SLOT_POWER_SCALE (PcieDeviceCap)]
2469       );
2470   }
2471   //
2472   // Function Level Reset Capability is only valid for Endpoint
2473   //
2474   if (IS_PCIE_ENDPOINT (DevicePortType)) {
2475     Print (
2476       L"  Function Level Reset Capability(28):      %E%d%N\n",
2477       PCIE_CAP_FUNC_LEVEL_RESET (PcieDeviceCap)
2478       );
2479   }
2480   return EFI_SUCCESS;
2481 }
2482
2483 EFI_STATUS
2484 ExplainPcieDeviceControl (
2485   IN PCIE_CAP_STURCTURE *PciExpressCap
2486 )
2487 {
2488   UINT16 PcieCapReg;
2489   UINT16 PcieDeviceControl;
2490
2491   PcieCapReg        = PciExpressCap->PcieCapReg;
2492   PcieDeviceControl = PciExpressCap->DeviceControl;
2493   Print (
2494     L"  Correctable Error Reporting Enable(0):    %E%d%N\n",
2495     PCIE_CAP_COR_ERR_REPORTING_ENABLE (PcieDeviceControl)
2496     );
2497   Print (
2498     L"  Non-Fatal Error Reporting Enable(1):      %E%d%N\n",
2499     PCIE_CAP_NONFAT_ERR_REPORTING_ENABLE (PcieDeviceControl)
2500     );
2501   Print (
2502     L"  Fatal Error Reporting Enable(2):          %E%d%N\n",
2503     PCIE_CAP_FATAL_ERR_REPORTING_ENABLE (PcieDeviceControl)
2504     );
2505   Print (
2506     L"  Unsupported Request Reporting Enable(3):  %E%d%N\n",
2507     PCIE_CAP_UNSUP_REQ_REPORTING_ENABLE (PcieDeviceControl)
2508     );
2509   Print (
2510     L"  Enable Relaxed Ordering(4):               %E%d%N\n",
2511     PCIE_CAP_RELAXED_ORDERING_ENABLE (PcieDeviceControl)
2512     );
2513   Print (L"  Max_Payload_Size(7:5):                    ");
2514   if (PCIE_CAP_MAX_PAYLOAD_SIZE (PcieDeviceControl) < 6) {
2515     Print (L"%E%d bytes%N\n", 1 << (PCIE_CAP_MAX_PAYLOAD_SIZE (PcieDeviceControl) + 7));
2516   } else {
2517     Print (L"%EUnknown%N\n");
2518   }
2519   Print (
2520     L"  Extended Tag Field Enable(8):             %E%d%N\n",
2521     PCIE_CAP_EXTENDED_TAG_ENABLE (PcieDeviceControl)
2522     );
2523   Print (
2524     L"  Phantom Functions Enable(9):              %E%d%N\n",
2525     PCIE_CAP_PHANTOM_FUNC_ENABLE (PcieDeviceControl)
2526     );
2527   Print (
2528     L"  Auxiliary (AUX) Power PM Enable(10):      %E%d%N\n",
2529     PCIE_CAP_AUX_PM_ENABLE (PcieDeviceControl)
2530     );
2531   Print (
2532     L"  Enable No Snoop(11):                      %E%d%N\n",
2533     PCIE_CAP_NO_SNOOP_ENABLE (PcieDeviceControl)
2534     );
2535   Print (L"  Max_Read_Request_Size(14:12):             ");
2536   if (PCIE_CAP_MAX_READ_REQ_SIZE (PcieDeviceControl) < 6) {
2537     Print (L"%E%d bytes%N\n", 1 << (PCIE_CAP_MAX_READ_REQ_SIZE (PcieDeviceControl) + 7));
2538   } else {
2539     Print (L"%EUnknown%N\n");
2540   }
2541   //
2542   // Read operation is only valid for PCI Express to PCI/PCI-X Bridges
2543   //
2544   if (PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_PCIE_TO_PCIX_BRIDGE) {
2545     Print (
2546       L"  Bridge Configuration Retry Enable(15):  %E%d%N\n",
2547       PCIE_CAP_BRG_CONF_RETRY (PcieDeviceControl)
2548       );
2549   }
2550   return EFI_SUCCESS;
2551 }
2552
2553 EFI_STATUS
2554 ExplainPcieDeviceStatus (
2555   IN PCIE_CAP_STURCTURE *PciExpressCap
2556 )
2557 {
2558   UINT16 PcieDeviceStatus;
2559
2560   PcieDeviceStatus = PciExpressCap->DeviceStatus;
2561   Print (
2562     L"  Correctable Error Detected(0):            %E%d%N\n",
2563     PCIE_CAP_COR_ERR_DETECTED (PcieDeviceStatus)
2564     );
2565   Print (
2566     L"  Non-Fatal Error Detected(1):              %E%d%N\n",
2567     PCIE_CAP_NONFAT_ERR_DETECTED (PcieDeviceStatus)
2568     );
2569   Print (
2570     L"  Fatal Error Detected(2):                  %E%d%N\n",
2571     PCIE_CAP_FATAL_ERR_DETECTED (PcieDeviceStatus)
2572     );
2573   Print (
2574     L"  Unsupported Request Detected(3):          %E%d%N\n",
2575     PCIE_CAP_UNSUP_REQ_DETECTED (PcieDeviceStatus)
2576     );
2577   Print (
2578     L"  AUX Power Detected(4):                    %E%d%N\n",
2579     PCIE_CAP_AUX_POWER_DETECTED (PcieDeviceStatus)
2580     );
2581   Print (
2582     L"  Transactions Pending(5):                  %E%d%N\n",
2583     PCIE_CAP_TRANSACTION_PENDING (PcieDeviceStatus)
2584     );
2585   return EFI_SUCCESS;
2586 }
2587
2588 EFI_STATUS
2589 ExplainPcieLinkCap (
2590   IN PCIE_CAP_STURCTURE *PciExpressCap
2591 )
2592 {
2593   UINT32 PcieLinkCap;
2594   CHAR16 *SupLinkSpeeds;
2595   CHAR16 *ASPM;
2596
2597   PcieLinkCap = PciExpressCap->LinkCap;
2598   switch (PCIE_CAP_SUP_LINK_SPEEDS (PcieLinkCap)) {
2599     case 1:
2600       SupLinkSpeeds = L"2.5 GT/s";
2601       break;
2602     case 2:
2603       SupLinkSpeeds = L"5.0 GT/s and 2.5 GT/s";
2604       break;
2605     default:
2606       SupLinkSpeeds = L"Unknown";
2607       break;
2608   }
2609   Print (
2610     L"  Supported Link Speeds(3:0):                         %E%s supported%N\n",
2611     SupLinkSpeeds
2612     );
2613   Print (
2614     L"  Maximum Link Width(9:4):                            %Ex%d%N\n",
2615     PCIE_CAP_MAX_LINK_WIDTH (PcieLinkCap)
2616     );
2617   switch (PCIE_CAP_ASPM_SUPPORT (PcieLinkCap)) {
2618     case 1:
2619       ASPM = L"L0s Entry";
2620       break;
2621     case 3:
2622       ASPM = L"L0s and L1";
2623       break;
2624     default:
2625       ASPM = L"Reserved";
2626       break;
2627   }
2628   Print (
2629     L"  Active State Power Management Support(11:10):       %E%s Supported%N\n",
2630     ASPM
2631     );
2632   Print (
2633     L"  L0s Exit Latency(14:12):                            %E%s%N\n",
2634     L0sLatencyStrTable[PCIE_CAP_L0s_LATENCY (PcieLinkCap)]
2635     );
2636   Print (
2637     L"  L1 Exit Latency(17:15):                             %E%s%N\n",
2638     L1LatencyStrTable[PCIE_CAP_L0s_LATENCY (PcieLinkCap)]
2639     );
2640   Print (
2641     L"  Clock Power Management(18):                         %E%d%N\n",
2642     PCIE_CAP_CLOCK_PM (PcieLinkCap)
2643     );
2644   Print (
2645     L"  Surprise Down Error Reporting Capable(19):          %E%d%N\n",
2646     PCIE_CAP_SUP_DOWN_ERR_REPORTING (PcieLinkCap)
2647     );
2648   Print (
2649     L"  Data Link Layer Link Active Reporting Capable(20):  %E%d%N\n",
2650     PCIE_CAP_LINK_ACTIVE_REPORTING (PcieLinkCap)
2651     );
2652   Print (
2653     L"  Link Bandwidth Notification Capability(21):         %E%d%N\n",
2654     PCIE_CAP_LINK_BWD_NOTIF_CAP (PcieLinkCap)
2655     );
2656   Print (
2657     L"  Port Number(31:24):                                 %E0x%02x%N\n",
2658     PCIE_CAP_PORT_NUMBER (PcieLinkCap)
2659     );
2660   return EFI_SUCCESS;
2661 }
2662
2663 EFI_STATUS
2664 ExplainPcieLinkControl (
2665   IN PCIE_CAP_STURCTURE *PciExpressCap
2666 )
2667 {
2668   UINT16 PcieLinkControl;
2669   UINT8  DevicePortType;
2670
2671   PcieLinkControl = PciExpressCap->LinkControl;
2672   DevicePortType  = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PciExpressCap->PcieCapReg);
2673   Print (
2674     L"  Active State Power Management Control(1:0):         %E%s%N\n",
2675     ASPMCtrlStrTable[PCIE_CAP_ASPM_CONTROL (PcieLinkControl)]
2676     );
2677   //
2678   // RCB is not applicable to switches
2679   //
2680   if (!IS_PCIE_SWITCH(DevicePortType)) {
2681     Print (
2682       L"  Read Completion Boundary (RCB)(3):                  %E%d byte%N\n",
2683       1 << (PCIE_CAP_RCB (PcieLinkControl) + 6)
2684       );
2685   }
2686   //
2687   // Link Disable is reserved on
2688   // a) Endpoints
2689   // b) PCI Express to PCI/PCI-X bridges
2690   // c) Upstream Ports of Switches
2691   //
2692   if (!IS_PCIE_ENDPOINT (DevicePortType) &&
2693       DevicePortType != PCIE_SWITCH_UPSTREAM_PORT &&
2694       DevicePortType != PCIE_PCIE_TO_PCIX_BRIDGE) {
2695     Print (
2696       L"  Link Disable(4):                                    %E%d%N\n",
2697       PCIE_CAP_LINK_DISABLE (PcieLinkControl)
2698       );
2699   }
2700   Print (
2701     L"  Common Clock Configuration(6):                      %E%d%N\n",
2702     PCIE_CAP_COMMON_CLK_CONF (PcieLinkControl)
2703     );
2704   Print (
2705     L"  Extended Synch(7):                                  %E%d%N\n",
2706     PCIE_CAP_EXT_SYNC (PcieLinkControl)
2707     );
2708   Print (
2709     L"  Enable Clock Power Management(8):                   %E%d%N\n",
2710     PCIE_CAP_CLK_PWR_MNG (PcieLinkControl)
2711     );
2712   Print (
2713     L"  Hardware Autonomous Width Disable(9):               %E%d%N\n",
2714     PCIE_CAP_HW_AUTO_WIDTH_DISABLE (PcieLinkControl)
2715     );
2716   Print (
2717     L"  Link Bandwidth Management Interrupt Enable(10):     %E%d%N\n",
2718     PCIE_CAP_LINK_BDW_MNG_INT_EN (PcieLinkControl)
2719     );
2720   Print (
2721     L"  Link Autonomous Bandwidth Interrupt Enable(11):     %E%d%N\n",
2722     PCIE_CAP_LINK_AUTO_BDW_INT_EN (PcieLinkControl)
2723     );
2724   return EFI_SUCCESS;
2725 }
2726
2727 EFI_STATUS
2728 ExplainPcieLinkStatus (
2729   IN PCIE_CAP_STURCTURE *PciExpressCap
2730 )
2731 {
2732   UINT16 PcieLinkStatus;
2733   CHAR16 *SupLinkSpeeds;
2734
2735   PcieLinkStatus = PciExpressCap->LinkStatus;
2736   switch (PCIE_CAP_CUR_LINK_SPEED (PcieLinkStatus)) {
2737     case 1:
2738       SupLinkSpeeds = L"2.5 GT/s";
2739       break;
2740     case 2:
2741       SupLinkSpeeds = L"5.0 GT/s";
2742       break;
2743     default:
2744       SupLinkSpeeds = L"Reserved";
2745       break;
2746   }
2747   Print (
2748     L"  Current Link Speed(3:0):                            %E%s%N\n",
2749     SupLinkSpeeds
2750     );
2751   Print (
2752     L"  Negotiated Link Width(9:4):                         %Ex%d%N\n",
2753     PCIE_CAP_NEGO_LINK_WIDTH (PcieLinkStatus)
2754     );
2755   Print (
2756     L"  Link Training(11):                                  %E%d%N\n",
2757     PCIE_CAP_LINK_TRAINING (PcieLinkStatus)
2758     );
2759   Print (
2760     L"  Slot Clock Configuration(12):                       %E%d%N\n",
2761     PCIE_CAP_SLOT_CLK_CONF (PcieLinkStatus)
2762     );
2763   Print (
2764     L"  Data Link Layer Link Active(13):                    %E%d%N\n",
2765     PCIE_CAP_DATA_LINK_ACTIVE (PcieLinkStatus)
2766     );
2767   Print (
2768     L"  Link Bandwidth Management Status(14):               %E%d%N\n",
2769     PCIE_CAP_LINK_BDW_MNG_STAT (PcieLinkStatus)
2770     );
2771   Print (
2772     L"  Link Autonomous Bandwidth Status(15):               %E%d%N\n",
2773     PCIE_CAP_LINK_AUTO_BDW_STAT (PcieLinkStatus)
2774     );
2775   return EFI_SUCCESS;
2776 }
2777
2778 EFI_STATUS
2779 ExplainPcieSlotCap (
2780   IN PCIE_CAP_STURCTURE *PciExpressCap
2781 )
2782 {
2783   UINT32 PcieSlotCap;
2784
2785   PcieSlotCap = PciExpressCap->SlotCap;
2786
2787   Print (
2788     L"  Attention Button Present(0):                        %E%d%N\n",
2789     PCIE_CAP_ATT_BUT_PRESENT (PcieSlotCap)
2790     );
2791   Print (
2792     L"  Power Controller Present(1):                        %E%d%N\n",
2793     PCIE_CAP_PWR_CTRLLER_PRESENT (PcieSlotCap)
2794     );
2795   Print (
2796     L"  MRL Sensor Present(2):                              %E%d%N\n",
2797     PCIE_CAP_MRL_SENSOR_PRESENT (PcieSlotCap)
2798     );
2799   Print (
2800     L"  Attention Indicator Present(3):                     %E%d%N\n",
2801     PCIE_CAP_ATT_IND_PRESENT (PcieSlotCap)
2802     );
2803   Print (
2804     L"  Power Indicator Present(4):                         %E%d%N\n",
2805     PCIE_CAP_PWD_IND_PRESENT (PcieSlotCap)
2806     );
2807   Print (
2808     L"  Hot-Plug Surprise(5):                               %E%d%N\n",
2809     PCIE_CAP_HOTPLUG_SUPPRISE (PcieSlotCap)
2810     );
2811   Print (
2812     L"  Hot-Plug Capable(6):                                %E%d%N\n",
2813     PCIE_CAP_HOTPLUG_CAPABLE (PcieSlotCap)
2814     );
2815   Print (
2816     L"  Slot Power Limit Value(14:7):                       %E0x%02x%N\n",
2817     PCIE_CAP_SLOT_PWR_LIMIT_VALUE (PcieSlotCap)
2818     );
2819   Print (
2820     L"  Slot Power Limit Scale(16:15):                      %E%s%N\n",
2821     SlotPwrLmtScaleTable[PCIE_CAP_SLOT_PWR_LIMIT_SCALE (PcieSlotCap)]
2822     );
2823   Print (
2824     L"  Electromechanical Interlock Present(17):            %E%d%N\n",
2825     PCIE_CAP_ELEC_INTERLOCK_PRESENT (PcieSlotCap)
2826     );
2827   Print (
2828     L"  No Command Completed Support(18):                   %E%d%N\n",
2829     PCIE_CAP_NO_COMM_COMPLETED_SUP (PcieSlotCap)
2830     );
2831   Print (
2832     L"  Physical Slot Number(31:19):                        %E%d%N\n",
2833     PCIE_CAP_PHY_SLOT_NUM (PcieSlotCap)
2834     );
2835     
2836   return EFI_SUCCESS;
2837 }
2838
2839 EFI_STATUS
2840 ExplainPcieSlotControl (
2841   IN PCIE_CAP_STURCTURE *PciExpressCap
2842 )
2843 {
2844   UINT16 PcieSlotControl;
2845
2846   PcieSlotControl = PciExpressCap->SlotControl;
2847   Print (
2848     L"  Attention Button Pressed Enable(0):                 %E%d%N\n",
2849     PCIE_CAP_ATT_BUT_ENABLE (PcieSlotControl)
2850     );
2851   Print (
2852     L"  Power Fault Detected Enable(1):                     %E%d%N\n",
2853     PCIE_CAP_PWR_FLT_DETECT_ENABLE (PcieSlotControl)
2854     );
2855   Print (
2856     L"  MRL Sensor Changed Enable(2):                       %E%d%N\n",
2857     PCIE_CAP_MRL_SENSOR_CHANGE_ENABLE (PcieSlotControl)
2858     );
2859   Print (
2860     L"  Presence Detect Changed Enable(3):                  %E%d%N\n",
2861     PCIE_CAP_PRES_DETECT_CHANGE_ENABLE (PcieSlotControl)
2862     );
2863   Print (
2864     L"  Command Completed Interrupt Enable(4):              %E%d%N\n",
2865     PCIE_CAP_COMM_CMPL_INT_ENABLE (PcieSlotControl)
2866     );
2867   Print (
2868     L"  Hot-Plug Interrupt Enable(5):                       %E%d%N\n",
2869     PCIE_CAP_HOTPLUG_INT_ENABLE (PcieSlotControl)
2870     );
2871   Print (
2872     L"  Attention Indicator Control(7:6):                   %E%s%N\n",
2873     IndicatorTable[PCIE_CAP_ATT_IND_CTRL (PcieSlotControl)]
2874     );
2875   Print (
2876     L"  Power Indicator Control(9:8):                       %E%s%N\n",
2877     IndicatorTable[PCIE_CAP_PWR_IND_CTRL (PcieSlotControl)]
2878     );
2879   Print (L"  Power Controller Control(10):                       %EPower ");
2880   if (PCIE_CAP_PWR_CTRLLER_CTRL (PcieSlotControl)) {
2881     Print (L"Off%N\n");
2882   } else {
2883     Print (L"On%N\n");
2884   }
2885   Print (
2886     L"  Electromechanical Interlock Control(11):            %E%d%N\n",
2887     PCIE_CAP_ELEC_INTERLOCK_CTRL (PcieSlotControl)
2888     );
2889   Print (
2890     L"  Data Link Layer State Changed Enable(12):           %E%d%N\n",
2891     PCIE_CAP_DLINK_STAT_CHANGE_ENABLE (PcieSlotControl)
2892     );
2893   return EFI_SUCCESS;
2894 }
2895
2896 EFI_STATUS
2897 ExplainPcieSlotStatus (
2898   IN PCIE_CAP_STURCTURE *PciExpressCap
2899 )
2900 {
2901   UINT16 PcieSlotStatus;
2902
2903   PcieSlotStatus = PciExpressCap->SlotStatus;
2904
2905   Print (
2906     L"  Attention Button Pressed(0):           %E%d%N\n",
2907     PCIE_CAP_ATT_BUT_PRESSED (PcieSlotStatus)
2908     );
2909   Print (
2910     L"  Power Fault Detected(1):               %E%d%N\n",
2911     PCIE_CAP_PWR_FLT_DETECTED (PcieSlotStatus)
2912     );
2913   Print (
2914     L"  MRL Sensor Changed(2):                 %E%d%N\n",
2915     PCIE_CAP_MRL_SENSOR_CHANGED (PcieSlotStatus)
2916     );
2917   Print (
2918     L"  Presence Detect Changed(3):            %E%d%N\n",
2919     PCIE_CAP_PRES_DETECT_CHANGED (PcieSlotStatus)
2920     );
2921   Print (
2922     L"  Command Completed(4):                  %E%d%N\n",
2923     PCIE_CAP_COMM_COMPLETED (PcieSlotStatus)
2924     );
2925   Print (L"  MRL Sensor State(5):                   %EMRL ");
2926   if (PCIE_CAP_MRL_SENSOR_STATE (PcieSlotStatus)) {
2927     Print (L" Opened%N\n");
2928   } else {
2929     Print (L" Closed%N\n");
2930   }
2931   Print (L"  Presence Detect State(6):              ");
2932   if (PCIE_CAP_PRES_DETECT_STATE (PcieSlotStatus)) {
2933     Print (L"%ECard Present in slot%N\n");
2934   } else {
2935     Print (L"%ESlot Empty%N\n");
2936   }
2937   Print (L"  Electromechanical Interlock Status(7): %EElectromechanical Interlock ");
2938   if (PCIE_CAP_ELEC_INTERLOCK_STATE (PcieSlotStatus)) {
2939     Print (L"Engaged%N\n");
2940   } else {
2941     Print (L"Disengaged%N\n");
2942   }
2943   Print (
2944     L"  Data Link Layer State Changed(8):      %E%d%N\n",
2945     PCIE_CAP_DLINK_STAT_CHANGED (PcieSlotStatus)
2946     );
2947   return EFI_SUCCESS;
2948 }
2949
2950 EFI_STATUS
2951 ExplainPcieRootControl (
2952   IN PCIE_CAP_STURCTURE *PciExpressCap
2953 )
2954 {
2955   UINT16 PcieRootControl;
2956
2957   PcieRootControl = PciExpressCap->RootControl;
2958
2959   Print (
2960     L"  System Error on Correctable Error Enable(0):  %E%d%N\n",
2961     PCIE_CAP_SYSERR_ON_CORERR_EN (PcieRootControl)
2962     );
2963   Print (
2964     L"  System Error on Non-Fatal Error Enable(1):    %E%d%N\n",
2965     PCIE_CAP_SYSERR_ON_NONFATERR_EN (PcieRootControl)
2966     );
2967   Print (
2968     L"  System Error on Fatal Error Enable(2):        %E%d%N\n",
2969     PCIE_CAP_SYSERR_ON_FATERR_EN (PcieRootControl)
2970     );
2971   Print (
2972     L"  PME Interrupt Enable(3):                      %E%d%N\n",
2973     PCIE_CAP_PME_INT_ENABLE (PcieRootControl)
2974     );
2975   Print (
2976     L"  CRS Software Visibility Enable(4):            %E%d%N\n",
2977     PCIE_CAP_CRS_SW_VIS_ENABLE (PcieRootControl)
2978     );
2979     
2980   return EFI_SUCCESS;
2981 }
2982
2983 EFI_STATUS
2984 ExplainPcieRootCap (
2985   IN PCIE_CAP_STURCTURE *PciExpressCap
2986 )
2987 {
2988   UINT16 PcieRootCap;
2989
2990   PcieRootCap = PciExpressCap->RsvdP;
2991
2992   Print (
2993     L"  CRS Software Visibility(0):                   %E%d%N\n",
2994     PCIE_CAP_CRS_SW_VIS (PcieRootCap)
2995     );
2996
2997   return EFI_SUCCESS;
2998 }
2999
3000 EFI_STATUS
3001 ExplainPcieRootStatus (
3002   IN PCIE_CAP_STURCTURE *PciExpressCap
3003 )
3004 {
3005   UINT32 PcieRootStatus;
3006
3007   PcieRootStatus = PciExpressCap->RootStatus;
3008
3009   Print (
3010     L"  PME Requester ID(15:0):                       %E0x%04x%N\n",
3011     PCIE_CAP_PME_REQ_ID (PcieRootStatus)
3012     );
3013   Print (
3014     L"  PME Status(16):                               %E%d%N\n",
3015     PCIE_CAP_PME_STATUS (PcieRootStatus)
3016     );
3017   Print (
3018     L"  PME Pending(17):                              %E%d%N\n",
3019     PCIE_CAP_PME_PENDING (PcieRootStatus)
3020     );
3021   return EFI_SUCCESS;
3022 }
3023
3024 EFI_STATUS
3025 PciExplainPciExpress (
3026   IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         *IoDev,
3027   IN  UINT64                                  Address,
3028   IN  UINT8                                   CapabilityPtr
3029   )
3030 {
3031
3032   PCIE_CAP_STURCTURE  PciExpressCap;
3033   EFI_STATUS          Status;
3034   UINT64              CapRegAddress;
3035   UINT8               Bus;
3036   UINT8               Dev;
3037   UINT8               Func;
3038   UINT8               *ExRegBuffer;
3039   UINTN               ExtendRegSize;
3040   UINT64              Pciex_Address;
3041   UINT8               DevicePortType;
3042   UINTN               Index;
3043   UINT8               *RegAddr;
3044   UINTN               RegValue;
3045
3046   CapRegAddress = Address + CapabilityPtr;
3047   IoDev->Pci.Read (
3048               IoDev,
3049               EfiPciWidthUint32,
3050               CapRegAddress,
3051               sizeof (PciExpressCap) / sizeof (UINT32),
3052               &PciExpressCap
3053               );
3054
3055   DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PciExpressCap.PcieCapReg);
3056   
3057   Print (L"\nPci Express device capability structure:\n");
3058
3059   for (Index = 0; PcieExplainList[Index].Type < PcieExplainTypeMax; Index++) {
3060     if (GetExecutionBreak ()) {
3061       goto Done;
3062     }
3063     RegAddr = ((UINT8 *) &PciExpressCap) + PcieExplainList[Index].Offset;
3064     switch (PcieExplainList[Index].Width) {
3065       case FieldWidthUINT8:
3066         RegValue = *(UINT8 *) RegAddr;
3067         break;
3068       case FieldWidthUINT16:
3069         RegValue = *(UINT16 *) RegAddr;
3070         break;
3071       case FieldWidthUINT32:
3072         RegValue = *(UINT32 *) RegAddr;
3073         break;
3074       default:
3075         RegValue = 0;
3076         break;
3077     }
3078     PrintToken (
3079       PcieExplainList[Index].Token,
3080       HiiHandle,
3081       PcieExplainList[Index].Offset,
3082       RegValue
3083       );
3084     if (PcieExplainList[Index].Func == NULL) {
3085       continue;
3086     }
3087     switch (PcieExplainList[Index].Type) {
3088       case PcieExplainTypeLink:
3089         //
3090         // Link registers should not be used by
3091         // a) Root Complex Integrated Endpoint
3092         // b) Root Complex Event Collector
3093         //
3094         if (DevicePortType == PCIE_ROOT_COMPLEX_INTEGRATED_PORT ||
3095             DevicePortType == PCIE_ROOT_COMPLEX_EVENT_COLLECTOR) {
3096           continue;
3097         }
3098         break;
3099       case PcieExplainTypeSlot:
3100         //
3101         // Slot registers are only valid for
3102         // a) Root Port of PCI Express Root Complex
3103         // b) Downstream Port of PCI Express Switch
3104         // and when SlotImplemented bit is set in PCIE cap register.
3105         //
3106         if ((DevicePortType != PCIE_ROOT_COMPLEX_ROOT_PORT &&
3107              DevicePortType != PCIE_SWITCH_DOWNSTREAM_PORT) ||
3108             !PCIE_CAP_SLOT_IMPLEMENTED (PciExpressCap.PcieCapReg)) {
3109           continue;
3110         }
3111         break;
3112       case PcieExplainTypeRoot:
3113         //
3114         // Root registers are only valid for
3115         // Root Port of PCI Express Root Complex
3116         //
3117         if (DevicePortType != PCIE_ROOT_COMPLEX_ROOT_PORT) {
3118           continue;
3119         }
3120         break;
3121       default:
3122         break;
3123     }
3124     PcieExplainList[Index].Func (&PciExpressCap);
3125   }
3126
3127   Bus           = (UINT8) (RShiftU64 (Address, 24));
3128   Dev           = (UINT8) (RShiftU64 (Address, 16));
3129   Func          = (UINT8) (RShiftU64 (Address, 8));
3130
3131   Pciex_Address = CALC_EFI_PCIEX_ADDRESS (Bus, Dev, Func, 0x100);
3132
3133   ExtendRegSize = 0x1000 - 0x100;
3134
3135   ExRegBuffer   = (UINT8 *) AllocatePool (ExtendRegSize);
3136
3137   //
3138   // PciRootBridgeIo protocol should support pci express extend space IO
3139   // (Begins at offset 0x100)
3140   //
3141   Status = IoDev->Pci.Read (
3142                         IoDev,
3143                         EfiPciWidthUint32,
3144                         Pciex_Address,
3145                         (ExtendRegSize) / sizeof (UINT32),
3146                         (VOID *) (ExRegBuffer)
3147                         );
3148   if (EFI_ERROR (Status)) {
3149     FreePool ((VOID *) ExRegBuffer);
3150     return EFI_UNSUPPORTED;
3151   }
3152   //
3153   // Start outputing PciEx extend space( 0xFF-0xFFF)
3154   //
3155   Print (L"\n%HStart dumping PCIex extended configuration space (0x100 - 0xFFF).%N\n\n");
3156
3157   PrivateDumpHex (
3158     2,
3159     0x100,
3160     ExtendRegSize,
3161     (VOID *) (ExRegBuffer)
3162     );
3163
3164   FreePool ((VOID *) ExRegBuffer);
3165
3166 Done:
3167   return EFI_SUCCESS;
3168 }
3169
3170 EFI_STATUS
3171 InitializePciGetLineHelp (
3172   OUT CHAR16              **Str
3173   )
3174 /*++
3175
3176 Routine Description:
3177
3178   Get this command's line help
3179
3180 Arguments:
3181
3182   Str - The line help
3183
3184 Returns:
3185
3186   EFI_SUCCESS   - Success
3187
3188 --*/
3189 {
3190   return LibCmdGetStringByToken (
3191           STRING_ARRAY_NAME,
3192           &EfiPciGuid,
3193           STRING_TOKEN (STR_HELPINFO_PCI_LINEHELP),
3194           Str
3195           );
3196 }