MCP750 PCI

gregory.menke at gsfc.nasa.gov gregory.menke at gsfc.nasa.gov
Wed Jan 22 17:03:18 UTC 2003


Till Straumann writes:
 > gregory.menke at gsfc.nasa.gov wrote:
 > > Till Straumann writes:
 > >  > Hi Gregory.
 > >  > 
 > >  > 
 > >  > Although I don't know if your 'strange results' (what exactly are you 
 > >  > observing??) 
 > > 
 > > 
 > > On Linux, I can dump the card's PCI and 1553 tranceiver registers and
 > > get a reasonable "idle state".  I know the card is working because
 > > theres a 16 bit timer register that I can see ticking by printing it
 > > several times.
 > > 
 > > When I print the same registers under RTEMS, I don't get the idle
 > > state values- nothing even close.  The PCI chipset registers come back
 > > as 0xffffffff, as if the addresses was out of range whereas under
 > > Linux, they come back as 0x0.  The tranceiver registers come back as
 > > all 0 except for the weird ones, some of which yield the same
 > > "uninitialized" value that they give under Linux.  The timer tick
 > > register is not incrementing either.
 > > 
 > > My test code only does ld_le16 for the tranceiver and ld_le32 for the
 > > pci chipset. 
 > 
 > Could you attach your test code, please? And the values you read from
 > PCI config space (for command/status and base registers)?

Here's the relevant output of my test routine:
========================================================================

Scanning pci busses for hardware...
bus 0x0, slot 0x00, vendor 0x1057, device 0x4801, bar0 00000001, bar1 01000000, bar3 00000000
bus 0x0, slot 0x0b, vendor 0x1106, device 0x0586, bar0 00000000, bar1 00000000, bar3 00000000
bus 0x0, slot 0x0e, vendor 0x1011, device 0x0009, bar0 00010001, bar1 01060000, bar3 00000000
bus 0x0, slot 0x10, vendor 0x13C5, device 0x0306, bar0 01060100, bar1 01060080, bar3 01040000

pci1553: Found device 0
Device: Alphi Technology, PMC1553(0x0306), rev 0x00,
   bus 0x00, slot 0x10, irq 0x05
   PCI Command register: [ MEMenable Bmaster ]
   PCI Status register:  [ ]
   bar 0, start/end C1060100/C1060140, width 32, flags 00000000
   bar 1, start/end C1060080/C1060100, width 16, flags 00000000
   bar 3, start/end C1040000/C1060000, width 16, flags 00000000

bus 0x0, slot 0x14, vendor 0x1011, device 0x0026, bar0 00000000, bar1 00000000, bar3 2280E1F1
bus 0x1, slot 0x0f, vendor 0x13C5, device 0x0108, bar0 3BEFFFC0, bar1 3BEFFF00, bar3 3BEC0000

pci1553: Found device 1
Device: Alphi Technology, CPCI1553-1(0x0108), rev 0x00,
   bus 0x01, slot 0x0f, irq 0xFF
   PCI Command register: [ MEMenable Bmaster ]
   PCI Status register:  [ ]
   bar 0, start/end FBEFFFC0/FBF00000, width 32, flags 00000000
   bar 1, start/end FBEFFF00/FBEFFF80, width 16, flags 00000000
   bar 3, start/end FBEC0000/FBEE0000, width 16, flags 00000000


Finished scanning pci busses.


Printing information for device PMC1553-00:10
Dumping r0 registers;
   offset 00 not fetched (OMB1 Outgoing Mailbox reg 1)
   offset 04 not fetched (OMB2 Outgoing Mailbox reg 2)
   offset 08 not fetched (OMB3 Outgoing Mailbox reg 3)
   offset 0c not fetched (OMB4 Outgoing Mailbox reg 4)
   offset 10 not fetched (IMB1 Incoming Mailbox reg 1)
   offset 14 not fetched (IMB2 Incoming Mailbox reg 2)
   offset 18 not fetched (IMB3 Incoming Mailbox reg 3)
   FFFFFFFF - (0x1C - IMB4 Incoming Mailbox reg 4)
   offset 20 not fetched (Bidirectional FIFO register)
   offset 24 not fetched (MWAR Master Write Address Register)
   offset 28 not fetched (MWTC Master Write Transfer Counter)
   offset 2c not fetched (MRAR Master Read Address Register)
   offset 30 not fetched (MRTC Master Read Transfer Counter)
   FFFFFFFF - (0x34 - MBEF Mailbox Empty/Full Status)
   FFFFFFFF - (0x38 - INTCSR Interrupt Control/Status Register)
   offset 3c not fetched (MCSR Bus Master Control/Status Register)

Dumping r1 registers;
   0000 - (0x00 - Control Register)
   0000 - (0x02 - Operational Status Register)
   0000 - (0x04 - Current Command Register)
   0000 - (0x08 - Interrupt Mask Register)
   0000 - (0x0A - Pending Interrupt Register)
   0000 - (0x0C - BIT Word Register)
   0000 - (0x0E - Time Tag Register)
   0000 - (0x10 - RT Descriptor Pointer Register)
   0000 - (0x12 - Status Word Bits Register)
   FFF7 - (0x20 - Illegalization Register)
   FFF7 - (0x22 - Illegalization Register)
   FFF7 - (0x24 - Illegalization Register)
   FFF7 - (0x26 - Illegalization Register)
   FFF7 - (0x28 - Illegalization Register)
   FFF7 - (0x2A - Illegalization Register)
   FFF7 - (0x2C - Illegalization Register)
   FFF7 - (0x2E - Illegalization Register)
   FFF7 - (0x30 - Illegalization Register)
   FFF7 - (0x32 - Illegalization Register)
   FFF7 - (0x34 - Illegalization Register)
   FFF7 - (0x36 - Illegalization Register)
   FFF7 - (0x38 - Illegalization Register)
   FFF7 - (0x3A - Illegalization Register)
   FFF7 - (0x3C - Illegalization Register)
   FFF7 - (0x3E - Illegalization Register)
   0000 - (0x42 - PMC Status)


Printing information for device CPCI1553-1-01:0F
Dumping r0 registers;
   offset 00 not fetched (OMB1 Outgoing Mailbox reg 1)
   offset 04 not fetched (OMB2 Outgoing Mailbox reg 2)
   offset 08 not fetched (OMB3 Outgoing Mailbox reg 3)
   offset 0c not fetched (OMB4 Outgoing Mailbox reg 4)
   offset 10 not fetched (IMB1 Incoming Mailbox reg 1)
   offset 14 not fetched (IMB2 Incoming Mailbox reg 2)
   offset 18 not fetched (IMB3 Incoming Mailbox reg 3)
   FFFFFFFF - (0x1C - IMB4 Incoming Mailbox reg 4)
   offset 20 not fetched (Bidirectional FIFO register)
   offset 24 not fetched (MWAR Master Write Address Register)
   offset 28 not fetched (MWTC Master Write Transfer Counter)
   offset 2c not fetched (MRAR Master Read Address Register)
   offset 30 not fetched (MRTC Master Read Transfer Counter)
   FFFFFFFF - (0x34 - MBEF Mailbox Empty/Full Status)
   FFFFFFFF - (0x38 - INTCSR Interrupt Control/Status Register)
   offset 3c not fetched (MCSR Bus Master Control/Status Register)

Dumping r1 registers;
   0000 - (0x00 - Control Register)
   0000 - (0x02 - Operational Status Register)
   0000 - (0x04 - Current Command Register)
   0000 - (0x08 - Interrupt Mask Register)
   0000 - (0x0A - Pending Interrupt Register)
   0000 - (0x0C - BIT Word Register)
   0000 - (0x0E - Time Tag Register)
   0000 - (0x10 - RT Descriptor Pointer Register)
   0000 - (0x12 - Status Word Bits Register)
   FF07 - (0x20 - Illegalization Register)
   FF07 - (0x22 - Illegalization Register)
   FF07 - (0x24 - Illegalization Register)
   FF07 - (0x26 - Illegalization Register)
   FF07 - (0x28 - Illegalization Register)
   FF07 - (0x2A - Illegalization Register)
   FF07 - (0x2C - Illegalization Register)
   FF07 - (0x2E - Illegalization Register)
   FF07 - (0x30 - Illegalization Register)
   FF07 - (0x32 - Illegalization Register)
   FF07 - (0x34 - Illegalization Register)
   FF07 - (0x36 - Illegalization Register)
   FF07 - (0x38 - Illegalization Register)
   FF07 - (0x3A - Illegalization Register)
   FF07 - (0x3C - Illegalization Register)
   FF07 - (0x3E - Illegalization Register)
   FFFF - (0x42 - PMC Status)

========================================================================

So it finds the devices OK, but doesn't yield plausible values for the
registers.  In both cases, the r0 registers that are fetched should
return 0 and the "Time Tag" register in both r1 sets should be
incrementing and rolling over at 0xffff.  The test code is below &
includes the code I use to parse the command/status registers. (the
oarcorp mailer fussed at the attachment)

The following is how I compute the base address for the PCI chipset
and the tranceiver.  Its in the attached code, but maybe theres
something wrong here so you don't have to wade thru the whole file.
THis code is run after identifying the bus and slot that one of the
devices I support is in.  start is the base address I use in all the
ld_* functions- it does find the various spaces for the cards OK.  I'm
very suspicious that I'm doing something wrong given the 0xffffffff
coming back from the pci chipset registers, but my pci book hasn't
been very helpful.

    int pbar[]= { PCI_BASE_ADDRESS_0, 
                   PCI_BASE_ADDRESS_1, 
                   PCI_BASE_ADDRESS_2, 
                   PCI_BASE_ADDRESS_3,
                   PCI_BASE_ADDRESS_4,
                   PCI_BASE_ADDRESS_5,
                   -1};
 
     for(j=0; pbar[j] > -1; j++)
     {
        pci_read_config_dword( devinst->bus, devinst->slot, 0, pbar[j], &start );

        if( start & PCI_BASE_ADDRESS_MEM_MASK )
        {
           // base address != 0 means this range is decoded

           // set the base address
           //start &= PCI_BASE_ADDRESS_MEM_MASK;

           // get size & flags out of base address register
           pci_write_config_dword( devinst->bus, devinst->slot, 0, pbar[j], 0xffffffff );
           pci_read_config_dword( devinst->bus, devinst->slot, 0, pbar[j], &dwtemp );

           flags = dwtemp & ~PCI_BASE_ADDRESS_MEM_MASK;

           // reassert the start address
           pci_write_config_dword( devinst->bus, devinst->slot, 0, pbar[j], start );

           start = (start & PCI_BASE_ADDRESS_MEM_MASK) + PCI_MEM_BASE;

           // find the first bit set to one after the base
           // address type bits to find length of region
           {
              unsigned int c= 16 , val= 0;
              while( !(val= dwtemp & c) ) c <<= 1;
              end = start + val;
           }




 
 > 
 > > Linux implements ioremap to get address ranges mapped thu the vm
 > > subsystem, are there BAT or mapping configuration changes needed to
 > > talk to other pci hardware under RTEMS?
 > 
 > AFAIK, no. (Unless you need more than 0x08000000 bytes - startup.c
 > lets the BAT map only that many.)

The boards only need 128kb of memory for the IO buffers and 128 bytes
or so for the register spaces.

 > 
 > > 
 > > Could there be extra incantations needed to get transactions out onto
 > > the backplane?  I've looked thru the bsp fairly closely but haven't
 > > found anything.
 > > 
 > 
 > I can perfectly talk to a PMC-network adapter plugged into my MVME23xx
 > under RTEMS. I scan config space for the vendor/device signature
 > 
 >    BSP_pciFindDevice(BLAH_VENDOR_ID, BLAH_DEVICE_ID, instance,
 >                      &bus, &dev, &fun);
 > 
 > and read the base address from config space:
 > 
 >    pci_read_config_dword(bus,dev,fun,PCI_BASE_ADDRESS_1,&base_addr);
 > 
 > Then I can see the device at (base_address + PCI_MEM_BASE). No special 
 > magic needed.
 > BTW: what snapshot are you using?
 > 

20021007 (theres some updates that didn't make it into the later
snapshots, but should be in the next one)


Thanks for your help,

Gregm


========================================================================

//
// Exercise RTEMS pci functionality on MCP750/MTX603
//

#include <rtems.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

extern "C"
{
#include <bsp/pci.h>
#include <libcpu/byteorder.h>
#include <libcpu/io.h>
}



#define MAX_DEVICES             8
#define MAX_REGIONS             6
#define DEVICE_COUNT_RESOURCE   MAX_REGIONS

#define DEVICENAME_LEN          64







#define IOPROTOCOL_IOCTL        1
#define IOPROTOCOL_MMAP         2

#define DRIVER_NAME             "pci1553"



/*
** Supported device prototypes
**
*/

#define DEVICE_ALPHI_PMC1553       0
#define DEVICE_ALPHI_PCI1553_1     1


struct _bardata
{
      int bar;
      int width;
      int io_protocol;
};


struct _devproto
{
      unsigned int      vendor;
      unsigned int      device;
      unsigned int      id;
      char              *vendorName;
      char              *deviceName;
      struct _bardata   barlist[DEVICE_COUNT_RESOURCE];
};


static struct _devproto  devlist[]= \
{{ 0x13c5, 0x0306, DEVICE_ALPHI_PMC1553,  "Alphi Technology", "PMC1553", {{0, 32, IOPROTOCOL_IOCTL},
                                                                          {1, 16, IOPROTOCOL_IOCTL},
                                                                          {3, 16, IOPROTOCOL_MMAP},
                                                                          {-1,0}} },

 { 0x13c5, 0x0108, DEVICE_ALPHI_PCI1553_1, "Alphi Technology", "CPCI1553-1", {{0, 32, IOPROTOCOL_IOCTL },
                                                                              {1, 16, IOPROTOCOL_IOCTL },
                                                                              {3, 16, IOPROTOCOL_MMAP },
                                                                              {-1,0}}},
                                    { 0,0,0,NULL,NULL }};




/*
**
** Device instances & their bars
**
*/



struct _alphi_context
{
      int               int_ready;
      unsigned int      pending_int,int_mask;
};


union _devctx
{
      struct _alphi_context alphi;
};






struct _devregion
{
      int               deviceNum;              /* index into device array for this region's device */
      int               bar;                    /* base address register this region corresponds to */
      void              *mapped_start;          /* base pointer for ioremapp'ed ioctl-access IO memory */
      unsigned int      start, end, flags;      /* parameters for this region */
      int               width,io_protocol;      /* access size & type, ioctl or mmap */
};


struct _devinstance
{
      unsigned int      id;
      unsigned char     bus, slot, irq;
      unsigned char     revision;
      int               bGotIRQ;

      struct _devregion deviceRegion[MAX_REGIONS];
      int               numRegions;

      union _devctx     deviceContext;

      char              deviceName[DEVICENAME_LEN];
      int               deviceMajor;
};


struct _devinstance deviceInstances[MAX_DEVICES];
int                 numDevices;












void print_summit_registers( struct _devinstance *devinst );





void exercise_pci()
{
   {
      unsigned char    bus,slot;
      unsigned short   vendor,device;

      unsigned int     start, end, flags, dwtemp;
      int              dlentry,j,k,dnum,rnum;

      struct _devinstance *devinst;
      struct _devregion   *devregion;

      numDevices = 0;

      printf("\nScanning pci busses for hardware...\n");

      /*
      ** Search for all instances of each device we support
      */
      for(bus=0; bus < BusCountPCI() && numDevices < MAX_DEVICES; bus++)
      {
         for(slot=0; slot < PCI_MAX_DEVICES && numDevices < MAX_DEVICES; slot++)
         {
            pci_read_config_word(bus, slot, 0, PCI_VENDOR_ID, &vendor);

            if( vendor != 0xffff )
            {
               pci_read_config_word(bus, slot, 0, PCI_DEVICE_ID, &device);

               {
                  unsigned int bar0,bar1,bar3;
                  pci_read_config_dword(bus, slot, 0, PCI_BASE_ADDRESS_0, &bar0 );
                  pci_read_config_dword(bus, slot, 0, PCI_BASE_ADDRESS_1, &bar1 );
                  pci_read_config_dword(bus, slot, 0, PCI_BASE_ADDRESS_3, &bar3 );
               
                  printf("bus 0x%x, slot 0x%02x, vendor 0x%04X, device 0x%04X, bar0 %08X, bar1 %08X, bar3 %08X\n", 
                         bus, slot, vendor, device, 
                         bar0,bar1,bar3 );
               }


               for( dlentry=0; devlist[dlentry].vendorName && numDevices < MAX_DEVICES; dlentry++)
               {
                  if( devlist[dlentry].vendor == vendor && devlist[dlentry].device == device )
                  {
                     dnum = numDevices++;
                     memset( (devinst = &deviceInstances[dnum]), 0, sizeof(struct _devinstance) );

                     printf("\n%s: Found device %i\n", DRIVER_NAME, dnum );

                     devinst->id   = devlist[dlentry].id;
                     devinst->bus  = bus;
                     devinst->slot = slot;

                     /*
                     ** Create the base device name for the board.  
                     */
                     sprintf(devinst->deviceName, "%s-%02X:%02X", 
                             devlist[dlentry].deviceName,
                             devinst->bus,
                             devinst->slot );


                     pci_read_config_byte( devinst->bus, devinst->slot, 0, PCI_REVISION_ID, &devinst->revision );
                     pci_read_config_byte( devinst->bus, devinst->slot, 0, PCI_INTERRUPT_LINE, &devinst->irq );

                     printf("Device: %s, %s(0x%04X), rev 0x%02X,\n   bus 0x%02x, slot 0x%02x, irq 0x%02X\n", 
                            devlist[dlentry].vendorName, 
                            devlist[dlentry].deviceName, 
                            devlist[dlentry].device, 
                            devinst->revision, 
                            devinst->bus,
                            devinst->slot,
                            devinst->irq );


                     {
                        struct _bitdefs
                        {
                              unsigned short bval;
                              char *desc;
                        };

                        {
                           unsigned short cmd;
                           struct _bitdefs cmdbits[]= {{ PCI_COMMAND_IO,          "IOenable" },
                                                       { PCI_COMMAND_MEMORY,      "MEMenable" },
                                                       { PCI_COMMAND_MASTER,      "Bmaster" },
                                                       { PCI_COMMAND_SPECIAL,     "SPenable" },
                                                       { PCI_COMMAND_INVALIDATE,  "MEMw/inval" },
                                                       { PCI_COMMAND_VGA_PALETTE, "VGAsnoop" },
                                                       { PCI_COMMAND_PARITY,      "PERRenable" },
                                                       { PCI_COMMAND_WAIT,        "WAITenable" },
                                                       { PCI_COMMAND_SERR,        "SERRenable" },
                                                       { PCI_COMMAND_FAST_BACK,   "B2Benable" },
                                                       { 0, NULL }};

                           pci_read_config_word(devinst->bus, devinst->slot, 0, PCI_COMMAND, &cmd);

                           printf("   PCI Command register: [ ");
                           for(int i=0; cmdbits[i].bval; i++)
                              if( cmdbits[i].bval & cmd ) printf("%s ", cmdbits[i].desc );
                           printf("]\n");
                        }


                        {
                           unsigned short stat;
                           struct _bitdefs statbits[]= {{ PCI_STATUS_66MHZ,            "66MHZenabled" },
                                                        { PCI_STATUS_UDF,              "UDFenabled" },
                                                        { PCI_STATUS_FAST_BACK,        "B2Benabled" },
                                                        { PCI_STATUS_PARITY,           "PERRenabled" },
                                                        { PCI_STATUS_SIG_TARGET_ABORT, "STARGabort" },
                                                        { PCI_STATUS_REC_TARGET_ABORT, "RTARGabort" },
                                                        { PCI_STATUS_REC_MASTER_ABORT, "RMASTabort" },
                                                        { PCI_STATUS_SIG_SYSTEM_ERROR, "SSYSerror" },
                                                        { PCI_STATUS_DETECTED_PARITY,  "PERRdetected" },
                                                        { 0, NULL }};

                           pci_read_config_word(devinst->bus, devinst->slot, 0, PCI_STATUS, &stat);

                           printf("   PCI Status register:  [ ");
                           for(int i=0; statbits[i].bval; i++)
                              if( statbits[i].bval & stat ) printf("%s ", statbits[i].desc );
                           printf("]\n");
                        }
                     }




                     /*
                     ** insert interrupt handler
                     */
                     //if( request_irq( devinst->pcid->irq, pci1553_int, SA_SHIRQ, DRIVER_NAME, (void *)devinst ) )
                     // {
                     //   printf("%s: unable to allocate irq 0x%02x\n", DRIVER_NAME, devinst->pcid->irq );
                     //}
                     //else
                     //devinst->bGotIRQ = -1;


                     /*
                     ** configure device contexts
                     */
                     switch( devinst->id )
                     {
                        case DEVICE_ALPHI_PMC1553:
                        case DEVICE_ALPHI_PCI1553_1:
                        {
                           struct _alphi_context  *alphi = (struct _alphi_context *)&devinst->deviceContext.alphi;
                        }
                     }




                     /*
                     ** Run through all the base addresses for this device and accumulate the defined ones
                     */

                     int pbar[]= { PCI_BASE_ADDRESS_0, 
                                   PCI_BASE_ADDRESS_1, 
                                   PCI_BASE_ADDRESS_2, 
                                   PCI_BASE_ADDRESS_3,
                                   PCI_BASE_ADDRESS_4,
                                   PCI_BASE_ADDRESS_5,
                                   -1};

                     for(j=0; pbar[j] > -1; j++)
                     {
                        pci_read_config_dword( devinst->bus, devinst->slot, 0, pbar[j], &start );

                        if( start & PCI_BASE_ADDRESS_MEM_MASK )
                        {
                           // base address != 0 means this range is decoded

                           // set the base address
                           //start &= PCI_BASE_ADDRESS_MEM_MASK;

                           // get size & flags out of base address register
                           pci_write_config_dword( devinst->bus, devinst->slot, 0, pbar[j], 0xffffffff );
                           pci_read_config_dword( devinst->bus, devinst->slot, 0, pbar[j], &dwtemp );

                           flags = dwtemp & ~PCI_BASE_ADDRESS_MEM_MASK;

                           // reassert the start address
                           pci_write_config_dword( devinst->bus, devinst->slot, 0, pbar[j], start );

                           start = (start & PCI_BASE_ADDRESS_MEM_MASK) + PCI_MEM_BASE;

                           // find the first bit set to one after the base
                           // address type bits to find length of region
                           {
                              unsigned int c= 16 , val= 0;
                              while( !(val= dwtemp & c) ) c <<= 1;
                              end = start + val;
                           }


                           /*
                           ** Found the start, end and flags of a decoded region
                           */
                           rnum = devinst->numRegions++;

                           memset( (devregion = &devinst->deviceRegion[rnum]), 0, sizeof(struct _devregion));

                           /*
                           ** Set up the region data for this bar
                           */
                           devregion->deviceNum = dlentry;

                           devregion->bar   = j;
                           devregion->start = start;
                           devregion->end   = end;
                           devregion->flags = flags;

                           for(k=0; devlist[dlentry].barlist[k].bar > -1; k++)
                           {
                              if( devlist[dlentry].barlist[k].bar == j )
                              {
                                 devregion->width       = devlist[dlentry].barlist[k].width;
                                 devregion->io_protocol = devlist[dlentry].barlist[k].io_protocol;
                                 break;
                              }
                           }
                           if( devlist[dlentry].barlist[k].bar == -1 )
                           {
                              printf("%s: warning, unable to find bar %i for device %s\n", DRIVER_NAME, j, devinst->deviceName );
                           }


                           /*
                           ** for ioctl access regions, remap them for later access
                           */
                           if( devregion->io_protocol == IOPROTOCOL_IOCTL )
                           {
                           }


                           /*
                           ** Print useful stuff
                           */
                           printf("   bar %i, start/end %08X/%08X, width %i, flags %08X\n",
                                  devregion->bar, 
                                  devregion->start, devregion->end,
                                  devregion->width,
                                  devregion->flags );

                        }
                     }
                     printf("\n");
                  }
               }
            }
         }
      }

      printf("\nFinished scanning pci busses.\n\n");

      for(int i=0; i < numDevices; i++ )
      {
         print_summit_registers( &deviceInstances[i] );
      }
   }

    
   return;
}















struct _regs
{
      int  fetch;
      int  offset;
      char *name;
};

struct _regs r0_regs[]= {{0, 0x0, "OMB1 Outgoing Mailbox reg 1"},
                         {0, 0x4, "OMB2 Outgoing Mailbox reg 2"},
                         {0, 0x8, "OMB3 Outgoing Mailbox reg 3"},
                         {0, 0xc, "OMB4 Outgoing Mailbox reg 4"},
                         {0, 0x10,"IMB1 Incoming Mailbox reg 1"},
                         {0, 0x14,"IMB2 Incoming Mailbox reg 2"},
                         {0, 0x18,"IMB3 Incoming Mailbox reg 3"},
                         {-1,0x1c,"IMB4 Incoming Mailbox reg 4"},
                         {0, 0x20,"Bidirectional FIFO register"},
                         {0, 0x24,"MWAR Master Write Address Register"},
                         {0, 0x28,"MWTC Master Write Transfer Counter"},
                         {0, 0x2c,"MRAR Master Read Address Register"},
                         {0, 0x30,"MRTC Master Read Transfer Counter"},
                         {-1,0x34,"MBEF Mailbox Empty/Full Status"},
                         {-1,0x38,"INTCSR Interrupt Control/Status Register"},
                         {0, 0x3c,"MCSR Bus Master Control/Status Register"},
                         {-1,-1, NULL}};

struct _regs r1_regs[]= {{-1,0x0,  "Control Register"},
                         {-1,0x2,  "Operational Status Register"},
                         {-1,0x4,  "Current Command Register"},
                         {-1,0x8,  "Interrupt Mask Register"},
                         {-1,0xa,  "Pending Interrupt Register"},
                         {-1,0xc,  "BIT Word Register"},
                         {-1,0xe,  "Time Tag Register"},
                         {-1,0x10, "RT Descriptor Pointer Register"},
                         {-1,0x12, "Status Word Bits Register"},
                         {-1,0x20, "Illegalization Register"},
                         {-1,0x22, "Illegalization Register"},
                         {-1,0x24, "Illegalization Register"},
                         {-1,0x26, "Illegalization Register"},
                         {-1,0x28, "Illegalization Register"},
                         {-1,0x2a, "Illegalization Register"},
                         {-1,0x2c, "Illegalization Register"},
                         {-1,0x2e, "Illegalization Register"},
                         {-1,0x30, "Illegalization Register"},
                         {-1,0x32, "Illegalization Register"},
                         {-1,0x34, "Illegalization Register"},
                         {-1,0x36, "Illegalization Register"},
                         {-1,0x38, "Illegalization Register"},
                         {-1,0x3a, "Illegalization Register"},
                         {-1,0x3c, "Illegalization Register"},
                         {-1,0x3e, "Illegalization Register"},
                         {-1,0x42, "PMC Status"},
                         {-1,-1, NULL}};




void print_summit_registers( struct _devinstance *devinst )
{
   volatile unsigned int   v;
   unsigned int   i;

   printf("\nPrinting information for device %s\n", devinst->deviceName );

   {
      struct _devregion   *devregion = &devinst->deviceRegion[0];
      unsigned char       *base = (unsigned char *)devregion->start;
      struct _regs        *reg = r0_regs;

      printf("Dumping r0 registers;\n");
      for(i=0; reg[i].offset > -1; i++)
      {
         if( reg[i].fetch )
         {
            switch( devregion->width )
            {
               case 16:
                  v = (unsigned int) ld_le16((unsigned short *) base+reg[i].offset );
                  break;
               case 32:
                  v = (unsigned int) ld_le32((unsigned int *) base+reg[i].offset );
                  break;
               default:
                  printf("unsupported register width %i\n", devregion->width );
                  v= 0;
            }
            printf("   %08X - (0x%02X - %s)\n", v, reg[i].offset , reg[i].name );
         }
         else
            printf("   offset %02x not fetched (%s)\n", reg[i].offset, reg[i].name );
      }
      printf("\n");
   }




   {
      struct _devregion   *devregion = &devinst->deviceRegion[1];
      unsigned char       *base = (unsigned char *)devregion->start;
      struct _regs        *reg = r1_regs;

      printf("Dumping r1 registers;\n");
      for(i=0; reg[i].offset > -1; i++)
      {
         if( reg[i].fetch )
         {
            switch( devregion->width )
            {
               case 16:
                  v = (unsigned int) ld_le16((unsigned short *) base+reg[i].offset );
                  break;
               case 32:
                  v = (unsigned int) ld_le32((unsigned int *) base+reg[i].offset );
                  break;
               default:
                  printf("unsupported register width %i\n", devregion->width );
                  v= 0;
            }
            printf("   %04X - (0x%02X - %s)\n", v, reg[i].offset , reg[i].name );
         }
         else
            printf("   offset %02x not fetched (%s)\n", reg[i].offset, reg[i].name );
      }
      printf("\n");
   }
}




// eof




More information about the users mailing list