~ubuntu-branches/ubuntu/wily/edk2/wily

« back to all changes in this revision

Viewing changes to ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c

  • Committer: Package Import Robot
  • Author(s): Steve Langasek
  • Date: 2013-02-10 13:11:25 UTC
  • Revision ID: package-import@ubuntu.com-20130210131125-0zwkb8f8m4ecia4m
Tags: upstream-0~20121205.edae8d2d
ImportĀ upstreamĀ versionĀ 0~20121205.edae8d2d

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
  Main file for Pci shell Debug1 function.
 
3
 
 
4
  Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
 
5
  This program and the accompanying materials
 
6
  are licensed and made available under the terms and conditions of the BSD License
 
7
  which accompanies this distribution.  The full text of the license may be found at
 
8
  http://opensource.org/licenses/bsd-license.php
 
9
 
 
10
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 
11
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 
12
 
 
13
**/
 
14
 
 
15
#include "UefiShellDebug1CommandsLib.h"
 
16
#include <Protocol/PciRootBridgeIo.h>
 
17
#include <Library/ShellLib.h>
 
18
#include <IndustryStandard/Pci.h>
 
19
#include <IndustryStandard/Acpi.h>
 
20
#include "Pci.h"
 
21
 
 
22
#define PCI_CLASS_STRING_LIMIT  54
 
23
//
 
24
// Printable strings for Pci class code
 
25
//
 
26
typedef struct {
 
27
  CHAR16  *BaseClass; // Pointer to the PCI base class string
 
28
  CHAR16  *SubClass;  // Pointer to the PCI sub class string
 
29
  CHAR16  *PIFClass;  // Pointer to the PCI programming interface string
 
30
} PCI_CLASS_STRINGS;
 
31
 
 
32
//
 
33
// a structure holding a single entry, which also points to its lower level
 
34
// class
 
35
//
 
36
typedef struct PCI_CLASS_ENTRY_TAG {
 
37
  UINT8                       Code;             // Class, subclass or I/F code
 
38
  CHAR16                      *DescText;        // Description string
 
39
  struct PCI_CLASS_ENTRY_TAG  *LowerLevelClass; // Subclass or I/F if any
 
40
} PCI_CLASS_ENTRY;
 
41
 
 
42
//
 
43
// Declarations of entries which contain printable strings for class codes
 
44
// in PCI configuration space
 
45
//
 
46
PCI_CLASS_ENTRY PCIBlankEntry[];
 
47
PCI_CLASS_ENTRY PCISubClass_00[];
 
48
PCI_CLASS_ENTRY PCISubClass_01[];
 
49
PCI_CLASS_ENTRY PCISubClass_02[];
 
50
PCI_CLASS_ENTRY PCISubClass_03[];
 
51
PCI_CLASS_ENTRY PCISubClass_04[];
 
52
PCI_CLASS_ENTRY PCISubClass_05[];
 
53
PCI_CLASS_ENTRY PCISubClass_06[];
 
54
PCI_CLASS_ENTRY PCISubClass_07[];
 
55
PCI_CLASS_ENTRY PCISubClass_08[];
 
56
PCI_CLASS_ENTRY PCISubClass_09[];
 
57
PCI_CLASS_ENTRY PCISubClass_0a[];
 
58
PCI_CLASS_ENTRY PCISubClass_0b[];
 
59
PCI_CLASS_ENTRY PCISubClass_0c[];
 
60
PCI_CLASS_ENTRY PCISubClass_0d[];
 
61
PCI_CLASS_ENTRY PCISubClass_0e[];
 
62
PCI_CLASS_ENTRY PCISubClass_0f[];
 
63
PCI_CLASS_ENTRY PCISubClass_10[];
 
64
PCI_CLASS_ENTRY PCISubClass_11[];
 
65
PCI_CLASS_ENTRY PCIPIFClass_0101[];
 
66
PCI_CLASS_ENTRY PCIPIFClass_0300[];
 
67
PCI_CLASS_ENTRY PCIPIFClass_0604[];
 
68
PCI_CLASS_ENTRY PCIPIFClass_0700[];
 
69
PCI_CLASS_ENTRY PCIPIFClass_0701[];
 
70
PCI_CLASS_ENTRY PCIPIFClass_0703[];
 
71
PCI_CLASS_ENTRY PCIPIFClass_0800[];
 
72
PCI_CLASS_ENTRY PCIPIFClass_0801[];
 
73
PCI_CLASS_ENTRY PCIPIFClass_0802[];
 
74
PCI_CLASS_ENTRY PCIPIFClass_0803[];
 
75
PCI_CLASS_ENTRY PCIPIFClass_0904[];
 
76
PCI_CLASS_ENTRY PCIPIFClass_0c00[];
 
77
PCI_CLASS_ENTRY PCIPIFClass_0c03[];
 
78
PCI_CLASS_ENTRY PCIPIFClass_0e00[];
 
79
 
 
80
//
 
81
// Base class strings entries
 
82
//
 
83
PCI_CLASS_ENTRY gClassStringList[] = {
 
84
  {
 
85
    0x00,
 
86
    L"Pre 2.0 device",
 
87
    PCISubClass_00
 
88
  },
 
89
  {
 
90
    0x01,
 
91
    L"Mass Storage Controller",
 
92
    PCISubClass_01
 
93
  },
 
94
  {
 
95
    0x02,
 
96
    L"Network Controller",
 
97
    PCISubClass_02
 
98
  },
 
99
  {
 
100
    0x03,
 
101
    L"Display Controller",
 
102
    PCISubClass_03
 
103
  },
 
104
  {
 
105
    0x04,
 
106
    L"Multimedia Device",
 
107
    PCISubClass_04
 
108
  },
 
109
  {
 
110
    0x05,
 
111
    L"Memory Controller",
 
112
    PCISubClass_05
 
113
  },
 
114
  {
 
115
    0x06,
 
116
    L"Bridge Device",
 
117
    PCISubClass_06
 
118
  },
 
119
  {
 
120
    0x07,
 
121
    L"Simple Communications Controllers",
 
122
    PCISubClass_07
 
123
  },
 
124
  {
 
125
    0x08,
 
126
    L"Base System Peripherals",
 
127
    PCISubClass_08
 
128
  },
 
129
  {
 
130
    0x09,
 
131
    L"Input Devices",
 
132
    PCISubClass_09
 
133
  },
 
134
  {
 
135
    0x0a,
 
136
    L"Docking Stations",
 
137
    PCISubClass_0a
 
138
  },
 
139
  {
 
140
    0x0b,
 
141
    L"Processors",
 
142
    PCISubClass_0b
 
143
  },
 
144
  {
 
145
    0x0c,
 
146
    L"Serial Bus Controllers",
 
147
    PCISubClass_0c
 
148
  },
 
149
  {
 
150
    0x0d,
 
151
    L"Wireless Controllers",
 
152
    PCISubClass_0d
 
153
  },
 
154
  {
 
155
    0x0e,
 
156
    L"Intelligent IO Controllers",
 
157
    PCISubClass_0e
 
158
  },
 
159
  {
 
160
    0x0f,
 
161
    L"Satellite Communications Controllers",
 
162
    PCISubClass_0f
 
163
  },
 
164
  {
 
165
    0x10,
 
166
    L"Encryption/Decryption Controllers",
 
167
    PCISubClass_10
 
168
  },
 
169
  {
 
170
    0x11,
 
171
    L"Data Acquisition & Signal Processing Controllers",
 
172
    PCISubClass_11
 
173
  },
 
174
  {
 
175
    0xff,
 
176
    L"Device does not fit in any defined classes",
 
177
    PCIBlankEntry
 
178
  },
 
179
  {
 
180
    0x00,
 
181
    NULL,
 
182
    /* null string ends the list */NULL
 
183
  }
 
184
};
 
185
 
 
186
//
 
187
// Subclass strings entries
 
188
//
 
189
PCI_CLASS_ENTRY PCIBlankEntry[] = {
 
190
  {
 
191
    0x00,
 
192
    L"",
 
193
    PCIBlankEntry
 
194
  },
 
195
  {
 
196
    0x00,
 
197
    NULL,
 
198
    /* null string ends the list */NULL
 
199
  }
 
200
};
 
201
 
 
202
PCI_CLASS_ENTRY PCISubClass_00[] = {
 
203
  {
 
204
    0x00,
 
205
    L"All devices other than VGA",
 
206
    PCIBlankEntry
 
207
  },
 
208
  {
 
209
    0x01,
 
210
    L"VGA-compatible devices",
 
211
    PCIBlankEntry
 
212
  },
 
213
  {
 
214
    0x00,
 
215
    NULL,
 
216
    /* null string ends the list */NULL
 
217
  }
 
218
};
 
219
 
 
220
PCI_CLASS_ENTRY PCISubClass_01[] = {
 
221
  {
 
222
    0x00,
 
223
    L"SCSI controller",
 
224
    PCIBlankEntry
 
225
  },
 
226
  {
 
227
    0x01,
 
228
    L"IDE controller",
 
229
    PCIPIFClass_0101
 
230
  },
 
231
  {
 
232
    0x02,
 
233
    L"Floppy disk controller",
 
234
    PCIBlankEntry
 
235
  },
 
236
  {
 
237
    0x03,
 
238
    L"IPI controller",
 
239
    PCIBlankEntry
 
240
  },
 
241
  {
 
242
    0x04,
 
243
    L"RAID controller",
 
244
    PCIBlankEntry
 
245
  },
 
246
  {
 
247
    0x80,
 
248
    L"Other mass storage controller",
 
249
    PCIBlankEntry
 
250
  },
 
251
  {
 
252
    0x00,
 
253
    NULL,
 
254
    /* null string ends the list */NULL
 
255
  }
 
256
};
 
257
 
 
258
PCI_CLASS_ENTRY PCISubClass_02[] = {
 
259
  {
 
260
    0x00,
 
261
    L"Ethernet controller",
 
262
    PCIBlankEntry
 
263
  },
 
264
  {
 
265
    0x01,
 
266
    L"Token ring controller",
 
267
    PCIBlankEntry
 
268
  },
 
269
  {
 
270
    0x02,
 
271
    L"FDDI controller",
 
272
    PCIBlankEntry
 
273
  },
 
274
  {
 
275
    0x03,
 
276
    L"ATM controller",
 
277
    PCIBlankEntry
 
278
  },
 
279
  {
 
280
    0x04,
 
281
    L"ISDN controller",
 
282
    PCIBlankEntry
 
283
  },
 
284
  {
 
285
    0x80,
 
286
    L"Other network controller",
 
287
    PCIBlankEntry
 
288
  },
 
289
  {
 
290
    0x00,
 
291
    NULL,
 
292
    /* null string ends the list */NULL
 
293
  }
 
294
};
 
295
 
 
296
PCI_CLASS_ENTRY PCISubClass_03[] = {
 
297
  {
 
298
    0x00,
 
299
    L"VGA/8514 controller",
 
300
    PCIPIFClass_0300
 
301
  },
 
302
  {
 
303
    0x01,
 
304
    L"XGA controller",
 
305
    PCIBlankEntry
 
306
  },
 
307
  {
 
308
    0x02,
 
309
    L"3D controller",
 
310
    PCIBlankEntry
 
311
  },
 
312
  {
 
313
    0x80,
 
314
    L"Other display controller",
 
315
    PCIBlankEntry
 
316
  },
 
317
  {
 
318
    0x00,
 
319
    NULL,
 
320
    /* null string ends the list */PCIBlankEntry
 
321
  }
 
322
};
 
323
 
 
324
PCI_CLASS_ENTRY PCISubClass_04[] = {
 
325
  {
 
326
    0x00,
 
327
    L"Video device",
 
328
    PCIBlankEntry
 
329
  },
 
330
  {
 
331
    0x01,
 
332
    L"Audio device",
 
333
    PCIBlankEntry
 
334
  },
 
335
  {
 
336
    0x02,
 
337
    L"Computer Telephony device",
 
338
    PCIBlankEntry
 
339
  },
 
340
  {
 
341
    0x80,
 
342
    L"Other multimedia device",
 
343
    PCIBlankEntry
 
344
  },
 
345
  {
 
346
    0x00,
 
347
    NULL,
 
348
    /* null string ends the list */NULL
 
349
  }
 
350
};
 
351
 
 
352
PCI_CLASS_ENTRY PCISubClass_05[] = {
 
353
  {
 
354
    0x00,
 
355
    L"RAM memory controller",
 
356
    PCIBlankEntry
 
357
  },
 
358
  {
 
359
    0x01,
 
360
    L"Flash memory controller",
 
361
    PCIBlankEntry
 
362
  },
 
363
  {
 
364
    0x80,
 
365
    L"Other memory controller",
 
366
    PCIBlankEntry
 
367
  },
 
368
  {
 
369
    0x00,
 
370
    NULL,
 
371
    /* null string ends the list */NULL
 
372
  }
 
373
};
 
374
 
 
375
PCI_CLASS_ENTRY PCISubClass_06[] = {
 
376
  {
 
377
    0x00,
 
378
    L"Host/PCI bridge",
 
379
    PCIBlankEntry
 
380
  },
 
381
  {
 
382
    0x01,
 
383
    L"PCI/ISA bridge",
 
384
    PCIBlankEntry
 
385
  },
 
386
  {
 
387
    0x02,
 
388
    L"PCI/EISA bridge",
 
389
    PCIBlankEntry
 
390
  },
 
391
  {
 
392
    0x03,
 
393
    L"PCI/Micro Channel bridge",
 
394
    PCIBlankEntry
 
395
  },
 
396
  {
 
397
    0x04,
 
398
    L"PCI/PCI bridge",
 
399
    PCIPIFClass_0604
 
400
  },
 
401
  {
 
402
    0x05,
 
403
    L"PCI/PCMCIA bridge",
 
404
    PCIBlankEntry
 
405
  },
 
406
  {
 
407
    0x06,
 
408
    L"NuBus bridge",
 
409
    PCIBlankEntry
 
410
  },
 
411
  {
 
412
    0x07,
 
413
    L"CardBus bridge",
 
414
    PCIBlankEntry
 
415
  },
 
416
  {
 
417
    0x08,
 
418
    L"RACEway bridge",
 
419
    PCIBlankEntry
 
420
  },
 
421
  {
 
422
    0x80,
 
423
    L"Other bridge type",
 
424
    PCIBlankEntry
 
425
  },
 
426
  {
 
427
    0x00,
 
428
    NULL,
 
429
    /* null string ends the list */NULL
 
430
  }
 
431
};
 
432
 
 
433
PCI_CLASS_ENTRY PCISubClass_07[] = {
 
434
  {
 
435
    0x00,
 
436
    L"Serial controller",
 
437
    PCIPIFClass_0700
 
438
  },
 
439
  {
 
440
    0x01,
 
441
    L"Parallel port",
 
442
    PCIPIFClass_0701
 
443
  },
 
444
  {
 
445
    0x02,
 
446
    L"Multiport serial controller",
 
447
    PCIBlankEntry
 
448
  },
 
449
  {
 
450
    0x03,
 
451
    L"Modem",
 
452
    PCIPIFClass_0703
 
453
  },
 
454
  {
 
455
    0x80,
 
456
    L"Other communication device",
 
457
    PCIBlankEntry
 
458
  },
 
459
  {
 
460
    0x00,
 
461
    NULL,
 
462
    /* null string ends the list */NULL
 
463
  }
 
464
};
 
465
 
 
466
PCI_CLASS_ENTRY PCISubClass_08[] = {
 
467
  {
 
468
    0x00,
 
469
    L"PIC",
 
470
    PCIPIFClass_0800
 
471
  },
 
472
  {
 
473
    0x01,
 
474
    L"DMA controller",
 
475
    PCIPIFClass_0801
 
476
  },
 
477
  {
 
478
    0x02,
 
479
    L"System timer",
 
480
    PCIPIFClass_0802
 
481
  },
 
482
  {
 
483
    0x03,
 
484
    L"RTC controller",
 
485
    PCIPIFClass_0803
 
486
  },
 
487
  {
 
488
    0x04,
 
489
    L"Generic PCI Hot-Plug controller",
 
490
    PCIBlankEntry
 
491
  },
 
492
  {
 
493
    0x80,
 
494
    L"Other system peripheral",
 
495
    PCIBlankEntry
 
496
  },
 
497
  {
 
498
    0x00,
 
499
    NULL,
 
500
    /* null string ends the list */NULL
 
501
  }
 
502
};
 
503
 
 
504
PCI_CLASS_ENTRY PCISubClass_09[] = {
 
505
  {
 
506
    0x00,
 
507
    L"Keyboard controller",
 
508
    PCIBlankEntry
 
509
  },
 
510
  {
 
511
    0x01,
 
512
    L"Digitizer (pen)",
 
513
    PCIBlankEntry
 
514
  },
 
515
  {
 
516
    0x02,
 
517
    L"Mouse controller",
 
518
    PCIBlankEntry
 
519
  },
 
520
  {
 
521
    0x03,
 
522
    L"Scanner controller",
 
523
    PCIBlankEntry
 
524
  },
 
525
  {
 
526
    0x04,
 
527
    L"Gameport controller",
 
528
    PCIPIFClass_0904
 
529
  },
 
530
  {
 
531
    0x80,
 
532
    L"Other input controller",
 
533
    PCIBlankEntry
 
534
  },
 
535
  {
 
536
    0x00,
 
537
    NULL,
 
538
    /* null string ends the list */NULL
 
539
  }
 
540
};
 
541
 
 
542
PCI_CLASS_ENTRY PCISubClass_0a[] = {
 
543
  {
 
544
    0x00,
 
545
    L"Generic docking station",
 
546
    PCIBlankEntry
 
547
  },
 
548
  {
 
549
    0x80,
 
550
    L"Other type of docking station",
 
551
    PCIBlankEntry
 
552
  },
 
553
  {
 
554
    0x00,
 
555
    NULL,
 
556
    /* null string ends the list */NULL
 
557
  }
 
558
};
 
559
 
 
560
PCI_CLASS_ENTRY PCISubClass_0b[] = {
 
561
  {
 
562
    0x00,
 
563
    L"386",
 
564
    PCIBlankEntry
 
565
  },
 
566
  {
 
567
    0x01,
 
568
    L"486",
 
569
    PCIBlankEntry
 
570
  },
 
571
  {
 
572
    0x02,
 
573
    L"Pentium",
 
574
    PCIBlankEntry
 
575
  },
 
576
  {
 
577
    0x10,
 
578
    L"Alpha",
 
579
    PCIBlankEntry
 
580
  },
 
581
  {
 
582
    0x20,
 
583
    L"PowerPC",
 
584
    PCIBlankEntry
 
585
  },
 
586
  {
 
587
    0x30,
 
588
    L"MIPS",
 
589
    PCIBlankEntry
 
590
  },
 
591
  {
 
592
    0x40,
 
593
    L"Co-processor",
 
594
    PCIBlankEntry
 
595
  },
 
596
  {
 
597
    0x80,
 
598
    L"Other processor",
 
599
    PCIBlankEntry
 
600
  },
 
601
  {
 
602
    0x00,
 
603
    NULL,
 
604
    /* null string ends the list */NULL
 
605
  }
 
606
};
 
607
 
 
608
PCI_CLASS_ENTRY PCISubClass_0c[] = {
 
609
  {
 
610
    0x00,
 
611
    L"Firewire(IEEE 1394)",
 
612
    PCIPIFClass_0c03
 
613
  },
 
614
  {
 
615
    0x01,
 
616
    L"ACCESS.bus",
 
617
    PCIBlankEntry
 
618
  },
 
619
  {
 
620
    0x02,
 
621
    L"SSA",
 
622
    PCIBlankEntry
 
623
  },
 
624
  {
 
625
    0x03,
 
626
    L"USB",
 
627
    PCIPIFClass_0c00
 
628
  },
 
629
  {
 
630
    0x04,
 
631
    L"Fibre Channel",
 
632
    PCIBlankEntry
 
633
  },
 
634
  {
 
635
    0x05,
 
636
    L"System Management Bus",
 
637
    PCIBlankEntry
 
638
  },
 
639
  {
 
640
    0x80,
 
641
    L"Other bus type",
 
642
    PCIBlankEntry
 
643
  },
 
644
  {
 
645
    0x00,
 
646
    NULL,
 
647
    /* null string ends the list */NULL
 
648
  }
 
649
};
 
650
 
 
651
PCI_CLASS_ENTRY PCISubClass_0d[] = {
 
652
  {
 
653
    0x00,
 
654
    L"iRDA compatible controller",
 
655
    PCIBlankEntry
 
656
  },
 
657
  {
 
658
    0x01,
 
659
    L"Consumer IR controller",
 
660
    PCIBlankEntry
 
661
  },
 
662
  {
 
663
    0x10,
 
664
    L"RF controller",
 
665
    PCIBlankEntry
 
666
  },
 
667
  {
 
668
    0x80,
 
669
    L"Other type of wireless controller",
 
670
    PCIBlankEntry
 
671
  },
 
672
  {
 
673
    0x00,
 
674
    NULL,
 
675
    /* null string ends the list */NULL
 
676
  }
 
677
};
 
678
 
 
679
PCI_CLASS_ENTRY PCISubClass_0e[] = {
 
680
  {
 
681
    0x00,
 
682
    L"I2O Architecture",
 
683
    PCIPIFClass_0e00
 
684
  },
 
685
  {
 
686
    0x00,
 
687
    NULL,
 
688
    /* null string ends the list */NULL
 
689
  }
 
690
};
 
691
 
 
692
PCI_CLASS_ENTRY PCISubClass_0f[] = {
 
693
  {
 
694
    0x00,
 
695
    L"TV",
 
696
    PCIBlankEntry
 
697
  },
 
698
  {
 
699
    0x01,
 
700
    L"Audio",
 
701
    PCIBlankEntry
 
702
  },
 
703
  {
 
704
    0x02,
 
705
    L"Voice",
 
706
    PCIBlankEntry
 
707
  },
 
708
  {
 
709
    0x03,
 
710
    L"Data",
 
711
    PCIBlankEntry
 
712
  },
 
713
  {
 
714
    0x00,
 
715
    NULL,
 
716
    /* null string ends the list */NULL
 
717
  }
 
718
};
 
719
 
 
720
PCI_CLASS_ENTRY PCISubClass_10[] = {
 
721
  {
 
722
    0x00,
 
723
    L"Network & computing Encrypt/Decrypt",
 
724
    PCIBlankEntry
 
725
  },
 
726
  {
 
727
    0x01,
 
728
    L"Entertainment Encrypt/Decrypt",
 
729
    PCIBlankEntry
 
730
  },
 
731
  {
 
732
    0x80,
 
733
    L"Other Encrypt/Decrypt",
 
734
    PCIBlankEntry
 
735
  },
 
736
  {
 
737
    0x00,
 
738
    NULL,
 
739
    /* null string ends the list */NULL
 
740
  }
 
741
};
 
742
 
 
743
PCI_CLASS_ENTRY PCISubClass_11[] = {
 
744
  {
 
745
    0x00,
 
746
    L"DPIO modules",
 
747
    PCIBlankEntry
 
748
  },
 
749
  {
 
750
    0x80,
 
751
    L"Other DAQ & SP controllers",
 
752
    PCIBlankEntry
 
753
  },
 
754
  {
 
755
    0x00,
 
756
    NULL,
 
757
    /* null string ends the list */NULL
 
758
  }
 
759
};
 
760
 
 
761
//
 
762
// Programming Interface entries
 
763
//
 
764
PCI_CLASS_ENTRY PCIPIFClass_0101[] = {
 
765
  {
 
766
    0x00,
 
767
    L"",
 
768
    PCIBlankEntry
 
769
  },
 
770
  {
 
771
    0x01,
 
772
    L"OM-primary",
 
773
    PCIBlankEntry
 
774
  },
 
775
  {
 
776
    0x02,
 
777
    L"PI-primary",
 
778
    PCIBlankEntry
 
779
  },
 
780
  {
 
781
    0x03,
 
782
    L"OM/PI-primary",
 
783
    PCIBlankEntry
 
784
  },
 
785
  {
 
786
    0x04,
 
787
    L"OM-secondary",
 
788
    PCIBlankEntry
 
789
  },
 
790
  {
 
791
    0x05,
 
792
    L"OM-primary, OM-secondary",
 
793
    PCIBlankEntry
 
794
  },
 
795
  {
 
796
    0x06,
 
797
    L"PI-primary, OM-secondary",
 
798
    PCIBlankEntry
 
799
  },
 
800
  {
 
801
    0x07,
 
802
    L"OM/PI-primary, OM-secondary",
 
803
    PCIBlankEntry
 
804
  },
 
805
  {
 
806
    0x08,
 
807
    L"OM-secondary",
 
808
    PCIBlankEntry
 
809
  },
 
810
  {
 
811
    0x09,
 
812
    L"OM-primary, PI-secondary",
 
813
    PCIBlankEntry
 
814
  },
 
815
  {
 
816
    0x0a,
 
817
    L"PI-primary, PI-secondary",
 
818
    PCIBlankEntry
 
819
  },
 
820
  {
 
821
    0x0b,
 
822
    L"OM/PI-primary, PI-secondary",
 
823
    PCIBlankEntry
 
824
  },
 
825
  {
 
826
    0x0c,
 
827
    L"OM-secondary",
 
828
    PCIBlankEntry
 
829
  },
 
830
  {
 
831
    0x0d,
 
832
    L"OM-primary, OM/PI-secondary",
 
833
    PCIBlankEntry
 
834
  },
 
835
  {
 
836
    0x0e,
 
837
    L"PI-primary, OM/PI-secondary",
 
838
    PCIBlankEntry
 
839
  },
 
840
  {
 
841
    0x0f,
 
842
    L"OM/PI-primary, OM/PI-secondary",
 
843
    PCIBlankEntry
 
844
  },
 
845
  {
 
846
    0x80,
 
847
    L"Master",
 
848
    PCIBlankEntry
 
849
  },
 
850
  {
 
851
    0x81,
 
852
    L"Master, OM-primary",
 
853
    PCIBlankEntry
 
854
  },
 
855
  {
 
856
    0x82,
 
857
    L"Master, PI-primary",
 
858
    PCIBlankEntry
 
859
  },
 
860
  {
 
861
    0x83,
 
862
    L"Master, OM/PI-primary",
 
863
    PCIBlankEntry
 
864
  },
 
865
  {
 
866
    0x84,
 
867
    L"Master, OM-secondary",
 
868
    PCIBlankEntry
 
869
  },
 
870
  {
 
871
    0x85,
 
872
    L"Master, OM-primary, OM-secondary",
 
873
    PCIBlankEntry
 
874
  },
 
875
  {
 
876
    0x86,
 
877
    L"Master, PI-primary, OM-secondary",
 
878
    PCIBlankEntry
 
879
  },
 
880
  {
 
881
    0x87,
 
882
    L"Master, OM/PI-primary, OM-secondary",
 
883
    PCIBlankEntry
 
884
  },
 
885
  {
 
886
    0x88,
 
887
    L"Master, OM-secondary",
 
888
    PCIBlankEntry
 
889
  },
 
890
  {
 
891
    0x89,
 
892
    L"Master, OM-primary, PI-secondary",
 
893
    PCIBlankEntry
 
894
  },
 
895
  {
 
896
    0x8a,
 
897
    L"Master, PI-primary, PI-secondary",
 
898
    PCIBlankEntry
 
899
  },
 
900
  {
 
901
    0x8b,
 
902
    L"Master, OM/PI-primary, PI-secondary",
 
903
    PCIBlankEntry
 
904
  },
 
905
  {
 
906
    0x8c,
 
907
    L"Master, OM-secondary",
 
908
    PCIBlankEntry
 
909
  },
 
910
  {
 
911
    0x8d,
 
912
    L"Master, OM-primary, OM/PI-secondary",
 
913
    PCIBlankEntry
 
914
  },
 
915
  {
 
916
    0x8e,
 
917
    L"Master, PI-primary, OM/PI-secondary",
 
918
    PCIBlankEntry
 
919
  },
 
920
  {
 
921
    0x8f,
 
922
    L"Master, OM/PI-primary, OM/PI-secondary",
 
923
    PCIBlankEntry
 
924
  },
 
925
  {
 
926
    0x00,
 
927
    NULL,
 
928
    /* null string ends the list */NULL
 
929
  }
 
930
};
 
931
 
 
932
PCI_CLASS_ENTRY PCIPIFClass_0300[] = {
 
933
  {
 
934
    0x00,
 
935
    L"VGA compatible",
 
936
    PCIBlankEntry
 
937
  },
 
938
  {
 
939
    0x01,
 
940
    L"8514 compatible",
 
941
    PCIBlankEntry
 
942
  },
 
943
  {
 
944
    0x00,
 
945
    NULL,
 
946
    /* null string ends the list */NULL
 
947
  }
 
948
};
 
949
 
 
950
PCI_CLASS_ENTRY PCIPIFClass_0604[] = {
 
951
  {
 
952
    0x00,
 
953
    L"",
 
954
    PCIBlankEntry
 
955
  },
 
956
  {
 
957
    0x01,
 
958
    L"Subtractive decode",
 
959
    PCIBlankEntry
 
960
  },
 
961
  {
 
962
    0x00,
 
963
    NULL,
 
964
    /* null string ends the list */NULL
 
965
  }
 
966
};
 
967
 
 
968
PCI_CLASS_ENTRY PCIPIFClass_0700[] = {
 
969
  {
 
970
    0x00,
 
971
    L"Generic XT-compatible",
 
972
    PCIBlankEntry
 
973
  },
 
974
  {
 
975
    0x01,
 
976
    L"16450-compatible",
 
977
    PCIBlankEntry
 
978
  },
 
979
  {
 
980
    0x02,
 
981
    L"16550-compatible",
 
982
    PCIBlankEntry
 
983
  },
 
984
  {
 
985
    0x03,
 
986
    L"16650-compatible",
 
987
    PCIBlankEntry
 
988
  },
 
989
  {
 
990
    0x04,
 
991
    L"16750-compatible",
 
992
    PCIBlankEntry
 
993
  },
 
994
  {
 
995
    0x05,
 
996
    L"16850-compatible",
 
997
    PCIBlankEntry
 
998
  },
 
999
  {
 
1000
    0x06,
 
1001
    L"16950-compatible",
 
1002
    PCIBlankEntry
 
1003
  },
 
1004
  {
 
1005
    0x00,
 
1006
    NULL,
 
1007
    /* null string ends the list */NULL
 
1008
  }
 
1009
};
 
1010
 
 
1011
PCI_CLASS_ENTRY PCIPIFClass_0701[] = {
 
1012
  {
 
1013
    0x00,
 
1014
    L"",
 
1015
    PCIBlankEntry
 
1016
  },
 
1017
  {
 
1018
    0x01,
 
1019
    L"Bi-directional",
 
1020
    PCIBlankEntry
 
1021
  },
 
1022
  {
 
1023
    0x02,
 
1024
    L"ECP 1.X-compliant",
 
1025
    PCIBlankEntry
 
1026
  },
 
1027
  {
 
1028
    0x03,
 
1029
    L"IEEE 1284",
 
1030
    PCIBlankEntry
 
1031
  },
 
1032
  {
 
1033
    0xfe,
 
1034
    L"IEEE 1284 target (not a controller)",
 
1035
    PCIBlankEntry
 
1036
  },
 
1037
  {
 
1038
    0x00,
 
1039
    NULL,
 
1040
    /* null string ends the list */NULL
 
1041
  }
 
1042
};
 
1043
 
 
1044
PCI_CLASS_ENTRY PCIPIFClass_0703[] = {
 
1045
  {
 
1046
    0x00,
 
1047
    L"Generic",
 
1048
    PCIBlankEntry
 
1049
  },
 
1050
  {
 
1051
    0x01,
 
1052
    L"Hayes-compatible 16450",
 
1053
    PCIBlankEntry
 
1054
  },
 
1055
  {
 
1056
    0x02,
 
1057
    L"Hayes-compatible 16550",
 
1058
    PCIBlankEntry
 
1059
  },
 
1060
  {
 
1061
    0x03,
 
1062
    L"Hayes-compatible 16650",
 
1063
    PCIBlankEntry
 
1064
  },
 
1065
  {
 
1066
    0x04,
 
1067
    L"Hayes-compatible 16750",
 
1068
    PCIBlankEntry
 
1069
  },
 
1070
  {
 
1071
    0x00,
 
1072
    NULL,
 
1073
    /* null string ends the list */NULL
 
1074
  }
 
1075
};
 
1076
 
 
1077
PCI_CLASS_ENTRY PCIPIFClass_0800[] = {
 
1078
  {
 
1079
    0x00,
 
1080
    L"Generic 8259",
 
1081
    PCIBlankEntry
 
1082
  },
 
1083
  {
 
1084
    0x01,
 
1085
    L"ISA",
 
1086
    PCIBlankEntry
 
1087
  },
 
1088
  {
 
1089
    0x02,
 
1090
    L"EISA",
 
1091
    PCIBlankEntry
 
1092
  },
 
1093
  {
 
1094
    0x10,
 
1095
    L"IO APIC",
 
1096
    PCIBlankEntry
 
1097
  },
 
1098
  {
 
1099
    0x20,
 
1100
    L"IO(x) APIC interrupt controller",
 
1101
    PCIBlankEntry
 
1102
  },
 
1103
  {
 
1104
    0x00,
 
1105
    NULL,
 
1106
    /* null string ends the list */NULL
 
1107
  }
 
1108
};
 
1109
 
 
1110
PCI_CLASS_ENTRY PCIPIFClass_0801[] = {
 
1111
  {
 
1112
    0x00,
 
1113
    L"Generic 8237",
 
1114
    PCIBlankEntry
 
1115
  },
 
1116
  {
 
1117
    0x01,
 
1118
    L"ISA",
 
1119
    PCIBlankEntry
 
1120
  },
 
1121
  {
 
1122
    0x02,
 
1123
    L"EISA",
 
1124
    PCIBlankEntry
 
1125
  },
 
1126
  {
 
1127
    0x00,
 
1128
    NULL,
 
1129
    /* null string ends the list */NULL
 
1130
  }
 
1131
};
 
1132
 
 
1133
PCI_CLASS_ENTRY PCIPIFClass_0802[] = {
 
1134
  {
 
1135
    0x00,
 
1136
    L"Generic 8254",
 
1137
    PCIBlankEntry
 
1138
  },
 
1139
  {
 
1140
    0x01,
 
1141
    L"ISA",
 
1142
    PCIBlankEntry
 
1143
  },
 
1144
  {
 
1145
    0x02,
 
1146
    L"EISA",
 
1147
    PCIBlankEntry
 
1148
  },
 
1149
  {
 
1150
    0x00,
 
1151
    NULL,
 
1152
    /* null string ends the list */NULL
 
1153
  }
 
1154
};
 
1155
 
 
1156
PCI_CLASS_ENTRY PCIPIFClass_0803[] = {
 
1157
  {
 
1158
    0x00,
 
1159
    L"Generic",
 
1160
    PCIBlankEntry
 
1161
  },
 
1162
  {
 
1163
    0x01,
 
1164
    L"ISA",
 
1165
    PCIBlankEntry
 
1166
  },
 
1167
  {
 
1168
    0x02,
 
1169
    L"EISA",
 
1170
    PCIBlankEntry
 
1171
  },
 
1172
  {
 
1173
    0x00,
 
1174
    NULL,
 
1175
    /* null string ends the list */NULL
 
1176
  }
 
1177
};
 
1178
 
 
1179
PCI_CLASS_ENTRY PCIPIFClass_0904[] = {
 
1180
  {
 
1181
    0x00,
 
1182
    L"Generic",
 
1183
    PCIBlankEntry
 
1184
  },
 
1185
  {
 
1186
    0x10,
 
1187
    L"",
 
1188
    PCIBlankEntry
 
1189
  },
 
1190
  {
 
1191
    0x00,
 
1192
    NULL,
 
1193
    /* null string ends the list */NULL
 
1194
  }
 
1195
};
 
1196
 
 
1197
PCI_CLASS_ENTRY PCIPIFClass_0c00[] = {
 
1198
  {
 
1199
    0x00,
 
1200
    L"Universal Host Controller spec",
 
1201
    PCIBlankEntry
 
1202
  },
 
1203
  {
 
1204
    0x10,
 
1205
    L"Open Host Controller spec",
 
1206
    PCIBlankEntry
 
1207
  },
 
1208
  {
 
1209
    0x80,
 
1210
    L"No specific programming interface",
 
1211
    PCIBlankEntry
 
1212
  },
 
1213
  {
 
1214
    0xfe,
 
1215
    L"(Not Host Controller)",
 
1216
    PCIBlankEntry
 
1217
  },
 
1218
  {
 
1219
    0x00,
 
1220
    NULL,
 
1221
    /* null string ends the list */NULL
 
1222
  }
 
1223
};
 
1224
 
 
1225
PCI_CLASS_ENTRY PCIPIFClass_0c03[] = {
 
1226
  {
 
1227
    0x00,
 
1228
    L"",
 
1229
    PCIBlankEntry
 
1230
  },
 
1231
  {
 
1232
    0x10,
 
1233
    L"Using 1394 OpenHCI spec",
 
1234
    PCIBlankEntry
 
1235
  },
 
1236
  {
 
1237
    0x00,
 
1238
    NULL,
 
1239
    /* null string ends the list */NULL
 
1240
  }
 
1241
};
 
1242
 
 
1243
PCI_CLASS_ENTRY PCIPIFClass_0e00[] = {
 
1244
  {
 
1245
    0x00,
 
1246
    L"Message FIFO at offset 40h",
 
1247
    PCIBlankEntry
 
1248
  },
 
1249
  {
 
1250
    0x01,
 
1251
    L"",
 
1252
    PCIBlankEntry
 
1253
  },
 
1254
  {
 
1255
    0x00,
 
1256
    NULL,
 
1257
    /* null string ends the list */NULL
 
1258
  }
 
1259
};
 
1260
 
 
1261
 
 
1262
/**
 
1263
  Generates printable Unicode strings that represent PCI device class,
 
1264
  subclass and programmed I/F based on a value passed to the function.
 
1265
 
 
1266
  @param[in] ClassCode      Value representing the PCI "Class Code" register read from a
 
1267
                 PCI device. The encodings are:
 
1268
                     bits 23:16 - Base Class Code
 
1269
                     bits 15:8  - Sub-Class Code
 
1270
                     bits  7:0  - Programming Interface
 
1271
  @param[in, out] ClassStrings   Pointer of PCI_CLASS_STRINGS structure, which contains
 
1272
                 printable class strings corresponding to ClassCode. The
 
1273
                 caller must not modify the strings that are pointed by
 
1274
                 the fields in ClassStrings.
 
1275
**/
 
1276
VOID
 
1277
PciGetClassStrings (
 
1278
  IN      UINT32               ClassCode,
 
1279
  IN OUT  PCI_CLASS_STRINGS    *ClassStrings
 
1280
  )
 
1281
{
 
1282
  INTN            Index;
 
1283
  UINT8           Code;
 
1284
  PCI_CLASS_ENTRY *CurrentClass;
 
1285
 
 
1286
  //
 
1287
  // Assume no strings found
 
1288
  //
 
1289
  ClassStrings->BaseClass = L"UNDEFINED";
 
1290
  ClassStrings->SubClass  = L"UNDEFINED";
 
1291
  ClassStrings->PIFClass  = L"UNDEFINED";
 
1292
 
 
1293
  CurrentClass = gClassStringList;
 
1294
  Code = (UINT8) (ClassCode >> 16);
 
1295
  Index = 0;
 
1296
 
 
1297
  //
 
1298
  // Go through all entries of the base class, until the entry with a matching
 
1299
  // base class code is found. If reaches an entry with a null description
 
1300
  // text, the last entry is met, which means no text for the base class was
 
1301
  // found, so no more action is needed.
 
1302
  //
 
1303
  while (Code != CurrentClass[Index].Code) {
 
1304
    if (NULL == CurrentClass[Index].DescText) {
 
1305
      return ;
 
1306
    }
 
1307
 
 
1308
    Index++;
 
1309
  }
 
1310
  //
 
1311
  // A base class was found. Assign description, and check if this class has
 
1312
  // sub-class defined. If sub-class defined, no more action is needed,
 
1313
  // otherwise, continue to find description for the sub-class code.
 
1314
  //
 
1315
  ClassStrings->BaseClass = CurrentClass[Index].DescText;
 
1316
  if (NULL == CurrentClass[Index].LowerLevelClass) {
 
1317
    return ;
 
1318
  }
 
1319
  //
 
1320
  // find Subclass entry
 
1321
  //
 
1322
  CurrentClass  = CurrentClass[Index].LowerLevelClass;
 
1323
  Code          = (UINT8) (ClassCode >> 8);
 
1324
  Index         = 0;
 
1325
 
 
1326
  //
 
1327
  // Go through all entries of the sub-class, until the entry with a matching
 
1328
  // sub-class code is found. If reaches an entry with a null description
 
1329
  // text, the last entry is met, which means no text for the sub-class was
 
1330
  // found, so no more action is needed.
 
1331
  //
 
1332
  while (Code != CurrentClass[Index].Code) {
 
1333
    if (NULL == CurrentClass[Index].DescText) {
 
1334
      return ;
 
1335
    }
 
1336
 
 
1337
    Index++;
 
1338
  }
 
1339
  //
 
1340
  // A class was found for the sub-class code. Assign description, and check if
 
1341
  // this sub-class has programming interface defined. If no, no more action is
 
1342
  // needed, otherwise, continue to find description for the programming
 
1343
  // interface.
 
1344
  //
 
1345
  ClassStrings->SubClass = CurrentClass[Index].DescText;
 
1346
  if (NULL == CurrentClass[Index].LowerLevelClass) {
 
1347
    return ;
 
1348
  }
 
1349
  //
 
1350
  // Find programming interface entry
 
1351
  //
 
1352
  CurrentClass  = CurrentClass[Index].LowerLevelClass;
 
1353
  Code          = (UINT8) ClassCode;
 
1354
  Index         = 0;
 
1355
 
 
1356
  //
 
1357
  // Go through all entries of the I/F entries, until the entry with a
 
1358
  // matching I/F code is found. If reaches an entry with a null description
 
1359
  // text, the last entry is met, which means no text was found, so no more
 
1360
  // action is needed.
 
1361
  //
 
1362
  while (Code != CurrentClass[Index].Code) {
 
1363
    if (NULL == CurrentClass[Index].DescText) {
 
1364
      return ;
 
1365
    }
 
1366
 
 
1367
    Index++;
 
1368
  }
 
1369
  //
 
1370
  // A class was found for the I/F code. Assign description, done!
 
1371
  //
 
1372
  ClassStrings->PIFClass = CurrentClass[Index].DescText;
 
1373
  return ;
 
1374
}
 
1375
 
 
1376
/**
 
1377
  Print strings that represent PCI device class, subclass and programmed I/F.
 
1378
 
 
1379
  @param[in] ClassCodePtr   Points to the memory which stores register Class Code in PCI
 
1380
                 configuation space.
 
1381
  @param[in] IncludePIF     If the printed string should include the programming I/F part
 
1382
**/
 
1383
VOID
 
1384
PciPrintClassCode (
 
1385
  IN      UINT8               *ClassCodePtr,
 
1386
  IN      BOOLEAN             IncludePIF
 
1387
  )
 
1388
{
 
1389
  UINT32            ClassCode;
 
1390
  PCI_CLASS_STRINGS ClassStrings;
 
1391
  CHAR16            OutputString[PCI_CLASS_STRING_LIMIT + 1];
 
1392
 
 
1393
  ClassCode = 0;
 
1394
  ClassCode |= ClassCodePtr[0];
 
1395
  ClassCode |= (ClassCodePtr[1] << 8);
 
1396
  ClassCode |= (ClassCodePtr[2] << 16);
 
1397
 
 
1398
  //
 
1399
  // Get name from class code
 
1400
  //
 
1401
  PciGetClassStrings (ClassCode, &ClassStrings);
 
1402
 
 
1403
  if (IncludePIF) {
 
1404
    //
 
1405
    // Only print base class and sub class name
 
1406
    //
 
1407
    ShellPrintEx(-1,-1, L"%s - %s - %s",
 
1408
      ClassStrings.BaseClass,
 
1409
      ClassStrings.SubClass,
 
1410
      ClassStrings.PIFClass
 
1411
     );
 
1412
 
 
1413
  } else {
 
1414
    //
 
1415
    // Print base class, sub class, and programming inferface name
 
1416
    //
 
1417
    UnicodeSPrint (
 
1418
      OutputString,
 
1419
      PCI_CLASS_STRING_LIMIT * sizeof (CHAR16),
 
1420
      L"%s - %s",
 
1421
      ClassStrings.BaseClass,
 
1422
      ClassStrings.SubClass
 
1423
     );
 
1424
 
 
1425
    OutputString[PCI_CLASS_STRING_LIMIT] = 0;
 
1426
    ShellPrintEx(-1,-1, L"%s", OutputString);
 
1427
  }
 
1428
}
 
1429
 
 
1430
/**
 
1431
  This function finds out the protocol which is in charge of the given
 
1432
  segment, and its bus range covers the current bus number. It lookes
 
1433
  each instances of RootBridgeIoProtocol handle, until the one meets the
 
1434
  criteria is found.
 
1435
 
 
1436
  @param[in] HandleBuf       Buffer which holds all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles.
 
1437
  @param[in] HandleCount     Count of all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles.
 
1438
  @param[in] Segment         Segment number of device we are dealing with.
 
1439
  @param[in] Bus             Bus number of device we are dealing with.
 
1440
  @param[out] IoDev          Handle used to access configuration space of PCI device.
 
1441
 
 
1442
  @retval EFI_SUCCESS             The command completed successfully.
 
1443
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 
1444
 
 
1445
**/
 
1446
EFI_STATUS
 
1447
PciFindProtocolInterface (
 
1448
  IN  EFI_HANDLE                            *HandleBuf,
 
1449
  IN  UINTN                                 HandleCount,
 
1450
  IN  UINT16                                Segment,
 
1451
  IN  UINT16                                Bus,
 
1452
  OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       **IoDev
 
1453
  );
 
1454
 
 
1455
/**
 
1456
  This function gets the protocol interface from the given handle, and
 
1457
  obtains its address space descriptors.
 
1458
 
 
1459
  @param[in] Handle          The PCI_ROOT_BRIDIGE_IO_PROTOCOL handle.
 
1460
  @param[out] IoDev          Handle used to access configuration space of PCI device.
 
1461
  @param[out] Descriptors    Points to the address space descriptors.
 
1462
 
 
1463
  @retval EFI_SUCCESS     The command completed successfully
 
1464
**/
 
1465
EFI_STATUS
 
1466
PciGetProtocolAndResource (
 
1467
  IN  EFI_HANDLE                            Handle,
 
1468
  OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       **IoDev,
 
1469
  OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     **Descriptors
 
1470
  );
 
1471
 
 
1472
/**
 
1473
  This function get the next bus range of given address space descriptors.
 
1474
  It also moves the pointer backward a node, to get prepared to be called
 
1475
  again.
 
1476
 
 
1477
  @param[in, out] Descriptors Points to current position of a serial of address space
 
1478
                              descriptors.
 
1479
  @param[out] MinBus          The lower range of bus number.
 
1480
  @param[out] MaxBus          The upper range of bus number.
 
1481
  @param[out] IsEnd           Meet end of the serial of descriptors.
 
1482
 
 
1483
  @retval EFI_SUCCESS     The command completed successfully.
 
1484
**/
 
1485
EFI_STATUS
 
1486
PciGetNextBusRange (
 
1487
  IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  **Descriptors,
 
1488
  OUT    UINT16                             *MinBus,
 
1489
  OUT    UINT16                             *MaxBus,
 
1490
  OUT    BOOLEAN                            *IsEnd
 
1491
  );
 
1492
 
 
1493
/**
 
1494
  Explain the data in PCI configuration space. The part which is common for
 
1495
  PCI device and bridge is interpreted in this function. It calls other
 
1496
  functions to interpret data unique for device or bridge.
 
1497
 
 
1498
  @param[in] ConfigSpace     Data in PCI configuration space.
 
1499
  @param[in] Address         Address used to access configuration space of this PCI device.
 
1500
  @param[in] IoDev           Handle used to access configuration space of PCI device.
 
1501
 
 
1502
  @retval EFI_SUCCESS     The command completed successfully.
 
1503
**/
 
1504
EFI_STATUS
 
1505
PciExplainData (
 
1506
  IN PCI_CONFIG_SPACE                       *ConfigSpace,
 
1507
  IN UINT64                                 Address,
 
1508
  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev
 
1509
  );
 
1510
 
 
1511
/**
 
1512
  Explain the device specific part of data in PCI configuration space.
 
1513
 
 
1514
  @param[in] Device          Data in PCI configuration space.
 
1515
  @param[in] Address         Address used to access configuration space of this PCI device.
 
1516
  @param[in] IoDev           Handle used to access configuration space of PCI device.
 
1517
 
 
1518
  @retval EFI_SUCCESS     The command completed successfully.
 
1519
**/
 
1520
EFI_STATUS
 
1521
PciExplainDeviceData (
 
1522
  IN PCI_DEVICE_HEADER                      *Device,
 
1523
  IN UINT64                                 Address,
 
1524
  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev
 
1525
  );
 
1526
 
 
1527
/**
 
1528
  Explain the bridge specific part of data in PCI configuration space.
 
1529
 
 
1530
  @param[in] Bridge          Bridge specific data region in PCI configuration space.
 
1531
  @param[in] Address         Address used to access configuration space of this PCI device.
 
1532
  @param[in] IoDev           Handle used to access configuration space of PCI device.
 
1533
 
 
1534
  @retval EFI_SUCCESS     The command completed successfully.
 
1535
**/
 
1536
EFI_STATUS
 
1537
PciExplainBridgeData (
 
1538
  IN  PCI_BRIDGE_HEADER                     *Bridge,
 
1539
  IN  UINT64                                Address,
 
1540
  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *IoDev
 
1541
  );
 
1542
 
 
1543
/**
 
1544
  Explain the Base Address Register(Bar) in PCI configuration space.
 
1545
 
 
1546
  @param[in] Bar              Points to the Base Address Register intended to interpret.
 
1547
  @param[in] Command          Points to the register Command.
 
1548
  @param[in] Address          Address used to access configuration space of this PCI device.
 
1549
  @param[in] IoDev            Handle used to access configuration space of PCI device.
 
1550
  @param[in, out] Index       The Index.
 
1551
 
 
1552
  @retval EFI_SUCCESS     The command completed successfully.
 
1553
**/
 
1554
EFI_STATUS
 
1555
PciExplainBar (
 
1556
  IN UINT32                                 *Bar,
 
1557
  IN UINT16                                 *Command,
 
1558
  IN UINT64                                 Address,
 
1559
  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev,
 
1560
  IN OUT UINTN                              *Index
 
1561
  );
 
1562
 
 
1563
/**
 
1564
  Explain the cardbus specific part of data in PCI configuration space.
 
1565
 
 
1566
  @param[in] CardBus         CardBus specific region of PCI configuration space.
 
1567
  @param[in] Address         Address used to access configuration space of this PCI device.
 
1568
  @param[in] IoDev           Handle used to access configuration space of PCI device.
 
1569
 
 
1570
  @retval EFI_SUCCESS     The command completed successfully.
 
1571
**/
 
1572
EFI_STATUS
 
1573
PciExplainCardBusData (
 
1574
  IN PCI_CARDBUS_HEADER                     *CardBus,
 
1575
  IN UINT64                                 Address,
 
1576
  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev
 
1577
  );
 
1578
 
 
1579
/**
 
1580
  Explain each meaningful bit of register Status. The definition of Status is
 
1581
  slightly different depending on the PCI header type.
 
1582
 
 
1583
  @param[in] Status          Points to the content of register Status.
 
1584
  @param[in] MainStatus      Indicates if this register is main status(not secondary
 
1585
                             status).
 
1586
  @param[in] HeaderType      Header type of this PCI device.
 
1587
 
 
1588
  @retval EFI_SUCCESS     The command completed successfully.
 
1589
**/
 
1590
EFI_STATUS
 
1591
PciExplainStatus (
 
1592
  IN UINT16                                 *Status,
 
1593
  IN BOOLEAN                                MainStatus,
 
1594
  IN PCI_HEADER_TYPE                        HeaderType
 
1595
  );
 
1596
 
 
1597
/**
 
1598
  Explain each meaningful bit of register Command.
 
1599
 
 
1600
  @param[in] Command         Points to the content of register Command.
 
1601
 
 
1602
  @retval EFI_SUCCESS     The command completed successfully.
 
1603
**/
 
1604
EFI_STATUS
 
1605
PciExplainCommand (
 
1606
  IN UINT16                                 *Command
 
1607
  );
 
1608
 
 
1609
/**
 
1610
  Explain each meaningful bit of register Bridge Control.
 
1611
 
 
1612
  @param[in] BridgeControl   Points to the content of register Bridge Control.
 
1613
  @param[in] HeaderType      The headertype.
 
1614
 
 
1615
  @retval EFI_SUCCESS     The command completed successfully.
 
1616
**/
 
1617
EFI_STATUS
 
1618
PciExplainBridgeControl (
 
1619
  IN UINT16                                 *BridgeControl,
 
1620
  IN PCI_HEADER_TYPE                        HeaderType
 
1621
  );
 
1622
 
 
1623
/**
 
1624
  Print each capability structure.
 
1625
 
 
1626
  @param[in] IoDev      The pointer to the deivce.
 
1627
  @param[in] Address    The address to start at.
 
1628
  @param[in] CapPtr     The offset from the address.
 
1629
 
 
1630
  @retval EFI_SUCCESS     The operation was successful.
 
1631
**/
 
1632
EFI_STATUS
 
1633
PciExplainCapabilityStruct (
 
1634
  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         *IoDev,
 
1635
  IN UINT64                                   Address,
 
1636
  IN  UINT8                                   CapPtr
 
1637
  );
 
1638
 
 
1639
/**
 
1640
  Display Pcie device structure.
 
1641
 
 
1642
  @param[in] IoDev          The pointer to the root pci protocol.
 
1643
  @param[in] Address        The Address to start at.
 
1644
  @param[in] CapabilityPtr  The offset from the address to start.
 
1645
**/
 
1646
EFI_STATUS
 
1647
PciExplainPciExpress (
 
1648
  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         *IoDev,
 
1649
  IN  UINT64                                  Address,
 
1650
  IN  UINT8                                   CapabilityPtr
 
1651
  );
 
1652
 
 
1653
/**
 
1654
  Print out information of the capability information.
 
1655
 
 
1656
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
1657
 
 
1658
  @retval EFI_SUCCESS   The operation was successful.
 
1659
**/
 
1660
EFI_STATUS
 
1661
ExplainPcieCapReg (
 
1662
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
1663
  );
 
1664
 
 
1665
/**
 
1666
  Print out information of the device capability information.
 
1667
 
 
1668
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
1669
 
 
1670
  @retval EFI_SUCCESS   The operation was successful.
 
1671
**/
 
1672
EFI_STATUS
 
1673
ExplainPcieDeviceCap (
 
1674
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
1675
  );
 
1676
 
 
1677
/**
 
1678
  Print out information of the device control information.
 
1679
 
 
1680
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
1681
 
 
1682
  @retval EFI_SUCCESS   The operation was successful.
 
1683
**/
 
1684
EFI_STATUS
 
1685
ExplainPcieDeviceControl (
 
1686
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
1687
  );
 
1688
 
 
1689
/**
 
1690
  Print out information of the device status information.
 
1691
 
 
1692
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
1693
 
 
1694
  @retval EFI_SUCCESS   The operation was successful.
 
1695
**/
 
1696
EFI_STATUS
 
1697
ExplainPcieDeviceStatus (
 
1698
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
1699
  );
 
1700
 
 
1701
/**
 
1702
  Print out information of the device link information.
 
1703
 
 
1704
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
1705
 
 
1706
  @retval EFI_SUCCESS   The operation was successful.
 
1707
**/
 
1708
EFI_STATUS
 
1709
ExplainPcieLinkCap (
 
1710
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
1711
  );
 
1712
 
 
1713
/**
 
1714
  Print out information of the device link control information.
 
1715
 
 
1716
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
1717
 
 
1718
  @retval EFI_SUCCESS   The operation was successful.
 
1719
**/
 
1720
EFI_STATUS
 
1721
ExplainPcieLinkControl (
 
1722
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
1723
  );
 
1724
 
 
1725
/**
 
1726
  Print out information of the device link status information.
 
1727
 
 
1728
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
1729
 
 
1730
  @retval EFI_SUCCESS   The operation was successful.
 
1731
**/
 
1732
EFI_STATUS
 
1733
ExplainPcieLinkStatus (
 
1734
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
1735
  );
 
1736
 
 
1737
/**
 
1738
  Print out information of the device slot information.
 
1739
 
 
1740
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
1741
 
 
1742
  @retval EFI_SUCCESS   The operation was successful.
 
1743
**/
 
1744
EFI_STATUS
 
1745
ExplainPcieSlotCap (
 
1746
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
1747
  );
 
1748
 
 
1749
/**
 
1750
  Print out information of the device slot control information.
 
1751
 
 
1752
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
1753
 
 
1754
  @retval EFI_SUCCESS   The operation was successful.
 
1755
**/
 
1756
EFI_STATUS
 
1757
ExplainPcieSlotControl (
 
1758
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
1759
  );
 
1760
 
 
1761
/**
 
1762
  Print out information of the device slot status information.
 
1763
 
 
1764
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
1765
 
 
1766
  @retval EFI_SUCCESS   The operation was successful.
 
1767
**/
 
1768
EFI_STATUS
 
1769
ExplainPcieSlotStatus (
 
1770
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
1771
  );
 
1772
 
 
1773
/**
 
1774
  Print out information of the device root information.
 
1775
 
 
1776
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
1777
 
 
1778
  @retval EFI_SUCCESS   The operation was successful.
 
1779
**/
 
1780
EFI_STATUS
 
1781
ExplainPcieRootControl (
 
1782
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
1783
  );
 
1784
 
 
1785
/**
 
1786
  Print out information of the device root capability information.
 
1787
 
 
1788
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
1789
 
 
1790
  @retval EFI_SUCCESS   The operation was successful.
 
1791
**/
 
1792
EFI_STATUS
 
1793
ExplainPcieRootCap (
 
1794
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
1795
  );
 
1796
 
 
1797
/**
 
1798
  Print out information of the device root status information.
 
1799
 
 
1800
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
1801
 
 
1802
  @retval EFI_SUCCESS   The operation was successful.
 
1803
**/
 
1804
EFI_STATUS
 
1805
ExplainPcieRootStatus (
 
1806
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
1807
  );
 
1808
 
 
1809
typedef EFI_STATUS (*PCIE_EXPLAIN_FUNCTION) (IN PCIE_CAP_STURCTURE *PciExpressCap);
 
1810
 
 
1811
typedef enum {
 
1812
  FieldWidthUINT8,
 
1813
  FieldWidthUINT16,
 
1814
  FieldWidthUINT32
 
1815
} PCIE_CAPREG_FIELD_WIDTH;
 
1816
 
 
1817
typedef enum {
 
1818
  PcieExplainTypeCommon,
 
1819
  PcieExplainTypeDevice,
 
1820
  PcieExplainTypeLink,
 
1821
  PcieExplainTypeSlot,
 
1822
  PcieExplainTypeRoot,
 
1823
  PcieExplainTypeMax
 
1824
} PCIE_EXPLAIN_TYPE;
 
1825
 
 
1826
typedef struct
 
1827
{
 
1828
  UINT16                  Token;
 
1829
  UINTN                   Offset;
 
1830
  PCIE_CAPREG_FIELD_WIDTH Width;
 
1831
  PCIE_EXPLAIN_FUNCTION   Func;
 
1832
  PCIE_EXPLAIN_TYPE       Type;
 
1833
} PCIE_EXPLAIN_STRUCT;
 
1834
 
 
1835
PCIE_EXPLAIN_STRUCT PcieExplainList[] = {
 
1836
  {
 
1837
    STRING_TOKEN (STR_PCIEX_CAPABILITY_CAPID),
 
1838
    0x00,
 
1839
    FieldWidthUINT8,
 
1840
    NULL,
 
1841
    PcieExplainTypeCommon
 
1842
  },
 
1843
  {
 
1844
    STRING_TOKEN (STR_PCIEX_NEXTCAP_PTR),
 
1845
    0x01,
 
1846
    FieldWidthUINT8,
 
1847
    NULL,
 
1848
    PcieExplainTypeCommon
 
1849
  },
 
1850
  {
 
1851
    STRING_TOKEN (STR_PCIEX_CAP_REGISTER),
 
1852
    0x02,
 
1853
    FieldWidthUINT16,
 
1854
    ExplainPcieCapReg,
 
1855
    PcieExplainTypeCommon
 
1856
  },
 
1857
  {
 
1858
    STRING_TOKEN (STR_PCIEX_DEVICE_CAP),
 
1859
    0x04,
 
1860
    FieldWidthUINT32,
 
1861
    ExplainPcieDeviceCap,
 
1862
    PcieExplainTypeDevice
 
1863
  },
 
1864
  {
 
1865
    STRING_TOKEN (STR_PCIEX_DEVICE_CONTROL),
 
1866
    0x08,
 
1867
    FieldWidthUINT16,
 
1868
    ExplainPcieDeviceControl,
 
1869
    PcieExplainTypeDevice
 
1870
  },
 
1871
  {
 
1872
    STRING_TOKEN (STR_PCIEX_DEVICE_STATUS),
 
1873
    0x0a,
 
1874
    FieldWidthUINT16,
 
1875
    ExplainPcieDeviceStatus,
 
1876
    PcieExplainTypeDevice
 
1877
  },
 
1878
  {
 
1879
    STRING_TOKEN (STR_PCIEX_LINK_CAPABILITIES),
 
1880
    0x0c,
 
1881
    FieldWidthUINT32,
 
1882
    ExplainPcieLinkCap,
 
1883
    PcieExplainTypeLink
 
1884
  },
 
1885
  {
 
1886
    STRING_TOKEN (STR_PCIEX_LINK_CONTROL),
 
1887
    0x10,
 
1888
    FieldWidthUINT16,
 
1889
    ExplainPcieLinkControl,
 
1890
    PcieExplainTypeLink
 
1891
  },
 
1892
  {
 
1893
    STRING_TOKEN (STR_PCIEX_LINK_STATUS),
 
1894
    0x12,
 
1895
    FieldWidthUINT16,
 
1896
    ExplainPcieLinkStatus,
 
1897
    PcieExplainTypeLink
 
1898
  },
 
1899
  {
 
1900
    STRING_TOKEN (STR_PCIEX_SLOT_CAPABILITIES),
 
1901
    0x14,
 
1902
    FieldWidthUINT32,
 
1903
    ExplainPcieSlotCap,
 
1904
    PcieExplainTypeSlot
 
1905
  },
 
1906
  {
 
1907
    STRING_TOKEN (STR_PCIEX_SLOT_CONTROL),
 
1908
    0x18,
 
1909
    FieldWidthUINT16,
 
1910
    ExplainPcieSlotControl,
 
1911
    PcieExplainTypeSlot
 
1912
  },
 
1913
  {
 
1914
    STRING_TOKEN (STR_PCIEX_SLOT_STATUS),
 
1915
    0x1a,
 
1916
    FieldWidthUINT16,
 
1917
    ExplainPcieSlotStatus,
 
1918
    PcieExplainTypeSlot
 
1919
  },
 
1920
  {
 
1921
    STRING_TOKEN (STR_PCIEX_ROOT_CONTROL),
 
1922
    0x1c,
 
1923
    FieldWidthUINT16,
 
1924
    ExplainPcieRootControl,
 
1925
    PcieExplainTypeRoot
 
1926
  },
 
1927
  {
 
1928
    STRING_TOKEN (STR_PCIEX_RSVDP),
 
1929
    0x1e,
 
1930
    FieldWidthUINT16,
 
1931
    ExplainPcieRootCap,
 
1932
    PcieExplainTypeRoot
 
1933
  },
 
1934
  {
 
1935
    STRING_TOKEN (STR_PCIEX_ROOT_STATUS),
 
1936
    0x20,
 
1937
    FieldWidthUINT32,
 
1938
    ExplainPcieRootStatus,
 
1939
    PcieExplainTypeRoot
 
1940
  },
 
1941
  {
 
1942
    0,
 
1943
    0,
 
1944
    (PCIE_CAPREG_FIELD_WIDTH)0,
 
1945
    NULL,
 
1946
    PcieExplainTypeMax
 
1947
  }
 
1948
};
 
1949
 
 
1950
//
 
1951
// Global Variables
 
1952
//
 
1953
PCI_CONFIG_SPACE  *mConfigSpace = NULL;
 
1954
STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
 
1955
  {L"-s", TypeValue},
 
1956
  {L"-i", TypeFlag},
 
1957
  {NULL, TypeMax}
 
1958
  };
 
1959
 
 
1960
CHAR16 *DevicePortTypeTable[] = {
 
1961
  L"PCI Express Endpoint",
 
1962
  L"Legacy PCI Express Endpoint",
 
1963
  L"Unknown Type",
 
1964
  L"Unknonw Type",
 
1965
  L"Root Port of PCI Express Root Complex",
 
1966
  L"Upstream Port of PCI Express Switch",
 
1967
  L"Downstream Port of PCI Express Switch",
 
1968
  L"PCI Express to PCI/PCI-X Bridge",
 
1969
  L"PCI/PCI-X to PCI Express Bridge",
 
1970
  L"Root Complex Integrated Endpoint",
 
1971
  L"Root Complex Event Collector"
 
1972
};
 
1973
 
 
1974
CHAR16 *L0sLatencyStrTable[] = {
 
1975
  L"Less than 64ns",
 
1976
  L"64ns to less than 128ns",
 
1977
  L"128ns to less than 256ns",
 
1978
  L"256ns to less than 512ns",
 
1979
  L"512ns to less than 1us",
 
1980
  L"1us to less than 2us",
 
1981
  L"2us-4us",
 
1982
  L"More than 4us"
 
1983
};
 
1984
 
 
1985
CHAR16 *L1LatencyStrTable[] = {
 
1986
  L"Less than 1us",
 
1987
  L"1us to less than 2us",
 
1988
  L"2us to less than 4us",
 
1989
  L"4us to less than 8us",
 
1990
  L"8us to less than 16us",
 
1991
  L"16us to less than 32us",
 
1992
  L"32us-64us",
 
1993
  L"More than 64us"
 
1994
};
 
1995
 
 
1996
CHAR16 *ASPMCtrlStrTable[] = {
 
1997
  L"Disabled",
 
1998
  L"L0s Entry Enabled",
 
1999
  L"L1 Entry Enabled",
 
2000
  L"L0s and L1 Entry Enabled"
 
2001
};
 
2002
 
 
2003
CHAR16 *SlotPwrLmtScaleTable[] = {
 
2004
  L"1.0x",
 
2005
  L"0.1x",
 
2006
  L"0.01x",
 
2007
  L"0.001x"
 
2008
};
 
2009
 
 
2010
CHAR16 *IndicatorTable[] = {
 
2011
  L"Reserved",
 
2012
  L"On",
 
2013
  L"Blink",
 
2014
  L"Off"
 
2015
};
 
2016
 
 
2017
 
 
2018
/**
 
2019
  Function for 'pci' command.
 
2020
 
 
2021
  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
 
2022
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
 
2023
**/
 
2024
SHELL_STATUS
 
2025
EFIAPI
 
2026
ShellCommandRunPci (
 
2027
  IN EFI_HANDLE        ImageHandle,
 
2028
  IN EFI_SYSTEM_TABLE  *SystemTable
 
2029
  )
 
2030
{
 
2031
  UINT16                            Segment;
 
2032
  UINT16                            Bus;
 
2033
  UINT16                            Device;
 
2034
  UINT16                            Func;
 
2035
  UINT64                            Address;
 
2036
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL   *IoDev;
 
2037
  EFI_STATUS                        Status;
 
2038
  PCI_COMMON_HEADER                 PciHeader;
 
2039
  PCI_CONFIG_SPACE                  ConfigSpace;
 
2040
  UINTN                             ScreenCount;
 
2041
  UINTN                             TempColumn;
 
2042
  UINTN                             ScreenSize;
 
2043
  BOOLEAN                           ExplainData;
 
2044
  UINTN                             Index;
 
2045
  UINTN                             SizeOfHeader;
 
2046
  BOOLEAN                           PrintTitle;
 
2047
  UINTN                             HandleBufSize;
 
2048
  EFI_HANDLE                        *HandleBuf;
 
2049
  UINTN                             HandleCount;
 
2050
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
 
2051
  UINT16                            MinBus;
 
2052
  UINT16                            MaxBus;
 
2053
  BOOLEAN                           IsEnd;
 
2054
  LIST_ENTRY                        *Package;
 
2055
  CHAR16                            *ProblemParam;
 
2056
  SHELL_STATUS                      ShellStatus;
 
2057
  UINTN                             Size;
 
2058
  CONST CHAR16                      *Temp;
 
2059
 
 
2060
  ShellStatus         = SHELL_SUCCESS;
 
2061
  Status              = EFI_SUCCESS;
 
2062
  Address             = 0;
 
2063
  Size                = 0;
 
2064
  IoDev               = NULL;
 
2065
  HandleBuf           = NULL;
 
2066
  Package             = NULL;
 
2067
 
 
2068
  //
 
2069
  // initialize the shell lib (we must be in non-auto-init...)
 
2070
  //
 
2071
  Status = ShellInitialize();
 
2072
  ASSERT_EFI_ERROR(Status);
 
2073
 
 
2074
  Status = CommandInit();
 
2075
  ASSERT_EFI_ERROR(Status);
 
2076
 
 
2077
  //
 
2078
  // parse the command line
 
2079
  //
 
2080
  Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
 
2081
  if (EFI_ERROR(Status)) {
 
2082
    if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
 
2083
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);
 
2084
      FreePool(ProblemParam);
 
2085
      ShellStatus = SHELL_INVALID_PARAMETER;
 
2086
    } else {
 
2087
      ASSERT(FALSE);
 
2088
    }
 
2089
  } else {
 
2090
 
 
2091
    if (ShellCommandLineGetCount(Package) == 2) {
 
2092
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);
 
2093
      ShellStatus = SHELL_INVALID_PARAMETER;
 
2094
      goto Done;
 
2095
    }
 
2096
 
 
2097
    if (ShellCommandLineGetCount(Package) > 4) {
 
2098
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
 
2099
      ShellStatus = SHELL_INVALID_PARAMETER;
 
2100
      goto Done;
 
2101
    }
 
2102
    if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetValue(Package, L"-s") == NULL) {
 
2103
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"-s");
 
2104
      ShellStatus = SHELL_INVALID_PARAMETER;
 
2105
      goto Done;
 
2106
    }
 
2107
    //
 
2108
    // Get all instances of PciRootBridgeIo. Allocate space for 1 EFI_HANDLE and
 
2109
    // call LibLocateHandle(), if EFI_BUFFER_TOO_SMALL is returned, allocate enough
 
2110
    // space for handles and call it again.
 
2111
    //
 
2112
    HandleBufSize = sizeof (EFI_HANDLE);
 
2113
    HandleBuf     = (EFI_HANDLE *) AllocateZeroPool (HandleBufSize);
 
2114
    if (HandleBuf == NULL) {
 
2115
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle);
 
2116
      ShellStatus = SHELL_OUT_OF_RESOURCES;
 
2117
      goto Done;
 
2118
    }
 
2119
 
 
2120
    Status = gBS->LocateHandle (
 
2121
                  ByProtocol,
 
2122
                  &gEfiPciRootBridgeIoProtocolGuid,
 
2123
                  NULL,
 
2124
                  &HandleBufSize,
 
2125
                  HandleBuf
 
2126
                 );
 
2127
 
 
2128
    if (Status == EFI_BUFFER_TOO_SMALL) {
 
2129
      HandleBuf = ReallocatePool (sizeof (EFI_HANDLE), HandleBufSize, HandleBuf);
 
2130
      if (HandleBuf == NULL) {
 
2131
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle);
 
2132
        ShellStatus = SHELL_OUT_OF_RESOURCES;
 
2133
        goto Done;
 
2134
      }
 
2135
 
 
2136
      Status = gBS->LocateHandle (
 
2137
                    ByProtocol,
 
2138
                    &gEfiPciRootBridgeIoProtocolGuid,
 
2139
                    NULL,
 
2140
                    &HandleBufSize,
 
2141
                    HandleBuf
 
2142
                   );
 
2143
    }
 
2144
 
 
2145
    if (EFI_ERROR (Status)) {
 
2146
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle);
 
2147
      ShellStatus = SHELL_NOT_FOUND;
 
2148
      goto Done;
 
2149
    }
 
2150
 
 
2151
    HandleCount = HandleBufSize / sizeof (EFI_HANDLE);
 
2152
    //
 
2153
    // Argument Count == 1(no other argument): enumerate all pci functions
 
2154
    //
 
2155
    if (ShellCommandLineGetCount(Package) == 1) {
 
2156
      gST->ConOut->QueryMode (
 
2157
                    gST->ConOut,
 
2158
                    gST->ConOut->Mode->Mode,
 
2159
                    &TempColumn,
 
2160
                    &ScreenSize
 
2161
                   );
 
2162
 
 
2163
      ScreenCount = 0;
 
2164
      ScreenSize -= 4;
 
2165
      if ((ScreenSize & 1) == 1) {
 
2166
        ScreenSize -= 1;
 
2167
      }
 
2168
 
 
2169
      PrintTitle = TRUE;
 
2170
 
 
2171
      //
 
2172
      // For each handle, which decides a segment and a bus number range,
 
2173
      // enumerate all devices on it.
 
2174
      //
 
2175
      for (Index = 0; Index < HandleCount; Index++) {
 
2176
        Status = PciGetProtocolAndResource (
 
2177
                  HandleBuf[Index],
 
2178
                  &IoDev,
 
2179
                  &Descriptors
 
2180
                 );
 
2181
        if (EFI_ERROR (Status)) {
 
2182
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_HANDLE_CFG_ERR), gShellDebug1HiiHandle, Status);
 
2183
          ShellStatus = SHELL_NOT_FOUND;
 
2184
          goto Done;
 
2185
        }
 
2186
        //
 
2187
        // No document say it's impossible for a RootBridgeIo protocol handle
 
2188
        // to have more than one address space descriptors, so find out every
 
2189
        // bus range and for each of them do device enumeration.
 
2190
        //
 
2191
        while (TRUE) {
 
2192
          Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd);
 
2193
 
 
2194
          if (EFI_ERROR (Status)) {
 
2195
            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_BUS_RANGE_ERR), gShellDebug1HiiHandle, Status);
 
2196
            ShellStatus = SHELL_NOT_FOUND;
 
2197
            goto Done;
 
2198
          }
 
2199
 
 
2200
          if (IsEnd) {
 
2201
            break;
 
2202
          }
 
2203
 
 
2204
          for (Bus = MinBus; Bus <= MaxBus; Bus++) {
 
2205
            //
 
2206
            // For each devices, enumerate all functions it contains
 
2207
            //
 
2208
            for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
 
2209
              //
 
2210
              // For each function, read its configuration space and print summary
 
2211
              //
 
2212
              for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
 
2213
                if (ShellGetExecutionBreakFlag ()) {
 
2214
                  ShellStatus = SHELL_ABORTED;
 
2215
                  goto Done;
 
2216
                }
 
2217
                Address = CALC_EFI_PCI_ADDRESS (Bus, Device, Func, 0);
 
2218
                IoDev->Pci.Read (
 
2219
                            IoDev,
 
2220
                            EfiPciWidthUint16,
 
2221
                            Address,
 
2222
                            1,
 
2223
                            &PciHeader.VendorId
 
2224
                           );
 
2225
 
 
2226
                //
 
2227
                // If VendorId = 0xffff, there does not exist a device at this
 
2228
                // location. For each device, if there is any function on it,
 
2229
                // there must be 1 function at Function 0. So if Func = 0, there
 
2230
                // will be no more functions in the same device, so we can break
 
2231
                // loop to deal with the next device.
 
2232
                //
 
2233
                if (PciHeader.VendorId == 0xffff && Func == 0) {
 
2234
                  break;
 
2235
                }
 
2236
 
 
2237
                if (PciHeader.VendorId != 0xffff) {
 
2238
 
 
2239
                  if (PrintTitle) {
 
2240
                    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_TITLE), gShellDebug1HiiHandle);
 
2241
                    PrintTitle = FALSE;
 
2242
                  }
 
2243
 
 
2244
                  IoDev->Pci.Read (
 
2245
                              IoDev,
 
2246
                              EfiPciWidthUint32,
 
2247
                              Address,
 
2248
                              sizeof (PciHeader) / sizeof (UINT32),
 
2249
                              &PciHeader
 
2250
                             );
 
2251
 
 
2252
                  ShellPrintHiiEx(
 
2253
                    -1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_P1), gShellDebug1HiiHandle,
 
2254
                    IoDev->SegmentNumber,
 
2255
                    Bus,
 
2256
                    Device,
 
2257
                    Func
 
2258
                   );
 
2259
 
 
2260
                  PciPrintClassCode (PciHeader.ClassCode, FALSE);
 
2261
                  ShellPrintHiiEx(
 
2262
                    -1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_P2), gShellDebug1HiiHandle,
 
2263
                    PciHeader.VendorId,
 
2264
                    PciHeader.DeviceId,
 
2265
                    PciHeader.ClassCode[0]
 
2266
                   );
 
2267
 
 
2268
                  ScreenCount += 2;
 
2269
                  if (ScreenCount >= ScreenSize && ScreenSize != 0) {
 
2270
                    //
 
2271
                    // If ScreenSize == 0 we have the console redirected so don't
 
2272
                    //  block updates
 
2273
                    //
 
2274
                    ScreenCount = 0;
 
2275
                  }
 
2276
                  //
 
2277
                  // If this is not a multi-function device, we can leave the loop
 
2278
                  // to deal with the next device.
 
2279
                  //
 
2280
                  if (Func == 0 && ((PciHeader.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00)) {
 
2281
                    break;
 
2282
                  }
 
2283
                }
 
2284
              }
 
2285
            }
 
2286
          }
 
2287
          //
 
2288
          // If Descriptor is NULL, Configuration() returns EFI_UNSUPPRORED,
 
2289
          // we assume the bus range is 0~PCI_MAX_BUS. After enumerated all
 
2290
          // devices on all bus, we can leave loop.
 
2291
          //
 
2292
          if (Descriptors == NULL) {
 
2293
            break;
 
2294
          }
 
2295
        }
 
2296
      }
 
2297
 
 
2298
      Status = EFI_SUCCESS;
 
2299
      goto Done;
 
2300
    }
 
2301
 
 
2302
    ExplainData                   = FALSE;
 
2303
    Segment                       = 0;
 
2304
    Bus                           = 0;
 
2305
    Device                        = 0;
 
2306
    Func                          = 0;
 
2307
    if (ShellCommandLineGetFlag(Package, L"-i")) {
 
2308
      ExplainData = TRUE;
 
2309
    }
 
2310
 
 
2311
    Temp = ShellCommandLineGetValue(Package, L"-s");
 
2312
    if (Temp != NULL) {
 
2313
      Segment = (UINT16) ShellStrToUintn (Temp);
 
2314
    }
 
2315
 
 
2316
    //
 
2317
    // The first Argument(except "-i") is assumed to be Bus number, second
 
2318
    // to be Device number, and third to be Func number.
 
2319
    //
 
2320
    Temp = ShellCommandLineGetRawValue(Package, 1);
 
2321
    if (Temp != NULL) {
 
2322
      Bus = (UINT16)ShellStrToUintn(Temp);
 
2323
      if (Bus > MAX_BUS_NUMBER) {
 
2324
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
 
2325
        ShellStatus = SHELL_INVALID_PARAMETER;
 
2326
        goto Done;
 
2327
      }
 
2328
    }
 
2329
    Temp = ShellCommandLineGetRawValue(Package, 2);
 
2330
    if (Temp != NULL) {
 
2331
      Device = (UINT16) ShellStrToUintn(Temp);
 
2332
      if (Device > MAX_DEVICE_NUMBER){
 
2333
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
 
2334
        ShellStatus = SHELL_INVALID_PARAMETER;
 
2335
        goto Done;
 
2336
      }
 
2337
    }
 
2338
 
 
2339
    Temp = ShellCommandLineGetRawValue(Package, 3);
 
2340
    if (Temp != NULL) {
 
2341
      Func = (UINT16) ShellStrToUintn(Temp);
 
2342
      if (Func > MAX_FUNCTION_NUMBER){
 
2343
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
 
2344
        ShellStatus = SHELL_INVALID_PARAMETER;
 
2345
        goto Done;
 
2346
      }
 
2347
    }
 
2348
 
 
2349
    //
 
2350
    // Find the protocol interface who's in charge of current segment, and its
 
2351
    // bus range covers the current bus
 
2352
    //
 
2353
    Status = PciFindProtocolInterface (
 
2354
              HandleBuf,
 
2355
              HandleCount,
 
2356
              Segment,
 
2357
              Bus,
 
2358
              &IoDev
 
2359
             );
 
2360
 
 
2361
    if (EFI_ERROR (Status)) {
 
2362
      ShellPrintHiiEx(
 
2363
        -1, -1, NULL, STRING_TOKEN (STR_PCI_NO_FIND), gShellDebug1HiiHandle,
 
2364
        gShellDebug1HiiHandle,
 
2365
        Segment,
 
2366
        Bus
 
2367
       );
 
2368
      ShellStatus = SHELL_NOT_FOUND;
 
2369
      goto Done;
 
2370
    }
 
2371
 
 
2372
    Address = CALC_EFI_PCI_ADDRESS (Bus, Device, Func, 0);
 
2373
    Status = IoDev->Pci.Read (
 
2374
                          IoDev,
 
2375
                          EfiPciWidthUint8,
 
2376
                          Address,
 
2377
                          sizeof (ConfigSpace),
 
2378
                          &ConfigSpace
 
2379
                         );
 
2380
 
 
2381
    if (EFI_ERROR (Status)) {
 
2382
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_NO_CFG), gShellDebug1HiiHandle, Status);
 
2383
      ShellStatus = SHELL_ACCESS_DENIED;
 
2384
      goto Done;
 
2385
    }
 
2386
 
 
2387
    mConfigSpace = &ConfigSpace;
 
2388
    ShellPrintHiiEx(
 
2389
      -1,
 
2390
      -1,
 
2391
      NULL,
 
2392
      STRING_TOKEN (STR_PCI_INFO),
 
2393
      gShellDebug1HiiHandle,
 
2394
      Segment,
 
2395
      Bus,
 
2396
      Device,
 
2397
      Func,
 
2398
      Segment,
 
2399
      Bus,
 
2400
      Device,
 
2401
      Func
 
2402
     );
 
2403
 
 
2404
    //
 
2405
    // Dump standard header of configuration space
 
2406
    //
 
2407
    SizeOfHeader = sizeof (ConfigSpace.Common) + sizeof (ConfigSpace.NonCommon);
 
2408
 
 
2409
    DumpHex (2, 0, SizeOfHeader, &ConfigSpace);
 
2410
    ShellPrintEx(-1,-1, L"\r\n");
 
2411
 
 
2412
    //
 
2413
    // Dump device dependent Part of configuration space
 
2414
    //
 
2415
    DumpHex (
 
2416
      2,
 
2417
      SizeOfHeader,
 
2418
      sizeof (ConfigSpace) - SizeOfHeader,
 
2419
      ConfigSpace.Data
 
2420
     );
 
2421
 
 
2422
    //
 
2423
    // If "-i" appears in command line, interpret data in configuration space
 
2424
    //
 
2425
    if (ExplainData) {
 
2426
      Status = PciExplainData (&ConfigSpace, Address, IoDev);
 
2427
    }
 
2428
  }
 
2429
Done:
 
2430
  if (HandleBuf != NULL) {
 
2431
    FreePool (HandleBuf);
 
2432
  }
 
2433
  if (Package != NULL) {
 
2434
    ShellCommandLineFreeVarList (Package);
 
2435
  }
 
2436
  mConfigSpace = NULL;
 
2437
  return ShellStatus;
 
2438
}
 
2439
 
 
2440
/**
 
2441
  This function finds out the protocol which is in charge of the given
 
2442
  segment, and its bus range covers the current bus number. It lookes
 
2443
  each instances of RootBridgeIoProtocol handle, until the one meets the
 
2444
  criteria is found.
 
2445
 
 
2446
  @param[in] HandleBuf       Buffer which holds all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles.
 
2447
  @param[in] HandleCount     Count of all PCI_ROOT_BRIDIGE_IO_PROTOCOL handles.
 
2448
  @param[in] Segment         Segment number of device we are dealing with.
 
2449
  @param[in] Bus             Bus number of device we are dealing with.
 
2450
  @param[out] IoDev          Handle used to access configuration space of PCI device.
 
2451
 
 
2452
  @retval EFI_SUCCESS             The command completed successfully.
 
2453
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 
2454
 
 
2455
**/
 
2456
EFI_STATUS
 
2457
PciFindProtocolInterface (
 
2458
  IN  EFI_HANDLE                            *HandleBuf,
 
2459
  IN  UINTN                                 HandleCount,
 
2460
  IN  UINT16                                Segment,
 
2461
  IN  UINT16                                Bus,
 
2462
  OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       **IoDev
 
2463
  )
 
2464
{
 
2465
  UINTN                             Index;
 
2466
  EFI_STATUS                        Status;
 
2467
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
 
2468
  UINT16                            MinBus;
 
2469
  UINT16                            MaxBus;
 
2470
  BOOLEAN                           IsEnd;
 
2471
 
 
2472
  //
 
2473
  // Go through all handles, until the one meets the criteria is found
 
2474
  //
 
2475
  for (Index = 0; Index < HandleCount; Index++) {
 
2476
    Status = PciGetProtocolAndResource (HandleBuf[Index], IoDev, &Descriptors);
 
2477
    if (EFI_ERROR (Status)) {
 
2478
      return Status;
 
2479
    }
 
2480
    //
 
2481
    // When Descriptors == NULL, the Configuration() is not implemented,
 
2482
    // so we only check the Segment number
 
2483
    //
 
2484
    if (Descriptors == NULL && Segment == (*IoDev)->SegmentNumber) {
 
2485
      return EFI_SUCCESS;
 
2486
    }
 
2487
 
 
2488
    if ((*IoDev)->SegmentNumber != Segment) {
 
2489
      continue;
 
2490
    }
 
2491
 
 
2492
    while (TRUE) {
 
2493
      Status = PciGetNextBusRange (&Descriptors, &MinBus, &MaxBus, &IsEnd);
 
2494
      if (EFI_ERROR (Status)) {
 
2495
        return Status;
 
2496
      }
 
2497
 
 
2498
      if (IsEnd) {
 
2499
        break;
 
2500
      }
 
2501
 
 
2502
      if (MinBus <= Bus && MaxBus >= Bus) {
 
2503
        return EFI_SUCCESS;
 
2504
      }
 
2505
    }
 
2506
  }
 
2507
 
 
2508
  return EFI_NOT_FOUND;
 
2509
}
 
2510
 
 
2511
/**
 
2512
  This function gets the protocol interface from the given handle, and
 
2513
  obtains its address space descriptors.
 
2514
 
 
2515
  @param[in] Handle          The PCI_ROOT_BRIDIGE_IO_PROTOCOL handle.
 
2516
  @param[out] IoDev          Handle used to access configuration space of PCI device.
 
2517
  @param[out] Descriptors    Points to the address space descriptors.
 
2518
 
 
2519
  @retval EFI_SUCCESS     The command completed successfully
 
2520
**/
 
2521
EFI_STATUS
 
2522
PciGetProtocolAndResource (
 
2523
  IN  EFI_HANDLE                            Handle,
 
2524
  OUT EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       **IoDev,
 
2525
  OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     **Descriptors
 
2526
  )
 
2527
{
 
2528
  EFI_STATUS  Status;
 
2529
 
 
2530
  //
 
2531
  // Get inferface from protocol
 
2532
  //
 
2533
  Status = gBS->HandleProtocol (
 
2534
                Handle,
 
2535
                &gEfiPciRootBridgeIoProtocolGuid,
 
2536
                (VOID**)IoDev
 
2537
               );
 
2538
 
 
2539
  if (EFI_ERROR (Status)) {
 
2540
    return Status;
 
2541
  }
 
2542
  //
 
2543
  // Call Configuration() to get address space descriptors
 
2544
  //
 
2545
  Status = (*IoDev)->Configuration (*IoDev, (VOID**)Descriptors);
 
2546
  if (Status == EFI_UNSUPPORTED) {
 
2547
    *Descriptors = NULL;
 
2548
    return EFI_SUCCESS;
 
2549
 
 
2550
  } else {
 
2551
    return Status;
 
2552
  }
 
2553
}
 
2554
 
 
2555
/**
 
2556
  This function get the next bus range of given address space descriptors.
 
2557
  It also moves the pointer backward a node, to get prepared to be called
 
2558
  again.
 
2559
 
 
2560
  @param[in, out] Descriptors Points to current position of a serial of address space
 
2561
                              descriptors.
 
2562
  @param[out] MinBus          The lower range of bus number.
 
2563
  @param[out] MaxBus          The upper range of bus number.
 
2564
  @param[out] IsEnd           Meet end of the serial of descriptors.
 
2565
 
 
2566
  @retval EFI_SUCCESS     The command completed successfully.
 
2567
**/
 
2568
EFI_STATUS
 
2569
PciGetNextBusRange (
 
2570
  IN OUT EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  **Descriptors,
 
2571
  OUT    UINT16                             *MinBus,
 
2572
  OUT    UINT16                             *MaxBus,
 
2573
  OUT    BOOLEAN                            *IsEnd
 
2574
  )
 
2575
{
 
2576
  *IsEnd = FALSE;
 
2577
 
 
2578
  //
 
2579
  // When *Descriptors is NULL, Configuration() is not implemented, so assume
 
2580
  // range is 0~PCI_MAX_BUS
 
2581
  //
 
2582
  if ((*Descriptors) == NULL) {
 
2583
    *MinBus = 0;
 
2584
    *MaxBus = PCI_MAX_BUS;
 
2585
    return EFI_SUCCESS;
 
2586
  }
 
2587
  //
 
2588
  // *Descriptors points to one or more address space descriptors, which
 
2589
  // ends with a end tagged descriptor. Examine each of the descriptors,
 
2590
  // if a bus typed one is found and its bus range covers bus, this handle
 
2591
  // is the handle we are looking for.
 
2592
  //
 
2593
 
 
2594
  while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {
 
2595
    if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {
 
2596
      *MinBus = (UINT16) (*Descriptors)->AddrRangeMin;
 
2597
      *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax;
 
2598
      (*Descriptors)++;
 
2599
      return (EFI_SUCCESS);
 
2600
    }
 
2601
 
 
2602
    (*Descriptors)++;
 
2603
  }
 
2604
 
 
2605
  if ((*Descriptors)->Desc == ACPI_END_TAG_DESCRIPTOR) {
 
2606
    *IsEnd = TRUE;
 
2607
  }
 
2608
 
 
2609
  return EFI_SUCCESS;
 
2610
}
 
2611
 
 
2612
/**
 
2613
  Explain the data in PCI configuration space. The part which is common for
 
2614
  PCI device and bridge is interpreted in this function. It calls other
 
2615
  functions to interpret data unique for device or bridge.
 
2616
 
 
2617
  @param[in] ConfigSpace     Data in PCI configuration space.
 
2618
  @param[in] Address         Address used to access configuration space of this PCI device.
 
2619
  @param[in] IoDev           Handle used to access configuration space of PCI device.
 
2620
 
 
2621
  @retval EFI_SUCCESS     The command completed successfully.
 
2622
**/
 
2623
EFI_STATUS
 
2624
PciExplainData (
 
2625
  IN PCI_CONFIG_SPACE                       *ConfigSpace,
 
2626
  IN UINT64                                 Address,
 
2627
  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev
 
2628
  )
 
2629
{
 
2630
  PCI_COMMON_HEADER *Common;
 
2631
  PCI_HEADER_TYPE   HeaderType;
 
2632
  EFI_STATUS        Status;
 
2633
  UINT8             CapPtr;
 
2634
 
 
2635
  Common = &(ConfigSpace->Common);
 
2636
 
 
2637
  Print (L"\n");
 
2638
 
 
2639
  //
 
2640
  // Print Vendor Id and Device Id
 
2641
  //
 
2642
  ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_VID_DID), gShellDebug1HiiHandle,
 
2643
    INDEX_OF (&(Common->VendorId)),
 
2644
    Common->VendorId,
 
2645
    INDEX_OF (&(Common->DeviceId)),
 
2646
    Common->DeviceId
 
2647
   );
 
2648
 
 
2649
  //
 
2650
  // Print register Command
 
2651
  //
 
2652
  PciExplainCommand (&(Common->Command));
 
2653
 
 
2654
  //
 
2655
  // Print register Status
 
2656
  //
 
2657
  PciExplainStatus (&(Common->Status), TRUE, PciUndefined);
 
2658
 
 
2659
  //
 
2660
  // Print register Revision ID
 
2661
  //
 
2662
  ShellPrintEx(-1, -1, L"/r/n");
 
2663
  ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_RID), gShellDebug1HiiHandle,
 
2664
    INDEX_OF (&(Common->RevisionId)),
 
2665
    Common->RevisionId
 
2666
   );
 
2667
 
 
2668
  //
 
2669
  // Print register BIST
 
2670
  //
 
2671
  ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_BIST), gShellDebug1HiiHandle, INDEX_OF (&(Common->Bist)));
 
2672
  if ((Common->Bist & PCI_BIT_7) != 0) {
 
2673
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP), gShellDebug1HiiHandle, 0x0f & Common->Bist);
 
2674
  } else {
 
2675
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_CAP_NO), gShellDebug1HiiHandle);
 
2676
  }
 
2677
  //
 
2678
  // Print register Cache Line Size
 
2679
  //
 
2680
  ShellPrintHiiEx(-1, -1, NULL,
 
2681
    STRING_TOKEN (STR_PCI2_CACHE_LINE_SIZE),
 
2682
    gShellDebug1HiiHandle,
 
2683
    INDEX_OF (&(Common->CacheLineSize)),
 
2684
    Common->CacheLineSize
 
2685
   );
 
2686
 
 
2687
  //
 
2688
  // Print register Latency Timer
 
2689
  //
 
2690
  ShellPrintHiiEx(-1, -1, NULL,
 
2691
    STRING_TOKEN (STR_PCI2_LATENCY_TIMER),
 
2692
    gShellDebug1HiiHandle,
 
2693
    INDEX_OF (&(Common->PrimaryLatencyTimer)),
 
2694
    Common->PrimaryLatencyTimer
 
2695
   );
 
2696
 
 
2697
  //
 
2698
  // Print register Header Type
 
2699
  //
 
2700
  ShellPrintHiiEx(-1, -1, NULL,
 
2701
    STRING_TOKEN (STR_PCI2_HEADER_TYPE),
 
2702
    gShellDebug1HiiHandle,
 
2703
    INDEX_OF (&(Common->HeaderType)),
 
2704
    Common->HeaderType
 
2705
   );
 
2706
 
 
2707
  if ((Common->HeaderType & PCI_BIT_7) != 0) {
 
2708
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MULTI_FUNCTION), gShellDebug1HiiHandle);
 
2709
 
 
2710
  } else {
 
2711
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SINGLE_FUNCTION), gShellDebug1HiiHandle);
 
2712
  }
 
2713
 
 
2714
  HeaderType = (PCI_HEADER_TYPE)(UINT8) (Common->HeaderType & 0x7f);
 
2715
  switch (HeaderType) {
 
2716
  case PciDevice:
 
2717
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_PCI_DEVICE), gShellDebug1HiiHandle);
 
2718
    break;
 
2719
 
 
2720
  case PciP2pBridge:
 
2721
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_P2P_BRIDGE), gShellDebug1HiiHandle);
 
2722
    break;
 
2723
 
 
2724
  case PciCardBusBridge:
 
2725
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_BRIDGE), gShellDebug1HiiHandle);
 
2726
    break;
 
2727
 
 
2728
  default:
 
2729
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESERVED), gShellDebug1HiiHandle);
 
2730
    HeaderType = PciUndefined;
 
2731
  }
 
2732
 
 
2733
  //
 
2734
  // Print register Class Code
 
2735
  //
 
2736
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CLASS), gShellDebug1HiiHandle);
 
2737
  PciPrintClassCode ((UINT8 *) Common->ClassCode, TRUE);
 
2738
  Print (L"\n");
 
2739
 
 
2740
  if (ShellGetExecutionBreakFlag()) {
 
2741
    return EFI_SUCCESS;
 
2742
  }
 
2743
 
 
2744
  //
 
2745
  // Interpret remaining part of PCI configuration header depending on
 
2746
  // HeaderType
 
2747
  //
 
2748
  CapPtr  = 0;
 
2749
  Status  = EFI_SUCCESS;
 
2750
  switch (HeaderType) {
 
2751
  case PciDevice:
 
2752
    Status = PciExplainDeviceData (
 
2753
              &(ConfigSpace->NonCommon.Device),
 
2754
              Address,
 
2755
              IoDev
 
2756
             );
 
2757
    CapPtr = ConfigSpace->NonCommon.Device.CapabilitiesPtr;
 
2758
    break;
 
2759
 
 
2760
  case PciP2pBridge:
 
2761
    Status = PciExplainBridgeData (
 
2762
              &(ConfigSpace->NonCommon.Bridge),
 
2763
              Address,
 
2764
              IoDev
 
2765
             );
 
2766
    CapPtr = ConfigSpace->NonCommon.Bridge.CapabilitiesPtr;
 
2767
    break;
 
2768
 
 
2769
  case PciCardBusBridge:
 
2770
    Status = PciExplainCardBusData (
 
2771
              &(ConfigSpace->NonCommon.CardBus),
 
2772
              Address,
 
2773
              IoDev
 
2774
             );
 
2775
    CapPtr = ConfigSpace->NonCommon.CardBus.CapabilitiesPtr;
 
2776
    break;
 
2777
  case PciUndefined:
 
2778
  default:
 
2779
    break;
 
2780
  }
 
2781
  //
 
2782
  // If Status bit4 is 1, dump or explain capability structure
 
2783
  //
 
2784
  if ((Common->Status) & EFI_PCI_STATUS_CAPABILITY) {
 
2785
    PciExplainCapabilityStruct (IoDev, Address, CapPtr);
 
2786
  }
 
2787
 
 
2788
  return Status;
 
2789
}
 
2790
 
 
2791
/**
 
2792
  Explain the device specific part of data in PCI configuration space.
 
2793
 
 
2794
  @param[in] Device          Data in PCI configuration space.
 
2795
  @param[in] Address         Address used to access configuration space of this PCI device.
 
2796
  @param[in] IoDev           Handle used to access configuration space of PCI device.
 
2797
 
 
2798
  @retval EFI_SUCCESS     The command completed successfully.
 
2799
**/
 
2800
EFI_STATUS
 
2801
PciExplainDeviceData (
 
2802
  IN PCI_DEVICE_HEADER                      *Device,
 
2803
  IN UINT64                                 Address,
 
2804
  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev
 
2805
  )
 
2806
{
 
2807
  UINTN       Index;
 
2808
  BOOLEAN     BarExist;
 
2809
  EFI_STATUS  Status;
 
2810
  UINTN       BarCount;
 
2811
 
 
2812
  //
 
2813
  // Print Base Address Registers(Bar). When Bar = 0, this Bar does not
 
2814
  // exist. If these no Bar for this function, print "none", otherwise
 
2815
  // list detail information about this Bar.
 
2816
  //
 
2817
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDR), gShellDebug1HiiHandle, INDEX_OF (Device->Bar));
 
2818
 
 
2819
  BarExist  = FALSE;
 
2820
  BarCount  = sizeof (Device->Bar) / sizeof (Device->Bar[0]);
 
2821
  for (Index = 0; Index < BarCount; Index++) {
 
2822
    if (Device->Bar[Index] == 0) {
 
2823
      continue;
 
2824
    }
 
2825
 
 
2826
    if (!BarExist) {
 
2827
      BarExist = TRUE;
 
2828
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE), gShellDebug1HiiHandle);
 
2829
      Print (L"  --------------------------------------------------------------------------");
 
2830
    }
 
2831
 
 
2832
    Status = PciExplainBar (
 
2833
              &(Device->Bar[Index]),
 
2834
              &(mConfigSpace->Common.Command),
 
2835
              Address,
 
2836
              IoDev,
 
2837
              &Index
 
2838
             );
 
2839
 
 
2840
    if (EFI_ERROR (Status)) {
 
2841
      break;
 
2842
    }
 
2843
  }
 
2844
 
 
2845
  if (!BarExist) {
 
2846
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle);
 
2847
 
 
2848
  } else {
 
2849
    Print (L"\n  --------------------------------------------------------------------------");
 
2850
  }
 
2851
 
 
2852
  //
 
2853
  // Print register Expansion ROM Base Address
 
2854
  //
 
2855
  if ((Device->ROMBar & PCI_BIT_0) == 0) {
 
2856
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_EXPANSION_ROM_DISABLED), gShellDebug1HiiHandle, INDEX_OF (&(Device->ROMBar)));
 
2857
 
 
2858
  } else {
 
2859
    ShellPrintHiiEx(-1, -1, NULL,
 
2860
      STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE),
 
2861
      gShellDebug1HiiHandle,
 
2862
      INDEX_OF (&(Device->ROMBar)),
 
2863
      Device->ROMBar
 
2864
     );
 
2865
  }
 
2866
  //
 
2867
  // Print register Cardbus CIS ptr
 
2868
  //
 
2869
  ShellPrintHiiEx(-1, -1, NULL,
 
2870
    STRING_TOKEN (STR_PCI2_CARDBUS_CIS),
 
2871
    gShellDebug1HiiHandle,
 
2872
    INDEX_OF (&(Device->CardBusCISPtr)),
 
2873
    Device->CardBusCISPtr
 
2874
   );
 
2875
 
 
2876
  //
 
2877
  // Print register Sub-vendor ID and subsystem ID
 
2878
  //
 
2879
  ShellPrintHiiEx(-1, -1, NULL,
 
2880
    STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID),
 
2881
    gShellDebug1HiiHandle,
 
2882
    INDEX_OF (&(Device->SubVendorId)),
 
2883
    Device->SubVendorId
 
2884
   );
 
2885
 
 
2886
  ShellPrintHiiEx(-1, -1, NULL,
 
2887
    STRING_TOKEN (STR_PCI2_SUBSYSTEM_ID),
 
2888
    gShellDebug1HiiHandle,
 
2889
    INDEX_OF (&(Device->SubSystemId)),
 
2890
    Device->SubSystemId
 
2891
   );
 
2892
 
 
2893
  //
 
2894
  // Print register Capabilities Ptr
 
2895
  //
 
2896
  ShellPrintHiiEx(-1, -1, NULL,
 
2897
    STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR),
 
2898
    gShellDebug1HiiHandle,
 
2899
    INDEX_OF (&(Device->CapabilitiesPtr)),
 
2900
    Device->CapabilitiesPtr
 
2901
   );
 
2902
 
 
2903
  //
 
2904
  // Print register Interrupt Line and interrupt pin
 
2905
  //
 
2906
  ShellPrintHiiEx(-1, -1, NULL,
 
2907
    STRING_TOKEN (STR_PCI2_INTERRUPT_LINE),
 
2908
    gShellDebug1HiiHandle,
 
2909
    INDEX_OF (&(Device->InterruptLine)),
 
2910
    Device->InterruptLine
 
2911
   );
 
2912
 
 
2913
  ShellPrintHiiEx(-1, -1, NULL,
 
2914
    STRING_TOKEN (STR_PCI2_INTERRUPT_PIN),
 
2915
    gShellDebug1HiiHandle,
 
2916
    INDEX_OF (&(Device->InterruptPin)),
 
2917
    Device->InterruptPin
 
2918
   );
 
2919
 
 
2920
  //
 
2921
  // Print register Min_Gnt and Max_Lat
 
2922
  //
 
2923
  ShellPrintHiiEx(-1, -1, NULL,
 
2924
    STRING_TOKEN (STR_PCI2_MIN_GNT),
 
2925
    gShellDebug1HiiHandle,
 
2926
    INDEX_OF (&(Device->MinGnt)),
 
2927
    Device->MinGnt
 
2928
   );
 
2929
 
 
2930
  ShellPrintHiiEx(-1, -1, NULL,
 
2931
    STRING_TOKEN (STR_PCI2_MAX_LAT),
 
2932
    gShellDebug1HiiHandle,
 
2933
    INDEX_OF (&(Device->MaxLat)),
 
2934
    Device->MaxLat
 
2935
   );
 
2936
 
 
2937
  return EFI_SUCCESS;
 
2938
}
 
2939
 
 
2940
/**
 
2941
  Explain the bridge specific part of data in PCI configuration space.
 
2942
 
 
2943
  @param[in] Bridge          Bridge specific data region in PCI configuration space.
 
2944
  @param[in] Address         Address used to access configuration space of this PCI device.
 
2945
  @param[in] IoDev           Handle used to access configuration space of PCI device.
 
2946
 
 
2947
  @retval EFI_SUCCESS     The command completed successfully.
 
2948
**/
 
2949
EFI_STATUS
 
2950
PciExplainBridgeData (
 
2951
  IN  PCI_BRIDGE_HEADER                     *Bridge,
 
2952
  IN  UINT64                                Address,
 
2953
  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *IoDev
 
2954
  )
 
2955
{
 
2956
  UINTN       Index;
 
2957
  BOOLEAN     BarExist;
 
2958
  UINTN       BarCount;
 
2959
  UINT32      IoAddress32;
 
2960
  EFI_STATUS  Status;
 
2961
 
 
2962
  //
 
2963
  // Print Base Address Registers. When Bar = 0, this Bar does not
 
2964
  // exist. If these no Bar for this function, print "none", otherwise
 
2965
  // list detail information about this Bar.
 
2966
  //
 
2967
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BASE_ADDRESS), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->Bar)));
 
2968
 
 
2969
  BarExist  = FALSE;
 
2970
  BarCount  = sizeof (Bridge->Bar) / sizeof (Bridge->Bar[0]);
 
2971
 
 
2972
  for (Index = 0; Index < BarCount; Index++) {
 
2973
    if (Bridge->Bar[Index] == 0) {
 
2974
      continue;
 
2975
    }
 
2976
 
 
2977
    if (!BarExist) {
 
2978
      BarExist = TRUE;
 
2979
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE_2), gShellDebug1HiiHandle);
 
2980
      Print (L"  --------------------------------------------------------------------------");
 
2981
    }
 
2982
 
 
2983
    Status = PciExplainBar (
 
2984
              &(Bridge->Bar[Index]),
 
2985
              &(mConfigSpace->Common.Command),
 
2986
              Address,
 
2987
              IoDev,
 
2988
              &Index
 
2989
             );
 
2990
 
 
2991
    if (EFI_ERROR (Status)) {
 
2992
      break;
 
2993
    }
 
2994
  }
 
2995
 
 
2996
  if (!BarExist) {
 
2997
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle);
 
2998
  } else {
 
2999
    Print (L"\n  --------------------------------------------------------------------------");
 
3000
  }
 
3001
 
 
3002
  //
 
3003
  // Expansion register ROM Base Address
 
3004
  //
 
3005
  if ((Bridge->ROMBar & PCI_BIT_0) == 0) {
 
3006
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO_EXPANSION_ROM), gShellDebug1HiiHandle, INDEX_OF (&(Bridge->ROMBar)));
 
3007
 
 
3008
  } else {
 
3009
    ShellPrintHiiEx(-1, -1, NULL,
 
3010
      STRING_TOKEN (STR_PCI2_EXPANSION_ROM_BASE_2),
 
3011
      gShellDebug1HiiHandle,
 
3012
      INDEX_OF (&(Bridge->ROMBar)),
 
3013
      Bridge->ROMBar
 
3014
     );
 
3015
  }
 
3016
  //
 
3017
  // Print Bus Numbers(Primary, Secondary, and Subordinate
 
3018
  //
 
3019
  ShellPrintHiiEx(-1, -1, NULL,
 
3020
    STRING_TOKEN (STR_PCI2_BUS_NUMBERS),
 
3021
    gShellDebug1HiiHandle,
 
3022
    INDEX_OF (&(Bridge->PrimaryBus)),
 
3023
    INDEX_OF (&(Bridge->SecondaryBus)),
 
3024
    INDEX_OF (&(Bridge->SubordinateBus))
 
3025
   );
 
3026
 
 
3027
  Print (L"               ------------------------------------------------------\n");
 
3028
 
 
3029
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->PrimaryBus);
 
3030
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SecondaryBus);
 
3031
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SubordinateBus);
 
3032
 
 
3033
  //
 
3034
  // Print register Secondary Latency Timer
 
3035
  //
 
3036
  ShellPrintHiiEx(-1, -1, NULL,
 
3037
    STRING_TOKEN (STR_PCI2_SECONDARY_TIMER),
 
3038
    gShellDebug1HiiHandle,
 
3039
    INDEX_OF (&(Bridge->SecondaryLatencyTimer)),
 
3040
    Bridge->SecondaryLatencyTimer
 
3041
   );
 
3042
 
 
3043
  //
 
3044
  // Print register Secondary Status
 
3045
  //
 
3046
  PciExplainStatus (&(Bridge->SecondaryStatus), FALSE, PciP2pBridge);
 
3047
 
 
3048
  //
 
3049
  // Print I/O and memory ranges this bridge forwards. There are 3 resource
 
3050
  // types: I/O, memory, and pre-fetchable memory. For each resource type,
 
3051
  // base and limit address are listed.
 
3052
  //
 
3053
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE), gShellDebug1HiiHandle);
 
3054
  Print (L"----------------------------------------------------------------------\n");
 
3055
 
 
3056
  //
 
3057
  // IO Base & Limit
 
3058
  //
 
3059
  IoAddress32 = (Bridge->IoBaseUpper << 16 | Bridge->IoBase << 8);
 
3060
  IoAddress32 &= 0xfffff000;
 
3061
  ShellPrintHiiEx(-1, -1, NULL,
 
3062
    STRING_TOKEN (STR_PCI2_TWO_VARS),
 
3063
    gShellDebug1HiiHandle,
 
3064
    INDEX_OF (&(Bridge->IoBase)),
 
3065
    IoAddress32
 
3066
   );
 
3067
 
 
3068
  IoAddress32 = (Bridge->IoLimitUpper << 16 | Bridge->IoLimit << 8);
 
3069
  IoAddress32 |= 0x00000fff;
 
3070
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR), gShellDebug1HiiHandle, IoAddress32);
 
3071
 
 
3072
  //
 
3073
  // Memory Base & Limit
 
3074
  //
 
3075
  ShellPrintHiiEx(-1, -1, NULL,
 
3076
    STRING_TOKEN (STR_PCI2_MEMORY),
 
3077
    gShellDebug1HiiHandle,
 
3078
    INDEX_OF (&(Bridge->MemoryBase)),
 
3079
    (Bridge->MemoryBase << 16) & 0xfff00000
 
3080
   );
 
3081
 
 
3082
  ShellPrintHiiEx(-1, -1, NULL,
 
3083
    STRING_TOKEN (STR_PCI2_ONE_VAR),
 
3084
    gShellDebug1HiiHandle,
 
3085
    (Bridge->MemoryLimit << 16) | 0x000fffff
 
3086
   );
 
3087
 
 
3088
  //
 
3089
  // Pre-fetch-able Memory Base & Limit
 
3090
  //
 
3091
  ShellPrintHiiEx(-1, -1, NULL,
 
3092
    STRING_TOKEN (STR_PCI2_PREFETCHABLE),
 
3093
    gShellDebug1HiiHandle,
 
3094
    INDEX_OF (&(Bridge->PrefetchableMemBase)),
 
3095
    Bridge->PrefetchableBaseUpper,
 
3096
    (Bridge->PrefetchableMemBase << 16) & 0xfff00000
 
3097
   );
 
3098
 
 
3099
  ShellPrintHiiEx(-1, -1, NULL,
 
3100
    STRING_TOKEN (STR_PCI2_TWO_VARS_2),
 
3101
    gShellDebug1HiiHandle,
 
3102
    Bridge->PrefetchableLimitUpper,
 
3103
    (Bridge->PrefetchableMemLimit << 16) | 0x000fffff
 
3104
   );
 
3105
 
 
3106
  //
 
3107
  // Print register Capabilities Pointer
 
3108
  //
 
3109
  ShellPrintHiiEx(-1, -1, NULL,
 
3110
    STRING_TOKEN (STR_PCI2_CAPABILITIES_PTR_2),
 
3111
    gShellDebug1HiiHandle,
 
3112
    INDEX_OF (&(Bridge->CapabilitiesPtr)),
 
3113
    Bridge->CapabilitiesPtr
 
3114
   );
 
3115
 
 
3116
  //
 
3117
  // Print register Bridge Control
 
3118
  //
 
3119
  PciExplainBridgeControl (&(Bridge->BridgeControl), PciP2pBridge);
 
3120
 
 
3121
  //
 
3122
  // Print register Interrupt Line & PIN
 
3123
  //
 
3124
  ShellPrintHiiEx(-1, -1, NULL,
 
3125
    STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_2),
 
3126
    gShellDebug1HiiHandle,
 
3127
    INDEX_OF (&(Bridge->InterruptLine)),
 
3128
    Bridge->InterruptLine
 
3129
   );
 
3130
 
 
3131
  ShellPrintHiiEx(-1, -1, NULL,
 
3132
    STRING_TOKEN (STR_PCI2_INTERRUPT_PIN),
 
3133
    gShellDebug1HiiHandle,
 
3134
    INDEX_OF (&(Bridge->InterruptPin)),
 
3135
    Bridge->InterruptPin
 
3136
   );
 
3137
 
 
3138
  return EFI_SUCCESS;
 
3139
}
 
3140
 
 
3141
/**
 
3142
  Explain the Base Address Register(Bar) in PCI configuration space.
 
3143
 
 
3144
  @param[in] Bar              Points to the Base Address Register intended to interpret.
 
3145
  @param[in] Command          Points to the register Command.
 
3146
  @param[in] Address          Address used to access configuration space of this PCI device.
 
3147
  @param[in] IoDev            Handle used to access configuration space of PCI device.
 
3148
  @param[in, out] Index       The Index.
 
3149
 
 
3150
  @retval EFI_SUCCESS     The command completed successfully.
 
3151
**/
 
3152
EFI_STATUS
 
3153
PciExplainBar (
 
3154
  IN UINT32                                 *Bar,
 
3155
  IN UINT16                                 *Command,
 
3156
  IN UINT64                                 Address,
 
3157
  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev,
 
3158
  IN OUT UINTN                              *Index
 
3159
  )
 
3160
{
 
3161
  UINT16  OldCommand;
 
3162
  UINT16  NewCommand;
 
3163
  UINT64  Bar64;
 
3164
  UINT32  OldBar32;
 
3165
  UINT32  NewBar32;
 
3166
  UINT64  OldBar64;
 
3167
  UINT64  NewBar64;
 
3168
  BOOLEAN IsMem;
 
3169
  BOOLEAN IsBar32;
 
3170
  UINT64  RegAddress;
 
3171
 
 
3172
  IsBar32   = TRUE;
 
3173
  Bar64     = 0;
 
3174
  NewBar32  = 0;
 
3175
  NewBar64  = 0;
 
3176
 
 
3177
  //
 
3178
  // According the bar type, list detail about this bar, for example: 32 or
 
3179
  // 64 bits; pre-fetchable or not.
 
3180
  //
 
3181
  if ((*Bar & PCI_BIT_0) == 0) {
 
3182
    //
 
3183
    // This bar is of memory type
 
3184
    //
 
3185
    IsMem = TRUE;
 
3186
 
 
3187
    if ((*Bar & PCI_BIT_1) == 0 && (*Bar & PCI_BIT_2) == 0) {
 
3188
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0);
 
3189
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle);
 
3190
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_32_BITS), gShellDebug1HiiHandle);
 
3191
 
 
3192
    } else if ((*Bar & PCI_BIT_1) == 0 && (*Bar & PCI_BIT_2) != 0) {
 
3193
      Bar64 = 0x0;
 
3194
      CopyMem (&Bar64, Bar, sizeof (UINT64));
 
3195
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_2), gShellDebug1HiiHandle, (UINT32) RShiftU64 ((Bar64 & 0xfffffffffffffff0ULL), 32));
 
3196
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_3), gShellDebug1HiiHandle, (UINT32) (Bar64 & 0xfffffffffffffff0ULL));
 
3197
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM), gShellDebug1HiiHandle);
 
3198
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_64_BITS), gShellDebug1HiiHandle);
 
3199
      IsBar32 = FALSE;
 
3200
      *Index += 1;
 
3201
 
 
3202
    } else {
 
3203
      //
 
3204
      // Reserved
 
3205
      //
 
3206
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BAR), gShellDebug1HiiHandle, *Bar & 0xfffffff0);
 
3207
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEM_2), gShellDebug1HiiHandle);
 
3208
    }
 
3209
 
 
3210
    if ((*Bar & PCI_BIT_3) == 0) {
 
3211
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NO), gShellDebug1HiiHandle);
 
3212
 
 
3213
    } else {
 
3214
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_YES), gShellDebug1HiiHandle);
 
3215
    }
 
3216
 
 
3217
  } else {
 
3218
    //
 
3219
    // This bar is of io type
 
3220
    //
 
3221
    IsMem = FALSE;
 
3222
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_4), gShellDebug1HiiHandle, *Bar & 0xfffffffc);
 
3223
    Print (L"I/O                               ");
 
3224
  }
 
3225
 
 
3226
  //
 
3227
  // Get BAR length(or the amount of resource this bar demands for). To get
 
3228
  // Bar length, first we should temporarily disable I/O and memory access
 
3229
  // of this function(by set bits in the register Command), then write all
 
3230
  // "1"s to this bar. The bar value read back is the amount of resource
 
3231
  // this bar demands for.
 
3232
  //
 
3233
  //
 
3234
  // Disable io & mem access
 
3235
  //
 
3236
  OldCommand  = *Command;
 
3237
  NewCommand  = (UINT16) (OldCommand & 0xfffc);
 
3238
  RegAddress  = Address | INDEX_OF (Command);
 
3239
  IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &NewCommand);
 
3240
 
 
3241
  RegAddress = Address | INDEX_OF (Bar);
 
3242
 
 
3243
  //
 
3244
  // Read after write the BAR to get the size
 
3245
  //
 
3246
  if (IsBar32) {
 
3247
    OldBar32  = *Bar;
 
3248
    NewBar32  = 0xffffffff;
 
3249
 
 
3250
    IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32);
 
3251
    IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 1, &NewBar32);
 
3252
    IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 1, &OldBar32);
 
3253
 
 
3254
    if (IsMem) {
 
3255
      NewBar32  = NewBar32 & 0xfffffff0;
 
3256
      NewBar32  = (~NewBar32) + 1;
 
3257
 
 
3258
    } else {
 
3259
      NewBar32  = NewBar32 & 0xfffffffc;
 
3260
      NewBar32  = (~NewBar32) + 1;
 
3261
      NewBar32  = NewBar32 & 0x0000ffff;
 
3262
    }
 
3263
  } else {
 
3264
 
 
3265
    OldBar64 = 0x0;
 
3266
    CopyMem (&OldBar64, Bar, sizeof (UINT64));
 
3267
    NewBar64 = 0xffffffffffffffffULL;
 
3268
 
 
3269
    IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64);
 
3270
    IoDev->Pci.Read (IoDev, EfiPciWidthUint32, RegAddress, 2, &NewBar64);
 
3271
    IoDev->Pci.Write (IoDev, EfiPciWidthUint32, RegAddress, 2, &OldBar64);
 
3272
 
 
3273
    if (IsMem) {
 
3274
      NewBar64  = NewBar64 & 0xfffffffffffffff0ULL;
 
3275
      NewBar64  = (~NewBar64) + 1;
 
3276
 
 
3277
    } else {
 
3278
      NewBar64  = NewBar64 & 0xfffffffffffffffcULL;
 
3279
      NewBar64  = (~NewBar64) + 1;
 
3280
      NewBar64  = NewBar64 & 0x000000000000ffff;
 
3281
    }
 
3282
  }
 
3283
  //
 
3284
  // Enable io & mem access
 
3285
  //
 
3286
  RegAddress = Address | INDEX_OF (Command);
 
3287
  IoDev->Pci.Write (IoDev, EfiPciWidthUint16, RegAddress, 1, &OldCommand);
 
3288
 
 
3289
  if (IsMem) {
 
3290
    if (IsBar32) {
 
3291
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32), gShellDebug1HiiHandle, NewBar32);
 
3292
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_2), gShellDebug1HiiHandle, NewBar32 + (*Bar & 0xfffffff0) - 1);
 
3293
 
 
3294
    } else {
 
3295
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) RShiftU64 (NewBar64, 32));
 
3296
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) NewBar64);
 
3297
      Print (L"  ");
 
3298
      ShellPrintHiiEx(-1, -1, NULL,
 
3299
        STRING_TOKEN (STR_PCI2_RSHIFT),
 
3300
        gShellDebug1HiiHandle,
 
3301
        (UINT32) RShiftU64 ((NewBar64 + (Bar64 & 0xfffffffffffffff0ULL) - 1), 32)
 
3302
       );
 
3303
      ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) (NewBar64 + (Bar64 & 0xfffffffffffffff0ULL) - 1));
 
3304
 
 
3305
    }
 
3306
  } else {
 
3307
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_3), gShellDebug1HiiHandle, NewBar32);
 
3308
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEWBAR_32_4), gShellDebug1HiiHandle, NewBar32 + (*Bar & 0xfffffffc) - 1);
 
3309
  }
 
3310
 
 
3311
  return EFI_SUCCESS;
 
3312
}
 
3313
 
 
3314
/**
 
3315
  Explain the cardbus specific part of data in PCI configuration space.
 
3316
 
 
3317
  @param[in] CardBus         CardBus specific region of PCI configuration space.
 
3318
  @param[in] Address         Address used to access configuration space of this PCI device.
 
3319
  @param[in] IoDev           Handle used to access configuration space of PCI device.
 
3320
 
 
3321
  @retval EFI_SUCCESS     The command completed successfully.
 
3322
**/
 
3323
EFI_STATUS
 
3324
PciExplainCardBusData (
 
3325
  IN PCI_CARDBUS_HEADER                     *CardBus,
 
3326
  IN UINT64                                 Address,
 
3327
  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *IoDev
 
3328
  )
 
3329
{
 
3330
  BOOLEAN           Io32Bit;
 
3331
  PCI_CARDBUS_DATA  *CardBusData;
 
3332
 
 
3333
  ShellPrintHiiEx(-1, -1, NULL,
 
3334
    STRING_TOKEN (STR_PCI2_CARDBUS_SOCKET),
 
3335
    gShellDebug1HiiHandle,
 
3336
    INDEX_OF (&(CardBus->CardBusSocketReg)),
 
3337
    CardBus->CardBusSocketReg
 
3338
   );
 
3339
 
 
3340
  //
 
3341
  // Print Secondary Status
 
3342
  //
 
3343
  PciExplainStatus (&(CardBus->SecondaryStatus), FALSE, PciCardBusBridge);
 
3344
 
 
3345
  //
 
3346
  // Print Bus Numbers(Primary bus number, CardBus bus number, and
 
3347
  // Subordinate bus number
 
3348
  //
 
3349
  ShellPrintHiiEx(-1, -1, NULL,
 
3350
    STRING_TOKEN (STR_PCI2_BUS_NUMBERS_2),
 
3351
    gShellDebug1HiiHandle,
 
3352
    INDEX_OF (&(CardBus->PciBusNumber)),
 
3353
    INDEX_OF (&(CardBus->CardBusBusNumber)),
 
3354
    INDEX_OF (&(CardBus->SubordinateBusNumber))
 
3355
   );
 
3356
 
 
3357
  Print (L"               ------------------------------------------------------\n");
 
3358
 
 
3359
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS), gShellDebug1HiiHandle, CardBus->PciBusNumber);
 
3360
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_2), gShellDebug1HiiHandle, CardBus->CardBusBusNumber);
 
3361
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_3), gShellDebug1HiiHandle, CardBus->SubordinateBusNumber);
 
3362
 
 
3363
  //
 
3364
  // Print CardBus Latency Timer
 
3365
  //
 
3366
  ShellPrintHiiEx(-1, -1, NULL,
 
3367
    STRING_TOKEN (STR_PCI2_CARDBUS_LATENCY),
 
3368
    gShellDebug1HiiHandle,
 
3369
    INDEX_OF (&(CardBus->CardBusLatencyTimer)),
 
3370
    CardBus->CardBusLatencyTimer
 
3371
   );
 
3372
 
 
3373
  //
 
3374
  // Print Memory/Io ranges this cardbus bridge forwards
 
3375
  //
 
3376
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE_2), gShellDebug1HiiHandle);
 
3377
  Print (L"----------------------------------------------------------------------\n");
 
3378
 
 
3379
  ShellPrintHiiEx(-1, -1, NULL,
 
3380
    STRING_TOKEN (STR_PCI2_MEM_3),
 
3381
    gShellDebug1HiiHandle,
 
3382
    INDEX_OF (&(CardBus->MemoryBase0)),
 
3383
    CardBus->BridgeControl & PCI_BIT_8 ? L"    Prefetchable" : L"Non-Prefetchable",
 
3384
    CardBus->MemoryBase0 & 0xfffff000,
 
3385
    CardBus->MemoryLimit0 | 0x00000fff
 
3386
   );
 
3387
 
 
3388
  ShellPrintHiiEx(-1, -1, NULL,
 
3389
    STRING_TOKEN (STR_PCI2_MEM_3),
 
3390
    gShellDebug1HiiHandle,
 
3391
    INDEX_OF (&(CardBus->MemoryBase1)),
 
3392
    CardBus->BridgeControl & PCI_BIT_9 ? L"    Prefetchable" : L"Non-Prefetchable",
 
3393
    CardBus->MemoryBase1 & 0xfffff000,
 
3394
    CardBus->MemoryLimit1 | 0x00000fff
 
3395
   );
 
3396
 
 
3397
  Io32Bit = (BOOLEAN) (CardBus->IoBase0 & PCI_BIT_0);
 
3398
  ShellPrintHiiEx(-1, -1, NULL,
 
3399
    STRING_TOKEN (STR_PCI2_IO_2),
 
3400
    gShellDebug1HiiHandle,
 
3401
    INDEX_OF (&(CardBus->IoBase0)),
 
3402
    Io32Bit ? L"          32 bit" : L"          16 bit",
 
3403
    CardBus->IoBase0 & (Io32Bit ? 0xfffffffc : 0x0000fffc),
 
3404
    (CardBus->IoLimit0 & (Io32Bit ? 0xffffffff : 0x0000ffff)) | 0x00000003
 
3405
   );
 
3406
 
 
3407
  Io32Bit = (BOOLEAN) (CardBus->IoBase1 & PCI_BIT_0);
 
3408
  ShellPrintHiiEx(-1, -1, NULL,
 
3409
    STRING_TOKEN (STR_PCI2_IO_2),
 
3410
    gShellDebug1HiiHandle,
 
3411
    INDEX_OF (&(CardBus->IoBase1)),
 
3412
    Io32Bit ? L"          32 bit" : L"          16 bit",
 
3413
    CardBus->IoBase1 & (Io32Bit ? 0xfffffffc : 0x0000fffc),
 
3414
    (CardBus->IoLimit1 & (Io32Bit ? 0xffffffff : 0x0000ffff)) | 0x00000003
 
3415
   );
 
3416
 
 
3417
  //
 
3418
  // Print register Interrupt Line & PIN
 
3419
  //
 
3420
  ShellPrintHiiEx(-1, -1, NULL,
 
3421
    STRING_TOKEN (STR_PCI2_INTERRUPT_LINE_3),
 
3422
    gShellDebug1HiiHandle,
 
3423
    INDEX_OF (&(CardBus->InterruptLine)),
 
3424
    CardBus->InterruptLine,
 
3425
    INDEX_OF (&(CardBus->InterruptPin)),
 
3426
    CardBus->InterruptPin
 
3427
   );
 
3428
 
 
3429
  //
 
3430
  // Print register Bridge Control
 
3431
  //
 
3432
  PciExplainBridgeControl (&(CardBus->BridgeControl), PciCardBusBridge);
 
3433
 
 
3434
  //
 
3435
  // Print some registers in data region of PCI configuration space for cardbus
 
3436
  // bridge. Fields include: Sub VendorId, Subsystem ID, and Legacy Mode Base
 
3437
  // Address.
 
3438
  //
 
3439
  CardBusData = (PCI_CARDBUS_DATA *) ((UINT8 *) CardBus + sizeof (PCI_CARDBUS_HEADER));
 
3440
 
 
3441
  ShellPrintHiiEx(-1, -1, NULL,
 
3442
    STRING_TOKEN (STR_PCI2_SUB_VENDOR_ID_2),
 
3443
    gShellDebug1HiiHandle,
 
3444
    INDEX_OF (&(CardBusData->SubVendorId)),
 
3445
    CardBusData->SubVendorId,
 
3446
    INDEX_OF (&(CardBusData->SubSystemId)),
 
3447
    CardBusData->SubSystemId
 
3448
   );
 
3449
 
 
3450
  ShellPrintHiiEx(-1, -1, NULL,
 
3451
    STRING_TOKEN (STR_PCI2_OPTIONAL),
 
3452
    gShellDebug1HiiHandle,
 
3453
    INDEX_OF (&(CardBusData->LegacyBase)),
 
3454
    CardBusData->LegacyBase
 
3455
   );
 
3456
 
 
3457
  return EFI_SUCCESS;
 
3458
}
 
3459
 
 
3460
/**
 
3461
  Explain each meaningful bit of register Status. The definition of Status is
 
3462
  slightly different depending on the PCI header type.
 
3463
 
 
3464
  @param[in] Status          Points to the content of register Status.
 
3465
  @param[in] MainStatus      Indicates if this register is main status(not secondary
 
3466
                             status).
 
3467
  @param[in] HeaderType      Header type of this PCI device.
 
3468
 
 
3469
  @retval EFI_SUCCESS     The command completed successfully.
 
3470
**/
 
3471
EFI_STATUS
 
3472
PciExplainStatus (
 
3473
  IN UINT16                                 *Status,
 
3474
  IN BOOLEAN                                MainStatus,
 
3475
  IN PCI_HEADER_TYPE                        HeaderType
 
3476
  )
 
3477
{
 
3478
  if (MainStatus) {
 
3479
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_STATUS), gShellDebug1HiiHandle, INDEX_OF (Status), *Status);
 
3480
 
 
3481
  } else {
 
3482
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SECONDARY_STATUS), gShellDebug1HiiHandle, INDEX_OF (Status), *Status);
 
3483
  }
 
3484
 
 
3485
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NEW_CAPABILITIES), gShellDebug1HiiHandle, (*Status & PCI_BIT_4) != 0);
 
3486
 
 
3487
  //
 
3488
  // Bit 5 is meaningless for CardBus Bridge
 
3489
  //
 
3490
  if (HeaderType == PciCardBusBridge) {
 
3491
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_66_CAPABLE), gShellDebug1HiiHandle, (*Status & PCI_BIT_5) != 0);
 
3492
 
 
3493
  } else {
 
3494
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_66_CAPABLE_2), gShellDebug1HiiHandle, (*Status & PCI_BIT_5) != 0);
 
3495
  }
 
3496
 
 
3497
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_FAST_BACK), gShellDebug1HiiHandle, (*Status & PCI_BIT_7) != 0);
 
3498
 
 
3499
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MASTER_DATA), gShellDebug1HiiHandle, (*Status & PCI_BIT_8) != 0);
 
3500
  //
 
3501
  // Bit 9 and bit 10 together decides the DEVSEL timing
 
3502
  //
 
3503
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_DEVSEL_TIMING), gShellDebug1HiiHandle);
 
3504
  if ((*Status & PCI_BIT_9) == 0 && (*Status & PCI_BIT_10) == 0) {
 
3505
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_FAST), gShellDebug1HiiHandle);
 
3506
 
 
3507
  } else if ((*Status & PCI_BIT_9) != 0 && (*Status & PCI_BIT_10) == 0) {
 
3508
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_MEDIUM), gShellDebug1HiiHandle);
 
3509
 
 
3510
  } else if ((*Status & PCI_BIT_9) == 0 && (*Status & PCI_BIT_10) != 0) {
 
3511
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_SLOW), gShellDebug1HiiHandle);
 
3512
 
 
3513
  } else {
 
3514
    ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESERVED_2), gShellDebug1HiiHandle);
 
3515
  }
 
3516
 
 
3517
  ShellPrintHiiEx(-1, -1, NULL,
 
3518
    STRING_TOKEN (STR_PCI2_SIGNALED_TARGET),
 
3519
    gShellDebug1HiiHandle,
 
3520
    (*Status & PCI_BIT_11) != 0
 
3521
   );
 
3522
 
 
3523
  ShellPrintHiiEx(-1, -1, NULL,
 
3524
    STRING_TOKEN (STR_PCI2_RECEIVED_TARGET),
 
3525
    gShellDebug1HiiHandle,
 
3526
    (*Status & PCI_BIT_12) != 0
 
3527
   );
 
3528
 
 
3529
  ShellPrintHiiEx(-1, -1, NULL,
 
3530
    STRING_TOKEN (STR_PCI2_RECEIVED_MASTER),
 
3531
    gShellDebug1HiiHandle,
 
3532
    (*Status & PCI_BIT_13) != 0
 
3533
   );
 
3534
 
 
3535
  if (MainStatus) {
 
3536
    ShellPrintHiiEx(-1, -1, NULL,
 
3537
      STRING_TOKEN (STR_PCI2_SIGNALED_ERROR),
 
3538
      gShellDebug1HiiHandle,
 
3539
      (*Status & PCI_BIT_14) != 0
 
3540
     );
 
3541
 
 
3542
  } else {
 
3543
    ShellPrintHiiEx(-1, -1, NULL,
 
3544
      STRING_TOKEN (STR_PCI2_RECEIVED_ERROR),
 
3545
      gShellDebug1HiiHandle,
 
3546
      (*Status & PCI_BIT_14) != 0
 
3547
     );
 
3548
  }
 
3549
 
 
3550
  ShellPrintHiiEx(-1, -1, NULL,
 
3551
    STRING_TOKEN (STR_PCI2_DETECTED_ERROR),
 
3552
    gShellDebug1HiiHandle,
 
3553
    (*Status & PCI_BIT_15) != 0
 
3554
   );
 
3555
 
 
3556
  return EFI_SUCCESS;
 
3557
}
 
3558
 
 
3559
/**
 
3560
  Explain each meaningful bit of register Command.
 
3561
 
 
3562
  @param[in] Command         Points to the content of register Command.
 
3563
 
 
3564
  @retval EFI_SUCCESS     The command completed successfully.
 
3565
**/
 
3566
EFI_STATUS
 
3567
PciExplainCommand (
 
3568
  IN UINT16                                 *Command
 
3569
  )
 
3570
{
 
3571
  //
 
3572
  // Print the binary value of register Command
 
3573
  //
 
3574
  ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_COMMAND), gShellDebug1HiiHandle, INDEX_OF (Command), *Command);
 
3575
 
 
3576
  //
 
3577
  // Explain register Command bit by bit
 
3578
  //
 
3579
  ShellPrintHiiEx(-1, -1, NULL,
 
3580
    STRING_TOKEN (STR_PCI2_SPACE_ACCESS_DENIED),
 
3581
    gShellDebug1HiiHandle,
 
3582
    (*Command & PCI_BIT_0) != 0
 
3583
   );
 
3584
 
 
3585
  ShellPrintHiiEx(-1, -1, NULL,
 
3586
    STRING_TOKEN (STR_PCI2_MEMORY_SPACE),
 
3587
    gShellDebug1HiiHandle,
 
3588
    (*Command & PCI_BIT_1) != 0
 
3589
   );
 
3590
 
 
3591
  ShellPrintHiiEx(-1, -1, NULL,
 
3592
    STRING_TOKEN (STR_PCI2_BEHAVE_BUS_MASTER),
 
3593
    gShellDebug1HiiHandle,
 
3594
    (*Command & PCI_BIT_2) != 0
 
3595
   );
 
3596
 
 
3597
  ShellPrintHiiEx(-1, -1, NULL,
 
3598
    STRING_TOKEN (STR_PCI2_MONITOR_SPECIAL_CYCLE),
 
3599
    gShellDebug1HiiHandle,
 
3600
    (*Command & PCI_BIT_3) != 0
 
3601
   );
 
3602
 
 
3603
  ShellPrintHiiEx(-1, -1, NULL,
 
3604
    STRING_TOKEN (STR_PCI2_MEM_WRITE_INVALIDATE),
 
3605
    gShellDebug1HiiHandle,
 
3606
    (*Command & PCI_BIT_4) != 0
 
3607
   );
 
3608
 
 
3609
  ShellPrintHiiEx(-1, -1, NULL,
 
3610
    STRING_TOKEN (STR_PCI2_PALETTE_SNOOPING),
 
3611
    gShellDebug1HiiHandle,
 
3612
    (*Command & PCI_BIT_5) != 0
 
3613
   );
 
3614
 
 
3615
  ShellPrintHiiEx(-1, -1, NULL,
 
3616
    STRING_TOKEN (STR_PCI2_ASSERT_PERR),
 
3617
    gShellDebug1HiiHandle,
 
3618
    (*Command & PCI_BIT_6) != 0
 
3619
   );
 
3620
 
 
3621
  ShellPrintHiiEx(-1, -1, NULL,
 
3622
    STRING_TOKEN (STR_PCI2_DO_ADDR_STEPPING),
 
3623
    gShellDebug1HiiHandle,
 
3624
    (*Command & PCI_BIT_7) != 0
 
3625
   );
 
3626
 
 
3627
  ShellPrintHiiEx(-1, -1, NULL,
 
3628
    STRING_TOKEN (STR_PCI2_SERR_DRIVER),
 
3629
    gShellDebug1HiiHandle,
 
3630
    (*Command & PCI_BIT_8) != 0
 
3631
   );
 
3632
 
 
3633
  ShellPrintHiiEx(-1, -1, NULL,
 
3634
    STRING_TOKEN (STR_PCI2_FAST_BACK_2),
 
3635
    gShellDebug1HiiHandle,
 
3636
    (*Command & PCI_BIT_9) != 0
 
3637
   );
 
3638
 
 
3639
  return EFI_SUCCESS;
 
3640
}
 
3641
 
 
3642
/**
 
3643
  Explain each meaningful bit of register Bridge Control.
 
3644
 
 
3645
  @param[in] BridgeControl   Points to the content of register Bridge Control.
 
3646
  @param[in] HeaderType      The headertype.
 
3647
 
 
3648
  @retval EFI_SUCCESS     The command completed successfully.
 
3649
**/
 
3650
EFI_STATUS
 
3651
PciExplainBridgeControl (
 
3652
  IN UINT16                                 *BridgeControl,
 
3653
  IN PCI_HEADER_TYPE                        HeaderType
 
3654
  )
 
3655
{
 
3656
  ShellPrintHiiEx(-1, -1, NULL,
 
3657
    STRING_TOKEN (STR_PCI2_BRIDGE_CONTROL),
 
3658
    gShellDebug1HiiHandle,
 
3659
    INDEX_OF (BridgeControl),
 
3660
    *BridgeControl
 
3661
   );
 
3662
 
 
3663
  ShellPrintHiiEx(-1, -1, NULL,
 
3664
    STRING_TOKEN (STR_PCI2_PARITY_ERROR),
 
3665
    gShellDebug1HiiHandle,
 
3666
    (*BridgeControl & PCI_BIT_0) != 0
 
3667
   );
 
3668
  ShellPrintHiiEx(-1, -1, NULL,
 
3669
    STRING_TOKEN (STR_PCI2_SERR_ENABLE),
 
3670
    gShellDebug1HiiHandle,
 
3671
    (*BridgeControl & PCI_BIT_1) != 0
 
3672
   );
 
3673
  ShellPrintHiiEx(-1, -1, NULL,
 
3674
    STRING_TOKEN (STR_PCI2_ISA_ENABLE),
 
3675
    gShellDebug1HiiHandle,
 
3676
    (*BridgeControl & PCI_BIT_2) != 0
 
3677
   );
 
3678
  ShellPrintHiiEx(-1, -1, NULL,
 
3679
    STRING_TOKEN (STR_PCI2_VGA_ENABLE),
 
3680
    gShellDebug1HiiHandle,
 
3681
    (*BridgeControl & PCI_BIT_3) != 0
 
3682
   );
 
3683
  ShellPrintHiiEx(-1, -1, NULL,
 
3684
    STRING_TOKEN (STR_PCI2_MASTER_ABORT),
 
3685
    gShellDebug1HiiHandle,
 
3686
    (*BridgeControl & PCI_BIT_5) != 0
 
3687
   );
 
3688
 
 
3689
  //
 
3690
  // Register Bridge Control has some slight differences between P2P bridge
 
3691
  // and Cardbus bridge from bit 6 to bit 11.
 
3692
  //
 
3693
  if (HeaderType == PciP2pBridge) {
 
3694
    ShellPrintHiiEx(-1, -1, NULL,
 
3695
      STRING_TOKEN (STR_PCI2_SECONDARY_BUS_RESET),
 
3696
      gShellDebug1HiiHandle,
 
3697
      (*BridgeControl & PCI_BIT_6) != 0
 
3698
     );
 
3699
    ShellPrintHiiEx(-1, -1, NULL,
 
3700
      STRING_TOKEN (STR_PCI2_FAST_ENABLE),
 
3701
      gShellDebug1HiiHandle,
 
3702
      (*BridgeControl & PCI_BIT_7) != 0
 
3703
     );
 
3704
    ShellPrintHiiEx(-1, -1, NULL,
 
3705
      STRING_TOKEN (STR_PCI2_PRIMARY_DISCARD_TIMER),
 
3706
      gShellDebug1HiiHandle,
 
3707
      (*BridgeControl & PCI_BIT_8)!=0 ? L"2^10" : L"2^15"
 
3708
     );
 
3709
    ShellPrintHiiEx(-1, -1, NULL,
 
3710
      STRING_TOKEN (STR_PCI2_SECONDARY_DISCARD_TIMER),
 
3711
      gShellDebug1HiiHandle,
 
3712
      (*BridgeControl & PCI_BIT_9)!=0 ? L"2^10" : L"2^15"
 
3713
     );
 
3714
    ShellPrintHiiEx(-1, -1, NULL,
 
3715
      STRING_TOKEN (STR_PCI2_DISCARD_TIMER_STATUS),
 
3716
      gShellDebug1HiiHandle,
 
3717
      (*BridgeControl & PCI_BIT_10) != 0
 
3718
     );
 
3719
    ShellPrintHiiEx(-1, -1, NULL,
 
3720
      STRING_TOKEN (STR_PCI2_DISCARD_TIMER_SERR),
 
3721
      gShellDebug1HiiHandle,
 
3722
      (*BridgeControl & PCI_BIT_11) != 0
 
3723
     );
 
3724
 
 
3725
  } else {
 
3726
    ShellPrintHiiEx(-1, -1, NULL,
 
3727
      STRING_TOKEN (STR_PCI2_CARDBUS_RESET),
 
3728
      gShellDebug1HiiHandle,
 
3729
      (*BridgeControl & PCI_BIT_6) != 0
 
3730
     );
 
3731
    ShellPrintHiiEx(-1, -1, NULL,
 
3732
      STRING_TOKEN (STR_PCI2_IREQ_ENABLE),
 
3733
      gShellDebug1HiiHandle,
 
3734
      (*BridgeControl & PCI_BIT_7) != 0
 
3735
     );
 
3736
    ShellPrintHiiEx(-1, -1, NULL,
 
3737
      STRING_TOKEN (STR_PCI2_WRITE_POSTING_ENABLE),
 
3738
      gShellDebug1HiiHandle,
 
3739
      (*BridgeControl & PCI_BIT_10) != 0
 
3740
     );
 
3741
  }
 
3742
 
 
3743
  return EFI_SUCCESS;
 
3744
}
 
3745
 
 
3746
/**
 
3747
  Print each capability structure.
 
3748
 
 
3749
  @param[in] IoDev      The pointer to the deivce.
 
3750
  @param[in] Address    The address to start at.
 
3751
  @param[in] CapPtr     The offset from the address.
 
3752
 
 
3753
  @retval EFI_SUCCESS     The operation was successful.
 
3754
**/
 
3755
EFI_STATUS
 
3756
PciExplainCapabilityStruct (
 
3757
  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         *IoDev,
 
3758
  IN UINT64                                   Address,
 
3759
  IN  UINT8                                   CapPtr
 
3760
  )
 
3761
{
 
3762
  UINT8   CapabilityPtr;
 
3763
  UINT16  CapabilityEntry;
 
3764
  UINT8   CapabilityID;
 
3765
  UINT64  RegAddress;
 
3766
 
 
3767
  CapabilityPtr = CapPtr;
 
3768
 
 
3769
  //
 
3770
  // Go through the Capability list
 
3771
  //
 
3772
  while ((CapabilityPtr >= 0x40) && ((CapabilityPtr & 0x03) == 0x00)) {
 
3773
    RegAddress = Address + CapabilityPtr;
 
3774
    IoDev->Pci.Read (IoDev, EfiPciWidthUint16, RegAddress, 1, &CapabilityEntry);
 
3775
 
 
3776
    CapabilityID = (UINT8) CapabilityEntry;
 
3777
 
 
3778
    //
 
3779
    // Explain PciExpress data
 
3780
    //
 
3781
    if (EFI_PCI_CAPABILITY_ID_PCIEXP == CapabilityID) {
 
3782
      PciExplainPciExpress (IoDev, Address, CapabilityPtr);
 
3783
      return EFI_SUCCESS;
 
3784
    }
 
3785
    //
 
3786
    // Explain other capabilities here
 
3787
    //
 
3788
    CapabilityPtr = (UINT8) (CapabilityEntry >> 8);
 
3789
  }
 
3790
 
 
3791
  return EFI_SUCCESS;
 
3792
}
 
3793
 
 
3794
/**
 
3795
  Print out information of the capability information.
 
3796
 
 
3797
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
3798
 
 
3799
  @retval EFI_SUCCESS   The operation was successful.
 
3800
**/
 
3801
EFI_STATUS
 
3802
ExplainPcieCapReg (
 
3803
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
3804
  )
 
3805
{
 
3806
  UINT16 PcieCapReg;
 
3807
  CHAR16 *DevicePortType;
 
3808
 
 
3809
  PcieCapReg = PciExpressCap->PcieCapReg;
 
3810
  Print (
 
3811
    L"  Capability Version(3:0):          %E0x%04x%N\n",
 
3812
    PCIE_CAP_VERSION (PcieCapReg)
 
3813
   );
 
3814
  if ((UINT8) PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) < PCIE_DEVICE_PORT_TYPE_MAX) {
 
3815
    DevicePortType = DevicePortTypeTable[PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg)];
 
3816
  } else {
 
3817
    DevicePortType = L"Unknown Type";
 
3818
  }
 
3819
  Print (
 
3820
    L"  Device/PortType(7:4):             %E%s%N\n",
 
3821
    DevicePortType
 
3822
   );
 
3823
  //
 
3824
  // 'Slot Implemented' is only valid for:
 
3825
  // a) Root Port of PCI Express Root Complex, or
 
3826
  // b) Downstream Port of PCI Express Switch
 
3827
  //
 
3828
  if (PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_ROOT_COMPLEX_ROOT_PORT ||
 
3829
      PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_SWITCH_DOWNSTREAM_PORT) {
 
3830
    Print (
 
3831
      L"  Slot Implemented(8):              %E%d%N\n",
 
3832
      PCIE_CAP_SLOT_IMPLEMENTED (PcieCapReg)
 
3833
     );
 
3834
  }
 
3835
  Print (
 
3836
    L"  Interrupt Message Number(13:9):   %E0x%05x%N\n",
 
3837
    PCIE_CAP_INT_MSG_NUM (PcieCapReg)
 
3838
   );
 
3839
  return EFI_SUCCESS;
 
3840
}
 
3841
 
 
3842
/**
 
3843
  Print out information of the device capability information.
 
3844
 
 
3845
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
3846
 
 
3847
  @retval EFI_SUCCESS   The operation was successful.
 
3848
**/
 
3849
EFI_STATUS
 
3850
ExplainPcieDeviceCap (
 
3851
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
3852
  )
 
3853
{
 
3854
  UINT16 PcieCapReg;
 
3855
  UINT32 PcieDeviceCap;
 
3856
  UINT8  DevicePortType;
 
3857
  UINT8  L0sLatency;
 
3858
  UINT8  L1Latency;
 
3859
 
 
3860
  PcieCapReg     = PciExpressCap->PcieCapReg;
 
3861
  PcieDeviceCap  = PciExpressCap->PcieDeviceCap;
 
3862
  DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg);
 
3863
  Print (L"  Max_Payload_Size Supported(2:0):          ");
 
3864
  if (PCIE_CAP_MAX_PAYLOAD (PcieDeviceCap) < 6) {
 
3865
    Print (L"%E%d bytes%N\n", 1 << (PCIE_CAP_MAX_PAYLOAD (PcieDeviceCap) + 7));
 
3866
  } else {
 
3867
    Print (L"%EUnknown%N\n");
 
3868
  }
 
3869
  Print (
 
3870
    L"  Phantom Functions Supported(4:3):         %E%d%N\n",
 
3871
    PCIE_CAP_PHANTOM_FUNC (PcieDeviceCap)
 
3872
   );
 
3873
  Print (
 
3874
    L"  Extended Tag Field Supported(5):          %E%d-bit Tag field supported%N\n",
 
3875
    PCIE_CAP_EXTENDED_TAG (PcieDeviceCap) ? 8 : 5
 
3876
   );
 
3877
  //
 
3878
  // Endpoint L0s and L1 Acceptable Latency is only valid for Endpoint
 
3879
  //
 
3880
  if (IS_PCIE_ENDPOINT (DevicePortType)) {
 
3881
    L0sLatency = (UINT8) PCIE_CAP_L0SLATENCY (PcieDeviceCap);
 
3882
    L1Latency  = (UINT8) PCIE_CAP_L1LATENCY (PcieDeviceCap);
 
3883
    Print (L"  Endpoint L0s Acceptable Latency(8:6):     ");
 
3884
    if (L0sLatency < 4) {
 
3885
      Print (L"%EMaximum of %d ns%N\n", 1 << (L0sLatency + 6));
 
3886
    } else {
 
3887
      if (L0sLatency < 7) {
 
3888
        Print (L"%EMaximum of %d us%N\n", 1 << (L0sLatency - 3));
 
3889
      } else {
 
3890
        Print (L"%ENo limit%N\n");
 
3891
      }
 
3892
    }
 
3893
    Print (L"  Endpoint L1 Acceptable Latency(11:9):     ");
 
3894
    if (L1Latency < 7) {
 
3895
      Print (L"%EMaximum of %d us%N\n", 1 << (L1Latency + 1));
 
3896
    } else {
 
3897
      Print (L"%ENo limit%N\n");
 
3898
    }
 
3899
  }
 
3900
  Print (
 
3901
    L"  Role-based Error Reporting(15):           %E%d%N\n",
 
3902
    PCIE_CAP_ERR_REPORTING (PcieDeviceCap)
 
3903
   );
 
3904
  //
 
3905
  // Only valid for Upstream Port:
 
3906
  // a) Captured Slot Power Limit Value
 
3907
  // b) Captured Slot Power Scale
 
3908
  //
 
3909
  if (DevicePortType == PCIE_SWITCH_UPSTREAM_PORT) {
 
3910
    Print (
 
3911
      L"  Captured Slot Power Limit Value(25:18):   %E0x%02x%N\n",
 
3912
      PCIE_CAP_SLOT_POWER_VALUE (PcieDeviceCap)
 
3913
     );
 
3914
    Print (
 
3915
      L"  Captured Slot Power Limit Scale(27:26):   %E%s%N\n",
 
3916
      SlotPwrLmtScaleTable[PCIE_CAP_SLOT_POWER_SCALE (PcieDeviceCap)]
 
3917
     );
 
3918
  }
 
3919
  //
 
3920
  // Function Level Reset Capability is only valid for Endpoint
 
3921
  //
 
3922
  if (IS_PCIE_ENDPOINT (DevicePortType)) {
 
3923
    Print (
 
3924
      L"  Function Level Reset Capability(28):      %E%d%N\n",
 
3925
      PCIE_CAP_FUNC_LEVEL_RESET (PcieDeviceCap)
 
3926
     );
 
3927
  }
 
3928
  return EFI_SUCCESS;
 
3929
}
 
3930
 
 
3931
/**
 
3932
  Print out information of the device control information.
 
3933
 
 
3934
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
3935
 
 
3936
  @retval EFI_SUCCESS   The operation was successful.
 
3937
**/
 
3938
EFI_STATUS
 
3939
ExplainPcieDeviceControl (
 
3940
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
3941
  )
 
3942
{
 
3943
  UINT16 PcieCapReg;
 
3944
  UINT16 PcieDeviceControl;
 
3945
 
 
3946
  PcieCapReg        = PciExpressCap->PcieCapReg;
 
3947
  PcieDeviceControl = PciExpressCap->DeviceControl;
 
3948
  Print (
 
3949
    L"  Correctable Error Reporting Enable(0):    %E%d%N\n",
 
3950
    PCIE_CAP_COR_ERR_REPORTING_ENABLE (PcieDeviceControl)
 
3951
   );
 
3952
  Print (
 
3953
    L"  Non-Fatal Error Reporting Enable(1):      %E%d%N\n",
 
3954
    PCIE_CAP_NONFAT_ERR_REPORTING_ENABLE (PcieDeviceControl)
 
3955
   );
 
3956
  Print (
 
3957
    L"  Fatal Error Reporting Enable(2):          %E%d%N\n",
 
3958
    PCIE_CAP_FATAL_ERR_REPORTING_ENABLE (PcieDeviceControl)
 
3959
   );
 
3960
  Print (
 
3961
    L"  Unsupported Request Reporting Enable(3):  %E%d%N\n",
 
3962
    PCIE_CAP_UNSUP_REQ_REPORTING_ENABLE (PcieDeviceControl)
 
3963
   );
 
3964
  Print (
 
3965
    L"  Enable Relaxed Ordering(4):               %E%d%N\n",
 
3966
    PCIE_CAP_RELAXED_ORDERING_ENABLE (PcieDeviceControl)
 
3967
   );
 
3968
  Print (L"  Max_Payload_Size(7:5):                    ");
 
3969
  if (PCIE_CAP_MAX_PAYLOAD_SIZE (PcieDeviceControl) < 6) {
 
3970
    Print (L"%E%d bytes%N\n", 1 << (PCIE_CAP_MAX_PAYLOAD_SIZE (PcieDeviceControl) + 7));
 
3971
  } else {
 
3972
    Print (L"%EUnknown%N\n");
 
3973
  }
 
3974
  Print (
 
3975
    L"  Extended Tag Field Enable(8):             %E%d%N\n",
 
3976
    PCIE_CAP_EXTENDED_TAG_ENABLE (PcieDeviceControl)
 
3977
   );
 
3978
  Print (
 
3979
    L"  Phantom Functions Enable(9):              %E%d%N\n",
 
3980
    PCIE_CAP_PHANTOM_FUNC_ENABLE (PcieDeviceControl)
 
3981
   );
 
3982
  Print (
 
3983
    L"  Auxiliary (AUX) Power PM Enable(10):      %E%d%N\n",
 
3984
    PCIE_CAP_AUX_PM_ENABLE (PcieDeviceControl)
 
3985
   );
 
3986
  Print (
 
3987
    L"  Enable No Snoop(11):                      %E%d%N\n",
 
3988
    PCIE_CAP_NO_SNOOP_ENABLE (PcieDeviceControl)
 
3989
   );
 
3990
  Print (L"  Max_Read_Request_Size(14:12):             ");
 
3991
  if (PCIE_CAP_MAX_READ_REQ_SIZE (PcieDeviceControl) < 6) {
 
3992
    Print (L"%E%d bytes%N\n", 1 << (PCIE_CAP_MAX_READ_REQ_SIZE (PcieDeviceControl) + 7));
 
3993
  } else {
 
3994
    Print (L"%EUnknown%N\n");
 
3995
  }
 
3996
  //
 
3997
  // Read operation is only valid for PCI Express to PCI/PCI-X Bridges
 
3998
  //
 
3999
  if (PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_PCIE_TO_PCIX_BRIDGE) {
 
4000
    Print (
 
4001
      L"  Bridge Configuration Retry Enable(15):  %E%d%N\n",
 
4002
      PCIE_CAP_BRG_CONF_RETRY (PcieDeviceControl)
 
4003
     );
 
4004
  }
 
4005
  return EFI_SUCCESS;
 
4006
}
 
4007
 
 
4008
/**
 
4009
  Print out information of the device status information.
 
4010
 
 
4011
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
4012
 
 
4013
  @retval EFI_SUCCESS   The operation was successful.
 
4014
**/
 
4015
EFI_STATUS
 
4016
ExplainPcieDeviceStatus (
 
4017
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
4018
  )
 
4019
{
 
4020
  UINT16 PcieDeviceStatus;
 
4021
 
 
4022
  PcieDeviceStatus = PciExpressCap->DeviceStatus;
 
4023
  Print (
 
4024
    L"  Correctable Error Detected(0):            %E%d%N\n",
 
4025
    PCIE_CAP_COR_ERR_DETECTED (PcieDeviceStatus)
 
4026
   );
 
4027
  Print (
 
4028
    L"  Non-Fatal Error Detected(1):              %E%d%N\n",
 
4029
    PCIE_CAP_NONFAT_ERR_DETECTED (PcieDeviceStatus)
 
4030
   );
 
4031
  Print (
 
4032
    L"  Fatal Error Detected(2):                  %E%d%N\n",
 
4033
    PCIE_CAP_FATAL_ERR_DETECTED (PcieDeviceStatus)
 
4034
   );
 
4035
  Print (
 
4036
    L"  Unsupported Request Detected(3):          %E%d%N\n",
 
4037
    PCIE_CAP_UNSUP_REQ_DETECTED (PcieDeviceStatus)
 
4038
   );
 
4039
  Print (
 
4040
    L"  AUX Power Detected(4):                    %E%d%N\n",
 
4041
    PCIE_CAP_AUX_POWER_DETECTED (PcieDeviceStatus)
 
4042
   );
 
4043
  Print (
 
4044
    L"  Transactions Pending(5):                  %E%d%N\n",
 
4045
    PCIE_CAP_TRANSACTION_PENDING (PcieDeviceStatus)
 
4046
   );
 
4047
  return EFI_SUCCESS;
 
4048
}
 
4049
 
 
4050
/**
 
4051
  Print out information of the device link information.
 
4052
 
 
4053
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
4054
 
 
4055
  @retval EFI_SUCCESS   The operation was successful.
 
4056
**/
 
4057
EFI_STATUS
 
4058
ExplainPcieLinkCap (
 
4059
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
4060
  )
 
4061
{
 
4062
  UINT32 PcieLinkCap;
 
4063
  CHAR16 *SupLinkSpeeds;
 
4064
  CHAR16 *AspmValue;
 
4065
 
 
4066
  PcieLinkCap = PciExpressCap->LinkCap;
 
4067
  switch (PCIE_CAP_SUP_LINK_SPEEDS (PcieLinkCap)) {
 
4068
    case 1:
 
4069
      SupLinkSpeeds = L"2.5 GT/s";
 
4070
      break;
 
4071
    case 2:
 
4072
      SupLinkSpeeds = L"5.0 GT/s and 2.5 GT/s";
 
4073
      break;
 
4074
    default:
 
4075
      SupLinkSpeeds = L"Unknown";
 
4076
      break;
 
4077
  }
 
4078
  Print (
 
4079
    L"  Supported Link Speeds(3:0):                         %E%s supported%N\n",
 
4080
    SupLinkSpeeds
 
4081
   );
 
4082
  Print (
 
4083
    L"  Maximum Link Width(9:4):                            %Ex%d%N\n",
 
4084
    PCIE_CAP_MAX_LINK_WIDTH (PcieLinkCap)
 
4085
   );
 
4086
  switch (PCIE_CAP_ASPM_SUPPORT (PcieLinkCap)) {
 
4087
    case 1:
 
4088
      AspmValue = L"L0s Entry";
 
4089
      break;
 
4090
    case 3:
 
4091
      AspmValue = L"L0s and L1";
 
4092
      break;
 
4093
    default:
 
4094
      AspmValue = L"Reserved";
 
4095
      break;
 
4096
  }
 
4097
  Print (
 
4098
    L"  Active State Power Management Support(11:10):       %E%s Supported%N\n",
 
4099
    AspmValue
 
4100
   );
 
4101
  Print (
 
4102
    L"  L0s Exit Latency(14:12):                            %E%s%N\n",
 
4103
    L0sLatencyStrTable[PCIE_CAP_L0S_LATENCY (PcieLinkCap)]
 
4104
   );
 
4105
  Print (
 
4106
    L"  L1 Exit Latency(17:15):                             %E%s%N\n",
 
4107
    L1LatencyStrTable[PCIE_CAP_L0S_LATENCY (PcieLinkCap)]
 
4108
   );
 
4109
  Print (
 
4110
    L"  Clock Power Management(18):                         %E%d%N\n",
 
4111
    PCIE_CAP_CLOCK_PM (PcieLinkCap)
 
4112
   );
 
4113
  Print (
 
4114
    L"  Surprise Down Error Reporting Capable(19):          %E%d%N\n",
 
4115
    PCIE_CAP_SUP_DOWN_ERR_REPORTING (PcieLinkCap)
 
4116
   );
 
4117
  Print (
 
4118
    L"  Data Link Layer Link Active Reporting Capable(20):  %E%d%N\n",
 
4119
    PCIE_CAP_LINK_ACTIVE_REPORTING (PcieLinkCap)
 
4120
   );
 
4121
  Print (
 
4122
    L"  Link Bandwidth Notification Capability(21):         %E%d%N\n",
 
4123
    PCIE_CAP_LINK_BWD_NOTIF_CAP (PcieLinkCap)
 
4124
   );
 
4125
  Print (
 
4126
    L"  Port Number(31:24):                                 %E0x%02x%N\n",
 
4127
    PCIE_CAP_PORT_NUMBER (PcieLinkCap)
 
4128
   );
 
4129
  return EFI_SUCCESS;
 
4130
}
 
4131
 
 
4132
/**
 
4133
  Print out information of the device link control information.
 
4134
 
 
4135
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
4136
 
 
4137
  @retval EFI_SUCCESS   The operation was successful.
 
4138
**/
 
4139
EFI_STATUS
 
4140
ExplainPcieLinkControl (
 
4141
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
4142
  )
 
4143
{
 
4144
  UINT16 PcieLinkControl;
 
4145
  UINT8  DevicePortType;
 
4146
 
 
4147
  PcieLinkControl = PciExpressCap->LinkControl;
 
4148
  DevicePortType  = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PciExpressCap->PcieCapReg);
 
4149
  Print (
 
4150
    L"  Active State Power Management Control(1:0):         %E%s%N\n",
 
4151
    ASPMCtrlStrTable[PCIE_CAP_ASPM_CONTROL (PcieLinkControl)]
 
4152
   );
 
4153
  //
 
4154
  // RCB is not applicable to switches
 
4155
  //
 
4156
  if (!IS_PCIE_SWITCH(DevicePortType)) {
 
4157
    Print (
 
4158
      L"  Read Completion Boundary (RCB)(3):                  %E%d byte%N\n",
 
4159
      1 << (PCIE_CAP_RCB (PcieLinkControl) + 6)
 
4160
     );
 
4161
  }
 
4162
  //
 
4163
  // Link Disable is reserved on
 
4164
  // a) Endpoints
 
4165
  // b) PCI Express to PCI/PCI-X bridges
 
4166
  // c) Upstream Ports of Switches
 
4167
  //
 
4168
  if (!IS_PCIE_ENDPOINT (DevicePortType) &&
 
4169
      DevicePortType != PCIE_SWITCH_UPSTREAM_PORT &&
 
4170
      DevicePortType != PCIE_PCIE_TO_PCIX_BRIDGE) {
 
4171
    Print (
 
4172
      L"  Link Disable(4):                                    %E%d%N\n",
 
4173
      PCIE_CAP_LINK_DISABLE (PcieLinkControl)
 
4174
     );
 
4175
  }
 
4176
  Print (
 
4177
    L"  Common Clock Configuration(6):                      %E%d%N\n",
 
4178
    PCIE_CAP_COMMON_CLK_CONF (PcieLinkControl)
 
4179
   );
 
4180
  Print (
 
4181
    L"  Extended Synch(7):                                  %E%d%N\n",
 
4182
    PCIE_CAP_EXT_SYNC (PcieLinkControl)
 
4183
   );
 
4184
  Print (
 
4185
    L"  Enable Clock Power Management(8):                   %E%d%N\n",
 
4186
    PCIE_CAP_CLK_PWR_MNG (PcieLinkControl)
 
4187
   );
 
4188
  Print (
 
4189
    L"  Hardware Autonomous Width Disable(9):               %E%d%N\n",
 
4190
    PCIE_CAP_HW_AUTO_WIDTH_DISABLE (PcieLinkControl)
 
4191
   );
 
4192
  Print (
 
4193
    L"  Link Bandwidth Management Interrupt Enable(10):     %E%d%N\n",
 
4194
    PCIE_CAP_LINK_BDW_MNG_INT_EN (PcieLinkControl)
 
4195
   );
 
4196
  Print (
 
4197
    L"  Link Autonomous Bandwidth Interrupt Enable(11):     %E%d%N\n",
 
4198
    PCIE_CAP_LINK_AUTO_BDW_INT_EN (PcieLinkControl)
 
4199
   );
 
4200
  return EFI_SUCCESS;
 
4201
}
 
4202
 
 
4203
/**
 
4204
  Print out information of the device link status information.
 
4205
 
 
4206
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
4207
 
 
4208
  @retval EFI_SUCCESS   The operation was successful.
 
4209
**/
 
4210
EFI_STATUS
 
4211
ExplainPcieLinkStatus (
 
4212
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
4213
  )
 
4214
{
 
4215
  UINT16 PcieLinkStatus;
 
4216
  CHAR16 *SupLinkSpeeds;
 
4217
 
 
4218
  PcieLinkStatus = PciExpressCap->LinkStatus;
 
4219
  switch (PCIE_CAP_CUR_LINK_SPEED (PcieLinkStatus)) {
 
4220
    case 1:
 
4221
      SupLinkSpeeds = L"2.5 GT/s";
 
4222
      break;
 
4223
    case 2:
 
4224
      SupLinkSpeeds = L"5.0 GT/s";
 
4225
      break;
 
4226
    default:
 
4227
      SupLinkSpeeds = L"Reserved";
 
4228
      break;
 
4229
  }
 
4230
  Print (
 
4231
    L"  Current Link Speed(3:0):                            %E%s%N\n",
 
4232
    SupLinkSpeeds
 
4233
   );
 
4234
  Print (
 
4235
    L"  Negotiated Link Width(9:4):                         %Ex%d%N\n",
 
4236
    PCIE_CAP_NEGO_LINK_WIDTH (PcieLinkStatus)
 
4237
   );
 
4238
  Print (
 
4239
    L"  Link Training(11):                                  %E%d%N\n",
 
4240
    PCIE_CAP_LINK_TRAINING (PcieLinkStatus)
 
4241
   );
 
4242
  Print (
 
4243
    L"  Slot Clock Configuration(12):                       %E%d%N\n",
 
4244
    PCIE_CAP_SLOT_CLK_CONF (PcieLinkStatus)
 
4245
   );
 
4246
  Print (
 
4247
    L"  Data Link Layer Link Active(13):                    %E%d%N\n",
 
4248
    PCIE_CAP_DATA_LINK_ACTIVE (PcieLinkStatus)
 
4249
   );
 
4250
  Print (
 
4251
    L"  Link Bandwidth Management Status(14):               %E%d%N\n",
 
4252
    PCIE_CAP_LINK_BDW_MNG_STAT (PcieLinkStatus)
 
4253
   );
 
4254
  Print (
 
4255
    L"  Link Autonomous Bandwidth Status(15):               %E%d%N\n",
 
4256
    PCIE_CAP_LINK_AUTO_BDW_STAT (PcieLinkStatus)
 
4257
   );
 
4258
  return EFI_SUCCESS;
 
4259
}
 
4260
 
 
4261
/**
 
4262
  Print out information of the device slot information.
 
4263
 
 
4264
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
4265
 
 
4266
  @retval EFI_SUCCESS   The operation was successful.
 
4267
**/
 
4268
EFI_STATUS
 
4269
ExplainPcieSlotCap (
 
4270
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
4271
  )
 
4272
{
 
4273
  UINT32 PcieSlotCap;
 
4274
 
 
4275
  PcieSlotCap = PciExpressCap->SlotCap;
 
4276
 
 
4277
  Print (
 
4278
    L"  Attention Button Present(0):                        %E%d%N\n",
 
4279
    PCIE_CAP_ATT_BUT_PRESENT (PcieSlotCap)
 
4280
   );
 
4281
  Print (
 
4282
    L"  Power Controller Present(1):                        %E%d%N\n",
 
4283
    PCIE_CAP_PWR_CTRLLER_PRESENT (PcieSlotCap)
 
4284
   );
 
4285
  Print (
 
4286
    L"  MRL Sensor Present(2):                              %E%d%N\n",
 
4287
    PCIE_CAP_MRL_SENSOR_PRESENT (PcieSlotCap)
 
4288
   );
 
4289
  Print (
 
4290
    L"  Attention Indicator Present(3):                     %E%d%N\n",
 
4291
    PCIE_CAP_ATT_IND_PRESENT (PcieSlotCap)
 
4292
   );
 
4293
  Print (
 
4294
    L"  Power Indicator Present(4):                         %E%d%N\n",
 
4295
    PCIE_CAP_PWD_IND_PRESENT (PcieSlotCap)
 
4296
   );
 
4297
  Print (
 
4298
    L"  Hot-Plug Surprise(5):                               %E%d%N\n",
 
4299
    PCIE_CAP_HOTPLUG_SUPPRISE (PcieSlotCap)
 
4300
   );
 
4301
  Print (
 
4302
    L"  Hot-Plug Capable(6):                                %E%d%N\n",
 
4303
    PCIE_CAP_HOTPLUG_CAPABLE (PcieSlotCap)
 
4304
   );
 
4305
  Print (
 
4306
    L"  Slot Power Limit Value(14:7):                       %E0x%02x%N\n",
 
4307
    PCIE_CAP_SLOT_PWR_LIMIT_VALUE (PcieSlotCap)
 
4308
   );
 
4309
  Print (
 
4310
    L"  Slot Power Limit Scale(16:15):                      %E%s%N\n",
 
4311
    SlotPwrLmtScaleTable[PCIE_CAP_SLOT_PWR_LIMIT_SCALE (PcieSlotCap)]
 
4312
   );
 
4313
  Print (
 
4314
    L"  Electromechanical Interlock Present(17):            %E%d%N\n",
 
4315
    PCIE_CAP_ELEC_INTERLOCK_PRESENT (PcieSlotCap)
 
4316
   );
 
4317
  Print (
 
4318
    L"  No Command Completed Support(18):                   %E%d%N\n",
 
4319
    PCIE_CAP_NO_COMM_COMPLETED_SUP (PcieSlotCap)
 
4320
   );
 
4321
  Print (
 
4322
    L"  Physical Slot Number(31:19):                        %E%d%N\n",
 
4323
    PCIE_CAP_PHY_SLOT_NUM (PcieSlotCap)
 
4324
   );
 
4325
 
 
4326
  return EFI_SUCCESS;
 
4327
}
 
4328
 
 
4329
/**
 
4330
  Print out information of the device slot control information.
 
4331
 
 
4332
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
4333
 
 
4334
  @retval EFI_SUCCESS   The operation was successful.
 
4335
**/
 
4336
EFI_STATUS
 
4337
ExplainPcieSlotControl (
 
4338
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
4339
  )
 
4340
{
 
4341
  UINT16 PcieSlotControl;
 
4342
 
 
4343
  PcieSlotControl = PciExpressCap->SlotControl;
 
4344
  Print (
 
4345
    L"  Attention Button Pressed Enable(0):                 %E%d%N\n",
 
4346
    PCIE_CAP_ATT_BUT_ENABLE (PcieSlotControl)
 
4347
   );
 
4348
  Print (
 
4349
    L"  Power Fault Detected Enable(1):                     %E%d%N\n",
 
4350
    PCIE_CAP_PWR_FLT_DETECT_ENABLE (PcieSlotControl)
 
4351
   );
 
4352
  Print (
 
4353
    L"  MRL Sensor Changed Enable(2):                       %E%d%N\n",
 
4354
    PCIE_CAP_MRL_SENSOR_CHANGE_ENABLE (PcieSlotControl)
 
4355
   );
 
4356
  Print (
 
4357
    L"  Presence Detect Changed Enable(3):                  %E%d%N\n",
 
4358
    PCIE_CAP_PRES_DETECT_CHANGE_ENABLE (PcieSlotControl)
 
4359
   );
 
4360
  Print (
 
4361
    L"  Command Completed Interrupt Enable(4):              %E%d%N\n",
 
4362
    PCIE_CAP_COMM_CMPL_INT_ENABLE (PcieSlotControl)
 
4363
   );
 
4364
  Print (
 
4365
    L"  Hot-Plug Interrupt Enable(5):                       %E%d%N\n",
 
4366
    PCIE_CAP_HOTPLUG_INT_ENABLE (PcieSlotControl)
 
4367
   );
 
4368
  Print (
 
4369
    L"  Attention Indicator Control(7:6):                   %E%s%N\n",
 
4370
    IndicatorTable[PCIE_CAP_ATT_IND_CTRL (PcieSlotControl)]
 
4371
   );
 
4372
  Print (
 
4373
    L"  Power Indicator Control(9:8):                       %E%s%N\n",
 
4374
    IndicatorTable[PCIE_CAP_PWR_IND_CTRL (PcieSlotControl)]
 
4375
   );
 
4376
  Print (L"  Power Controller Control(10):                       %EPower ");
 
4377
  if (PCIE_CAP_PWR_CTRLLER_CTRL (PcieSlotControl)) {
 
4378
    Print (L"Off%N\n");
 
4379
  } else {
 
4380
    Print (L"On%N\n");
 
4381
  }
 
4382
  Print (
 
4383
    L"  Electromechanical Interlock Control(11):            %E%d%N\n",
 
4384
    PCIE_CAP_ELEC_INTERLOCK_CTRL (PcieSlotControl)
 
4385
   );
 
4386
  Print (
 
4387
    L"  Data Link Layer State Changed Enable(12):           %E%d%N\n",
 
4388
    PCIE_CAP_DLINK_STAT_CHANGE_ENABLE (PcieSlotControl)
 
4389
   );
 
4390
  return EFI_SUCCESS;
 
4391
}
 
4392
 
 
4393
/**
 
4394
  Print out information of the device slot status information.
 
4395
 
 
4396
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
4397
 
 
4398
  @retval EFI_SUCCESS   The operation was successful.
 
4399
**/
 
4400
EFI_STATUS
 
4401
ExplainPcieSlotStatus (
 
4402
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
4403
  )
 
4404
{
 
4405
  UINT16 PcieSlotStatus;
 
4406
 
 
4407
  PcieSlotStatus = PciExpressCap->SlotStatus;
 
4408
 
 
4409
  Print (
 
4410
    L"  Attention Button Pressed(0):           %E%d%N\n",
 
4411
    PCIE_CAP_ATT_BUT_PRESSED (PcieSlotStatus)
 
4412
   );
 
4413
  Print (
 
4414
    L"  Power Fault Detected(1):               %E%d%N\n",
 
4415
    PCIE_CAP_PWR_FLT_DETECTED (PcieSlotStatus)
 
4416
   );
 
4417
  Print (
 
4418
    L"  MRL Sensor Changed(2):                 %E%d%N\n",
 
4419
    PCIE_CAP_MRL_SENSOR_CHANGED (PcieSlotStatus)
 
4420
   );
 
4421
  Print (
 
4422
    L"  Presence Detect Changed(3):            %E%d%N\n",
 
4423
    PCIE_CAP_PRES_DETECT_CHANGED (PcieSlotStatus)
 
4424
   );
 
4425
  Print (
 
4426
    L"  Command Completed(4):                  %E%d%N\n",
 
4427
    PCIE_CAP_COMM_COMPLETED (PcieSlotStatus)
 
4428
   );
 
4429
  Print (L"  MRL Sensor State(5):                   %EMRL ");
 
4430
  if (PCIE_CAP_MRL_SENSOR_STATE (PcieSlotStatus)) {
 
4431
    Print (L" Opened%N\n");
 
4432
  } else {
 
4433
    Print (L" Closed%N\n");
 
4434
  }
 
4435
  Print (L"  Presence Detect State(6):              ");
 
4436
  if (PCIE_CAP_PRES_DETECT_STATE (PcieSlotStatus)) {
 
4437
    Print (L"%ECard Present in slot%N\n");
 
4438
  } else {
 
4439
    Print (L"%ESlot Empty%N\n");
 
4440
  }
 
4441
  Print (L"  Electromechanical Interlock Status(7): %EElectromechanical Interlock ");
 
4442
  if (PCIE_CAP_ELEC_INTERLOCK_STATE (PcieSlotStatus)) {
 
4443
    Print (L"Engaged%N\n");
 
4444
  } else {
 
4445
    Print (L"Disengaged%N\n");
 
4446
  }
 
4447
  Print (
 
4448
    L"  Data Link Layer State Changed(8):      %E%d%N\n",
 
4449
    PCIE_CAP_DLINK_STAT_CHANGED (PcieSlotStatus)
 
4450
   );
 
4451
  return EFI_SUCCESS;
 
4452
}
 
4453
 
 
4454
/**
 
4455
  Print out information of the device root information.
 
4456
 
 
4457
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
4458
 
 
4459
  @retval EFI_SUCCESS   The operation was successful.
 
4460
**/
 
4461
EFI_STATUS
 
4462
ExplainPcieRootControl (
 
4463
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
4464
  )
 
4465
{
 
4466
  UINT16 PcieRootControl;
 
4467
 
 
4468
  PcieRootControl = PciExpressCap->RootControl;
 
4469
 
 
4470
  Print (
 
4471
    L"  System Error on Correctable Error Enable(0):  %E%d%N\n",
 
4472
    PCIE_CAP_SYSERR_ON_CORERR_EN (PcieRootControl)
 
4473
   );
 
4474
  Print (
 
4475
    L"  System Error on Non-Fatal Error Enable(1):    %E%d%N\n",
 
4476
    PCIE_CAP_SYSERR_ON_NONFATERR_EN (PcieRootControl)
 
4477
   );
 
4478
  Print (
 
4479
    L"  System Error on Fatal Error Enable(2):        %E%d%N\n",
 
4480
    PCIE_CAP_SYSERR_ON_FATERR_EN (PcieRootControl)
 
4481
   );
 
4482
  Print (
 
4483
    L"  PME Interrupt Enable(3):                      %E%d%N\n",
 
4484
    PCIE_CAP_PME_INT_ENABLE (PcieRootControl)
 
4485
   );
 
4486
  Print (
 
4487
    L"  CRS Software Visibility Enable(4):            %E%d%N\n",
 
4488
    PCIE_CAP_CRS_SW_VIS_ENABLE (PcieRootControl)
 
4489
   );
 
4490
 
 
4491
  return EFI_SUCCESS;
 
4492
}
 
4493
 
 
4494
/**
 
4495
  Print out information of the device root capability information.
 
4496
 
 
4497
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
4498
 
 
4499
  @retval EFI_SUCCESS   The operation was successful.
 
4500
**/
 
4501
EFI_STATUS
 
4502
ExplainPcieRootCap (
 
4503
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
4504
  )
 
4505
{
 
4506
  UINT16 PcieRootCap;
 
4507
 
 
4508
  PcieRootCap = PciExpressCap->RsvdP;
 
4509
 
 
4510
  Print (
 
4511
    L"  CRS Software Visibility(0):                   %E%d%N\n",
 
4512
    PCIE_CAP_CRS_SW_VIS (PcieRootCap)
 
4513
   );
 
4514
 
 
4515
  return EFI_SUCCESS;
 
4516
}
 
4517
 
 
4518
/**
 
4519
  Print out information of the device root status information.
 
4520
 
 
4521
  @param[in] PciExpressCap  The pointer to the structure about the device.
 
4522
 
 
4523
  @retval EFI_SUCCESS   The operation was successful.
 
4524
**/
 
4525
EFI_STATUS
 
4526
ExplainPcieRootStatus (
 
4527
  IN PCIE_CAP_STURCTURE *PciExpressCap
 
4528
  )
 
4529
{
 
4530
  UINT32 PcieRootStatus;
 
4531
 
 
4532
  PcieRootStatus = PciExpressCap->RootStatus;
 
4533
 
 
4534
  Print (
 
4535
    L"  PME Requester ID(15:0):                       %E0x%04x%N\n",
 
4536
    PCIE_CAP_PME_REQ_ID (PcieRootStatus)
 
4537
   );
 
4538
  Print (
 
4539
    L"  PME Status(16):                               %E%d%N\n",
 
4540
    PCIE_CAP_PME_STATUS (PcieRootStatus)
 
4541
   );
 
4542
  Print (
 
4543
    L"  PME Pending(17):                              %E%d%N\n",
 
4544
    PCIE_CAP_PME_PENDING (PcieRootStatus)
 
4545
   );
 
4546
  return EFI_SUCCESS;
 
4547
}
 
4548
 
 
4549
/**
 
4550
  Display Pcie device structure.
 
4551
 
 
4552
  @param[in] IoDev          The pointer to the root pci protocol.
 
4553
  @param[in] Address        The Address to start at.
 
4554
  @param[in] CapabilityPtr  The offset from the address to start.
 
4555
**/
 
4556
EFI_STATUS
 
4557
PciExplainPciExpress (
 
4558
  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL         *IoDev,
 
4559
  IN  UINT64                                  Address,
 
4560
  IN  UINT8                                   CapabilityPtr
 
4561
  )
 
4562
{
 
4563
 
 
4564
  PCIE_CAP_STURCTURE  PciExpressCap;
 
4565
  EFI_STATUS          Status;
 
4566
  UINT64              CapRegAddress;
 
4567
  UINT8               Bus;
 
4568
  UINT8               Dev;
 
4569
  UINT8               Func;
 
4570
  UINT8               *ExRegBuffer;
 
4571
  UINTN               ExtendRegSize;
 
4572
  UINT64              Pciex_Address;
 
4573
  UINT8               DevicePortType;
 
4574
  UINTN               Index;
 
4575
  UINT8               *RegAddr;
 
4576
  UINTN               RegValue;
 
4577
 
 
4578
  CapRegAddress = Address + CapabilityPtr;
 
4579
  IoDev->Pci.Read (
 
4580
              IoDev,
 
4581
              EfiPciWidthUint32,
 
4582
              CapRegAddress,
 
4583
              sizeof (PciExpressCap) / sizeof (UINT32),
 
4584
              &PciExpressCap
 
4585
             );
 
4586
 
 
4587
  DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PciExpressCap.PcieCapReg);
 
4588
 
 
4589
  Print (L"\nPci Express device capability structure:\n");
 
4590
 
 
4591
  for (Index = 0; PcieExplainList[Index].Type < PcieExplainTypeMax; Index++) {
 
4592
    if (ShellGetExecutionBreakFlag()) {
 
4593
      goto Done;
 
4594
    }
 
4595
    RegAddr = ((UINT8 *) &PciExpressCap) + PcieExplainList[Index].Offset;
 
4596
    switch (PcieExplainList[Index].Width) {
 
4597
      case FieldWidthUINT8:
 
4598
        RegValue = *(UINT8 *) RegAddr;
 
4599
        break;
 
4600
      case FieldWidthUINT16:
 
4601
        RegValue = *(UINT16 *) RegAddr;
 
4602
        break;
 
4603
      case FieldWidthUINT32:
 
4604
        RegValue = *(UINT32 *) RegAddr;
 
4605
        break;
 
4606
      default:
 
4607
        RegValue = 0;
 
4608
        break;
 
4609
    }
 
4610
    ShellPrintHiiEx(-1, -1, NULL,
 
4611
      PcieExplainList[Index].Token,
 
4612
      gShellDebug1HiiHandle,
 
4613
      PcieExplainList[Index].Offset,
 
4614
      RegValue
 
4615
     );
 
4616
    if (PcieExplainList[Index].Func == NULL) {
 
4617
      continue;
 
4618
    }
 
4619
    switch (PcieExplainList[Index].Type) {
 
4620
      case PcieExplainTypeLink:
 
4621
        //
 
4622
        // Link registers should not be used by
 
4623
        // a) Root Complex Integrated Endpoint
 
4624
        // b) Root Complex Event Collector
 
4625
        //
 
4626
        if (DevicePortType == PCIE_ROOT_COMPLEX_INTEGRATED_PORT ||
 
4627
            DevicePortType == PCIE_ROOT_COMPLEX_EVENT_COLLECTOR) {
 
4628
          continue;
 
4629
        }
 
4630
        break;
 
4631
      case PcieExplainTypeSlot:
 
4632
        //
 
4633
        // Slot registers are only valid for
 
4634
        // a) Root Port of PCI Express Root Complex
 
4635
        // b) Downstream Port of PCI Express Switch
 
4636
        // and when SlotImplemented bit is set in PCIE cap register.
 
4637
        //
 
4638
        if ((DevicePortType != PCIE_ROOT_COMPLEX_ROOT_PORT &&
 
4639
             DevicePortType != PCIE_SWITCH_DOWNSTREAM_PORT) ||
 
4640
            !PCIE_CAP_SLOT_IMPLEMENTED (PciExpressCap.PcieCapReg)) {
 
4641
          continue;
 
4642
        }
 
4643
        break;
 
4644
      case PcieExplainTypeRoot:
 
4645
        //
 
4646
        // Root registers are only valid for
 
4647
        // Root Port of PCI Express Root Complex
 
4648
        //
 
4649
        if (DevicePortType != PCIE_ROOT_COMPLEX_ROOT_PORT) {
 
4650
          continue;
 
4651
        }
 
4652
        break;
 
4653
      default:
 
4654
        break;
 
4655
    }
 
4656
    PcieExplainList[Index].Func (&PciExpressCap);
 
4657
  }
 
4658
 
 
4659
  Bus           = (UINT8) (RShiftU64 (Address, 24));
 
4660
  Dev           = (UINT8) (RShiftU64 (Address, 16));
 
4661
  Func          = (UINT8) (RShiftU64 (Address, 8));
 
4662
 
 
4663
  Pciex_Address = CALC_EFI_PCIEX_ADDRESS (Bus, Dev, Func, 0x100);
 
4664
 
 
4665
  ExtendRegSize = 0x1000 - 0x100;
 
4666
 
 
4667
  ExRegBuffer   = (UINT8 *) AllocateZeroPool (ExtendRegSize);
 
4668
 
 
4669
  //
 
4670
  // PciRootBridgeIo protocol should support pci express extend space IO
 
4671
  // (Begins at offset 0x100)
 
4672
  //
 
4673
  Status = IoDev->Pci.Read (
 
4674
                        IoDev,
 
4675
                        EfiPciWidthUint32,
 
4676
                        Pciex_Address,
 
4677
                        (ExtendRegSize) / sizeof (UINT32),
 
4678
                        (VOID *) (ExRegBuffer)
 
4679
                       );
 
4680
  if (EFI_ERROR (Status)) {
 
4681
    FreePool ((VOID *) ExRegBuffer);
 
4682
    return EFI_UNSUPPORTED;
 
4683
  }
 
4684
  //
 
4685
  // Start outputing PciEx extend space( 0xFF-0xFFF)
 
4686
  //
 
4687
  Print (L"\n%HStart dumping PCIex extended configuration space (0x100 - 0xFFF).%N\n\n");
 
4688
 
 
4689
  if (ExRegBuffer != NULL) {
 
4690
    DumpHex (
 
4691
      2,
 
4692
      0x100,
 
4693
      ExtendRegSize,
 
4694
      (VOID *) (ExRegBuffer)
 
4695
     );
 
4696
 
 
4697
    FreePool ((VOID *) ExRegBuffer);
 
4698
  }
 
4699
 
 
4700
Done:
 
4701
  return EFI_SUCCESS;
 
4702
}