source: umon/main/common/pci.c @ 87db514

Last change on this file since 87db514 was 87db514, checked in by Amar Takhar <amar@…>, on 04/16/15 at 19:26:21

Initial commit of the umon repository.

Prior to this three changes were made:

  • Remove umon_ prefix from parent directories.
  • Collapse main/target/ into main/
  • Remove ports/template/flashtest.scr.ucon script.
  • Property mode set to 100644
File size: 19.4 KB
Line 
1/**************************************************************************
2 *
3 * Copyright (c) 2013 Alcatel-Lucent
4 *
5 * Alcatel Lucent licenses this file to You under the Apache License,
6 * Version 2.0 (the "License"); you may not use this file except in
7 * compliance with the License.  A copy of the License is contained the
8 * file LICENSE at the top level of this repository.
9 * You may also obtain a copy of the License at:
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 **************************************************************************
20 *
21 * pci.c:
22 *
23 * This file provides the monitor with a reusable mechanism for
24 * interfacing with a PCI bus.  Four target-specific functions are
25 * required:
26 *
27 *      pciCtrl(), pciCfgRead(), pciCfgWrite(), pciShow()
28 *
29 * The two most important are pciCfgRead() and pciCfgWrite().  Refer to
30 * the bottom of pci.h for further details.
31 *
32 * Original author:     Ed Sutter (ed.sutter@alcatel-lucent.com)
33 *
34 */
35#include "config.h"
36#include "pci.h"
37#include "stddefs.h"
38#include "genlib.h"
39#include "cli.h"
40
41#if INCLUDE_PCI
42int pciVerbose;
43int pciBusNum;
44
45#define IMPLEMENTED     0x80000000
46
47#ifdef USE_DEFAULT_PCISHOW
48void
49pciShow(int interface)
50{
51        printf("No fixed devices on this platform\n");
52}
53#endif
54
55/* pciCfgAddress():
56 * Return a 32-bit value based on the input
57 * bus number, device number, function number and register
58 * number:
59 *
60 *  31 30 .... 24 23 ... 16 15 ... 11 10 ....  8 7 ...    2 1 0
61 * --------------------------------------------------------------
62 * |  |          |  Bus    | Device  | Function | Register |0|T|
63 * |En| Reserved |  Number | Number  | Number   | Number   | | |
64 * --------------------------------------------------------------
65 *  ^                                                         ^
66 *  |---- Enable bit 1=enabled, 0=disabled                    |
67 *                                                            |
68 *       Type0: 0 --------------------------------------------|
69 *       Type1: 1 --------------------------------------------|
70 *
71 * See pg 32 of the PCI2.2 spec for more details.
72 */
73
74unsigned long
75pciCfgAddress(int busno,int devno,int fncno,int regno)
76{
77        int     type;
78
79        if (busno > 0)
80                type = 1;
81        else
82                type = 0;
83
84        return((type | PCICFG_ENABLE_BIT |
85                        ((busno & PCICFG_BUSNO_MASK) << PCICFG_BUSNO_SHIFT) |
86                        ((devno & PCICFG_DEVNO_MASK) << PCICFG_DEVNO_SHIFT) |
87                        ((fncno & PCICFG_FNCNO_MASK) << PCICFG_FNCNO_SHIFT) |
88                        ((regno & PCICFG_REGNO_MASK) << PCICFG_REGNO_SHIFT)));
89}
90
91/* pciBaseClass():
92 * Based on appendix D of spec, return a simple string that describes
93 * the base class of the incoming class code.
94 */
95char *
96pciBaseClass(unsigned long classcode)
97{
98        unsigned long baseclass;
99        unsigned long subclass_progif;
100
101        baseclass = (classcode >> 16) & 0xff;
102        subclass_progif = classcode & 0xffff;
103
104        switch(baseclass) {
105                case 0:
106                        return("pre-class-code-definitions");
107                case 1:
108                        return("mass storage ctrlr");
109                case 2:
110                        return("network ctrlr");
111                case 3:
112                        return("display ctrlr");
113                case 4:
114                        return("multimedia device");
115                case 5:
116                        return("memory ctrlr");
117                case 6: /* Supply additional information for bridge class...
118                                 */
119                        switch(subclass_progif) {
120                                case 0x0000:
121                                        return("host/pci bridge");
122                                case 0x0100:
123                                        return("pci/isa bridge");
124                                case 0x0200:
125                                        return("pci/eisa bridge");
126                                case 0x0300:
127                                        return("pci/microchannel bridge");
128                                case 0x0400:
129                                        return("pci/pci bridge");
130                                case 0x0500:
131                                        return("pci/pcmcia bridge");
132                                case 0x0600:
133                                        return("pci/nubus bridge");
134                                case 0x0700:
135                                        return("pci/cardbus bridge");
136                                case 0x8000:
137                                        return("other bridge type");
138                                default:
139                                        return("bridge device");
140                        }
141                case 7:
142                        return("simple communication ctrlr");
143                case 8:
144                        return("base system peripheral");
145                case 9:
146                        return("input device");
147                case 10:
148                        return("docking station");
149                case 11:
150                        return("processor");
151                case 12:
152                        return("serial bus ctrlr");
153                case 13:
154                        return("wireless ctrlr");
155                case 14:
156                        return("intelligent io ctrlr");
157                case 15:
158                        return("satellite communication ctrlr");
159                case 16:
160                        return("encrypt/decrypt ctrlr");
161                case 17:
162                        return("data acquisition ctrlr");
163                case 256:
164                        return("no fit");
165                default:
166                        return("reserved");
167        }
168}
169
170/* pciscan():
171 * This function is used by "pci scan" and "pci enum" to look
172 * at the devices on the pci bus.  When the enumerate flag is set,
173 * this function will recursively nest itself each time it sees a
174 * PCI-to-PCI bridge device on the bus, and while doing this, it will
175 * assign bus numbers to each bridge appropriately.  This function does
176 * not assign address ranges or anything else, it simply provides a quick
177 * means of scanning all devices on the bus(es).
178 *
179 * NOTE: This has only been tested with simple PCI bus configurations (one
180 * bridge deep) so deeper configurations (bridges on bridges on bridges...)
181 * are untested as far as I know.
182 */
183void
184pciscan(long interface, long bus, long func, int showhdr, int enumerate)
185{
186        long    device;
187        uchar   hdr_type, rev_id;
188        ushort  vendor_id, device_id;
189        ulong   value, class_code;
190
191        if (showhdr) {
192                printf("\nInterface %ld...\n",interface);
193                printf("Bus Dev Vndr  Dev   Rev Hdr  Class\n"); 
194                printf("Num Num Id    Id    Id  Type Code\n"); 
195        }
196
197        if ((enumerate == 1) && (bus == 0))
198                pciBusNum = 0;
199
200        for(device=0;device<=31;device++) {
201                /* Retrieve portions of the configuration header that
202                 * are required by all PCI compliant devices...
203                 * Vendor, Device and Revision IDs, Class Code and Header Type
204                 * (see pg 191 of spec).
205                 */
206
207                /* Read reg_0 for vendor and device ids:
208                 */
209                value = pciCfgRead(interface,bus,device,func,0);
210                if (value == NO_DEVICE)
211                        continue;
212
213                vendor_id = (ushort)(value & 0xffff);
214                device_id = (ushort)((value>>16) & 0xffff);
215
216                /* Read reg_2 for class code and revision id:
217                 */
218                value = pciCfgRead(interface,bus,device,func,2);
219                rev_id = (uchar)(value & 0xff);
220                class_code = (ulong)((value>>8) & 0xffffff);
221
222                /* Read reg_3:  header type:
223                 */
224                value = pciCfgRead(interface,bus,device,func,3);
225                hdr_type = (uchar)((value>>16) & 0xff);
226                       
227                printf("%2ld  %02ld  x%04x x%04x",bus,
228                        device,vendor_id,device_id);
229                printf(" x%02x x%02x  x%06lx (%s)\n",rev_id,
230                        hdr_type,class_code,pciBaseClass(class_code));
231
232                /* If enumeration is enabled, see if this is a PCI-to-PCI
233                 * bridge.  If it is, then nest into pciscan...
234                 */
235                if ((enumerate) && (class_code == 0x060400)) {
236                        ulong pribus, secbus, subbus;
237
238                        pribus = pciBusNum & 0x0000ff;
239                        pciBusNum++;
240                        secbus = ((pciBusNum << 8) & 0x00ff00);
241                        subbus = ((pciBusNum << 16) & 0xff0000);
242
243                        value = pciCfgRead(interface,bus,device,func,6);
244                        value &= 0xffff0000;
245                        value |= (pribus | secbus);
246                        pciCfgWrite(interface,bus,device,func,6,value);
247
248                        pciscan(interface,pciBusNum,func,0,1);
249
250                        value = pciCfgRead(interface,bus,device,func,6);
251                        value &= 0xff000000;
252                        value |= (subbus | pribus | secbus);
253                        pciCfgWrite(interface,bus,device,func,6,value);
254                }
255        }
256}
257
258/* getBarInfo():
259 * Apply the algorithm as specified in PCI spec...
260 * Place size information in sizehi & sizelo (to support 64-bit).
261 * Return 0 if not implemented; else return value to indicate
262 * size (32 or 64 bit) and type (mem or io).
263 */
264ulong
265getBarInfo(long interface,long bus,long device,long func,int barnum,
266        ulong *sizehi, ulong *sizelo)
267{
268        int barregno;
269        ulong implemented, barval1, barval2, barinfo1, barinfo2, cmd;
270
271        /* Translate the incoming bar number to a register number
272         * in PCI config space:
273         */
274        barregno = barnum + 4;
275
276        /* Disable decoding through the command register:
277         */
278        cmd = pciCfgRead(interface,bus,device,func,1);
279        pciCfgWrite(interface,bus,device,func,1,
280                cmd & ~(IO_SPACE | MEMORY_SPACE));
281
282        /* Read the BAR:
283         */
284        barval1 = pciCfgRead(interface,bus,device,func,barregno);
285
286        /* Write 0xffffffff to the BAR:
287         */
288        pciCfgWrite(interface,bus,device,func,barregno,0xffffffff);
289
290        /* Read the value returned as a result of writing
291         * 0xffffffff to the BAR:
292         */
293        barinfo1 = pciCfgRead(interface,bus,device,func,barregno);
294
295        /* Restore original bar:
296         */
297        pciCfgWrite(interface,bus,device,func,barregno,barval1);
298
299        if (barinfo1 == 0) {
300                implemented = 0;
301        }
302        else {
303                implemented = IMPLEMENTED;
304
305                if (barval1 & BASEADDRESS_IO) {
306                        implemented |= BASEADDRESS_IO;
307
308                        if (sizelo) {
309                                /* Clear encoding bits:
310                                 */
311                                barinfo1 &= 0xfffffffe;
312                                /* Invert and add 1:
313                                 */
314                                *sizelo = (~barinfo1 + 1) & 0xffff;
315       
316                                if (sizehi)
317                                        *sizehi = 0;
318                        }
319                }
320                else {
321                        implemented |= (barinfo1 & PREFETCHABLE);
322
323                        if (barval1 & TYPE_64) {
324                                implemented |= TYPE_64;
325
326                                /* Apply same sequence as above to the next bar...
327                                 */
328                                barregno++;
329                                barval2 = pciCfgRead(interface,bus,device,func,barregno);
330                                pciCfgWrite(interface,bus,device,func,barregno,0xffffffff);
331                                barinfo2 = pciCfgRead(interface,bus,device,func,barregno);
332                                pciCfgWrite(interface,bus,device,func,barregno,barval2);
333       
334       
335                                if (sizelo) {
336                                        barinfo1 &= 0xfffffff0;
337                                        *sizelo = ~barinfo1 + 1;
338                                        if (sizehi)
339                                                *sizehi = ~barinfo2 + 1;
340                                }
341                        }
342                        else {
343                                if (sizelo) {
344                                        barinfo1 &= 0xfffffff0;
345                                        *sizelo = ~barinfo1 + 1;
346       
347                                        if (sizehi)
348                                                *sizehi = 0;
349                                }
350                        }
351                }
352        }
353
354        /* Now that we've completed messing with the BARS,
355         * restore original cmd:
356         */
357        pciCfgWrite(interface,bus,device,func,1,cmd);
358
359        return(implemented);
360}
361
362int
363showBar(int barnum,long interface,long bus,long device,long func)
364{
365        int     rtot;
366        ulong bar, barnext, sizehi, sizelo, implemented;
367
368        if ((barnum < 0) || (barnum > 5))
369                return(-1);
370
371        bar = pciCfgRead(interface,bus,device,func,barnum+4);
372
373        implemented = getBarInfo(interface,bus,device,func,
374                        barnum,&sizehi,&sizelo);
375
376        if (!implemented) {
377                printf("%02d BAR%d  : not implemented\n",barnum+4,barnum);
378                return(0);
379        }
380
381        printf("%02d BAR%d",barnum+4,barnum);
382        if (!(implemented & BASEADDRESS_IO) && (implemented & TYPE_64)) {
383                barnext = pciCfgRead(interface,bus,device,func,barnum+5);
384                printf("-%d: 0x%08lx 0x%08lx", barnum+1,bar,barnext);
385        }
386        else {
387                printf("  : 0x%08lx",bar);
388        }
389
390        printf(" Size: 0x");
391        if (!(implemented & BASEADDRESS_IO) && (implemented & TYPE_64)) {
392                printf("%08lx%08lx ",sizehi,sizelo);
393                rtot = 2;
394        }
395        else {
396                printf("%08lx ",sizelo);
397                rtot = 1;
398        }
399
400        if (bar & BASEADDRESS_IO)  {
401                printf("IO");
402        }
403        else {
404                printf("MEM %sbit",bar & TYPE_64 ? "64" : "32");
405        }
406
407        if (bar & PREFETCHABLE)
408                printf(" prefetchable");
409
410        putchar('\n');
411        return(rtot);
412}
413
414void
415dumpRawCfg(long interface,long bus,long device,long func,char *range,
416        char* varname)
417{
418        int gotone;
419        long regno;
420        ulong value;
421
422        value = 0;
423        gotone = 0;
424        for(regno=0;regno<64;regno++) {
425                if (inRange(range,regno)) {
426                        value = pciCfgRead(interface,bus,device,func,regno);
427                        printf("Cfg reg #%02ld: 0x%08lx\n",regno,value);
428                        gotone = 1;
429                }
430        }
431        if ((varname) && (gotone))
432                shell_sprintf(varname,"0x%08lx",value);
433}
434
435void
436dumpConfig(long interface,long bus,long device,long func)
437{
438        int     i;
439        char *multifunc, *type;
440        ulong hdrtype, values[16];
441
442        for(i=0;i<16;i++)
443                values[i] = pciCfgRead(interface,bus,device,func,i);
444
445        hdrtype = values[3] & HDR_MASK;
446
447        if (hdrtype & HDR_MULTIFUNC) {
448                multifunc = "multi-function ";
449                hdrtype &= ~HDR_MULTIFUNC;
450        }
451        else {
452                multifunc = "";
453        }
454
455        switch(hdrtype) {
456                case HDR_PCI2PCI:
457                        type = "PCI-to-PCI";
458                        break;
459                case HDR_CARDBUS:
460                        type = "CardBus";
461                        break;
462                case HDR_STANDARD:
463                        type = "Standard";
464                        break;
465                default:
466                        printf("dumpConfig(): hdrtype 0x%08lx not supported\n",hdrtype);
467                        return;
468        }
469        printf("%s %sconfig...\n",type,multifunc);
470
471        printf("00 DevId/VendorId:   0x%04lx/%04lx\n",
472                (values[0] & 0xffff0000) >> 16,values[0] & 0xffff);
473
474        printf("01 Status/Command:   0x%04lx/%04lx\n",
475                (values[1] & 0xffff0000) >> 16,values[1] & 0xffff);
476
477        printf("02 ClassCode/RevId:  0x%06lx/%02lx\n",
478                (values[2] & 0xffffff00) >> 8,values[2] & 0xff);
479
480
481        printf("03 BIST/HdrType/LatencyTmr/CacheLnSz: 0x%02lx/%02lx/%02lx/%02lx\n",
482                (values[3] & 0xff000000) >> 24, (values[3] & 0xff0000) >> 16,
483                (values[3] & 0xff00) >> 8,values[3] & 0xff);
484
485        if (showBar(0,interface,bus,device,func) == 1)
486                showBar(1,interface,bus,device,func);
487
488        if (hdrtype == HDR_STANDARD) {
489                if (showBar(2,interface,bus,device,func) == 1)
490                        showBar(3,interface,bus,device,func);
491                if (showBar(4,interface,bus,device,func) == 1)
492                        showBar(5,interface,bus,device,func);
493
494                printf("10 Cardbus CIS Ptr:        0x%08lx\n",values[10]);
495                printf("11 SubSysId/SubVendorId:   0x%04lx/%04lx\n",
496                        (values[11] & 0xffff0000) >> 16,values[11] & 0xffff);
497                printf("12 Expansion ROM BaseAddr: 0x%08lx\n",values[12]);
498        }
499        else if (hdrtype == HDR_PCI2PCI) {
500                printf("06 Secondary Latency Tmr:  0x%02lx\n",
501                        (values[6] & 0xff000000) >> 24);
502                printf("06 BusNum Subordinate/Secondary/Primary: 0x%02lx/%02lx/%02lx\n",
503                        (values[6] & 0xff0000) >> 16,
504                        (values[6] & 0xff00) >> 8,values[6] & 0xff);
505
506                printf("07 Secondary Status: 0x%04lx\n",
507                        (values[7] & 0xffff0000) >> 16);
508                printf("07 IO Limit/Base:    0x%02lx/%02lx\n",
509                        (values[7] & 0xff00) >> 8,(values[7] & 0xff));
510
511                printf("08 Memory Limit/Base:                0x%04lx/%04lx\n",
512                        (values[8] & 0xffff0000) >> 16,values[8] & 0xffff);
513
514                printf("09 Prefetchable Memory Limit/Base:   0x%04lx/%04lx\n",
515                        (values[9] & 0xffff0000) >> 16,values[9] & 0xffff);
516
517                printf("10 Prefetchable Base Upper 32 bits:  0x%08lx\n",values[10]);
518                printf("11 Prefetchable Limit Upper 32 bits: 0x%08lx\n",values[11]);
519               
520                printf("12 IO Upper 16 Bits Limit/Base:      0x%04lx/%04lx\n",
521                        (values[12] & 0xffff0000) >> 16,values[12] & 0xffff);
522        }
523
524        printf("13 Capabilities Ptr:       0x%02lx\n",values[13] & 0xff);
525
526        if (hdrtype == HDR_STANDARD) {
527                printf("15 MaxLat/MinGnt:          0x%02lx/%02lx\n",
528                        (values[15] & 0xff000000) >> 24, (values[15] & 0xff0000) >> 16);
529        }
530        else {
531                printf("14 Expansion ROM BaseAddr: 0x%08lx\n",
532                        values[14]);
533                printf("15 BridgeControl:          0x%04lx\n",
534                        (values[15] & 0xffff0000) >> 16);
535        }
536
537        printf("15 Interrupt Pin/Line:     0x%02lx/%02lx\n",
538                (values[15] & 0xff00) >> 8, values[15] & 0xff);
539}
540
541char *PciHelp[] = {
542        "PCI Config Interface",
543        "-[b:d:f:i:v] {operation} [args]",
544#if INCLUDE_VERBOSEHELP
545        "Options:",
546        " -b{###}   bus #",
547        " -d{###}   device #",
548        " -f{###}   function #",
549        " -i{###}   interface #",
550        " -v        verbose",
551        "Operations:",
552        " scan, enum, bist, show, size {bar#}",
553        " crd [reg#] [varname], cwr {reg#} {value}",
554    "Note:",
555        " bus, device, function & interface default to zero",
556#endif
557        0
558};
559
560/* PciCmd():
561 * General purpose command to provide access to the config portion of
562 * a PCI interface. 
563 *
564 * Notice that there is reference to an "interface number" as well as a
565 * "bus number".  In most systems, there will be one host-to-pci interface.
566 * and one pci bus.   Some targets will have more than one host-to-pci
567 * interface (galileo 64260A, for example, has 2 distinct host-to-PCI
568 * interface).  Some targets will have more than one bus (depends on whether
569 * or not there is a pci-to-pci bridge hanging off the bus).
570 *
571 */
572int
573PciCmd(int argc, char *argv[])
574{
575        ulong   value, bar;
576        long    bus, device, interface, regno, func;
577        int             enumerate, opt;
578
579        bus = 0;
580        func = 0;
581        device = 0;
582        enumerate = 0;
583        interface = 0;
584        pciVerbose = 0;
585        while ((opt=getopt(argc,argv,"b:d:f:i:v")) != -1) {
586                switch(opt) {
587                case 'b':
588                        bus = strtol(optarg,0,0);
589                        break;
590                case 'd':
591                        device = strtol(optarg,0,0);
592                        break;
593                case 'f':
594                        func = strtol(optarg,0,0);
595                        break;
596                case 'i':       /* Most systems will only have 1 interface */
597                         interface = strtol(optarg,0,0);
598                        break;
599                case 'v':
600                         pciVerbose = 1;
601                        break;
602                default:
603                        return(CMD_FAILURE);
604                }
605        }
606
607        if (argc < optind+1)
608                return(CMD_PARAM_ERROR);
609
610        /* The "scan" and "enum" commands are very similar.  They both use
611         * the pciscan() function.
612         *
613         * Scan: look at the devices on the specified bus.
614         * Enum: a recursive scan... start with bus 0 and attempt to query
615         * all devices on all busses, making the necessary bus-number assignments
616         * along the way.
617         */
618
619        /* For scan, the device number is ignored, all devices on a particular
620         * interface/bus are checked.  If ths bus number is something other than
621         * zero, then this function assumes that the appropriate pci-to-pci
622         * bridge device has already had its bus numbers assigned.
623         */
624        if (!strcmp(argv[optind],"scan")) {
625                if (argc != optind+1)
626                        return(CMD_PARAM_ERROR);
627
628                pciscan(interface,bus,func,1,0);
629                return(CMD_SUCCESS);
630        }
631
632        /* For enum, we start with bus 0, and attempt to enumerate all busses...
633         */
634        if (!strcmp(argv[optind],"enum")) {
635                if (argc != optind+1)
636                        return(CMD_PARAM_ERROR);
637
638                pciscan(interface,0,func,1,1);
639                return(CMD_SUCCESS);
640        }
641
642        if (!strcmp(argv[optind],"size")) { /* See pg 204 of PCI2.2 spec */
643                int barnum;
644                ulong implemented, sizehi, sizelo;
645
646                if (argc != optind+2)
647                        return(CMD_PARAM_ERROR);
648
649                /* The argument to size is the BAR #.  The value can be a single
650                 * digit or a range specification...
651                 */
652                printf(" Bar  Type Value      Size\n");
653                for(barnum=0;barnum<6;barnum++) {
654                        setenv("PCISIZE",0);
655                        if (inRange(argv[optind+1],barnum)) {
656                                /* Disable decoding through the command register:
657                                 * See section 6.2.2, pg 193.
658                                 */
659                                value = pciCfgRead(interface,bus,device,func,1);
660                                pciCfgWrite(interface,bus,device,0,1,
661                                        value & ~(IO_SPACE | MEMORY_SPACE));
662
663                                bar = pciCfgRead(interface,bus,device,func,barnum+4);
664                                implemented = getBarInfo(interface,bus,device,func,
665                                        barnum,&sizehi,&sizelo);
666               
667                                printf(" %d    ",barnum);
668
669                                if (implemented) {
670                                        shell_sprintf("PCISIZE","0x%08lx",bar);
671                                        printf("%s  0x%08lx ",
672                                                implemented & BASEADDRESS_IO ? "io " : "mem", bar);
673                                        if (implemented & TYPE_64)
674                                                printf("0x%08lx%08lx",sizehi,sizelo);
675                                        else
676                                                printf("0x%08lx",sizelo);
677                                        if (implemented & PREFETCHABLE)
678                                                printf(" (prefetchable)");
679                                        putchar('\n');
680                                }
681                                else
682                                        printf("not implemented\n");
683                        }
684                }
685        }
686        else if (!strcmp(argv[optind],"bist")) {
687                if (argc != optind+1)
688                        return(CMD_PARAM_ERROR);
689
690                value = pciCfgRead(interface,bus,device,func,3);
691
692                if (value & BIST_CAPABLE) {
693                        /* Set the BIST_START bit to begin the test, then wait for
694                         * the BIST_START bit to clear as an indication that the
695                         * test has completed.
696                         */
697                        pciCfgWrite(interface,bus,device,func,3,value | BIST_START);
698                        while(1) {
699                                value = pciCfgRead(interface,bus,device,func,3);
700                                if ((value & BIST_START) != BIST_START)
701                                        break;
702                        }
703                        if ((value & BIST_COMPCODE_MASK) != 0)
704                                printf("BIST failed: 0x%lx\n",value & BIST_COMPCODE_MASK);
705                        else
706                                printf("BIST passed\n");
707                }
708                else {
709                        printf("Device %ld is not BIST-capable\n",device);
710                }
711        }
712        else if (!strcmp(argv[optind],"crd")) {
713                char *varname = (char *)0;
714
715                if (argc == optind+3) {         /* varname specified ? */
716                        varname = argv[optind+2];
717                        argc--;
718                }
719
720                if (argc == optind+2) {
721                        dumpRawCfg(interface,bus,device,func,argv[optind+1],varname);
722                }
723                else if (argc == optind+1) {
724                        dumpConfig(interface,bus,device,func);
725                }
726                else
727                        return(CMD_PARAM_ERROR);
728        }
729        else if (!strcmp(argv[optind],"cwr")) {
730                if (argc != optind+3)
731                        return(CMD_PARAM_ERROR);
732
733                regno = strtol(argv[optind+1],0,0);
734                value = strtol(argv[optind+2],0,0);
735                pciCfgWrite(interface,bus,device,func,regno,value);
736        }
737        else if (!strcmp(argv[optind],"init")) {
738                pciCtrl(interface,PCICTRL_INIT,0,0);
739        }
740        else if (!strcmp(argv[optind],"show")) {
741                pciShow(interface);
742        }
743        else
744                return(CMD_PARAM_ERROR);
745        return(CMD_SUCCESS);
746}
747#endif
Note: See TracBrowser for help on using the repository browser.