home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / windr440.zip / windrive.zip / WinDriver / plx / 9054 / p9054_diag / p9054_diag.c
C/C++ Source or Header  |  2000-03-30  |  16KB  |  471 lines

  1. ////////////////////////////////////////////////////////////////
  2. // File - P9054_DIAG.C
  3. //
  4. // o A simple diagnostics program that lets you access the
  5. //   PLX 9054 registers and local memory. 
  6. // o This program is meant to be used as an example for using the P9054_LIB.H API,
  7. //   you may use it as a skeleton for your driver, or 'cut & paste' parts
  8. //   of it into your device driver code.
  9. // o For a more advanced monitor program, use the standard PLXMON.EXE
  10. //   from PLX.
  11. // 
  12. ////////////////////////////////////////////////////////////////
  13.  
  14. #include "../lib/p9054_lib.h"
  15. #include "../../../samples/shared/pci_diag_lib.h"
  16. #include <stdio.h>
  17.  
  18. // input of command from user
  19. static char line[256];
  20.  
  21. void PLX_EditReg(P9054_HANDLE hPlx)
  22. {
  23.     struct 
  24.     {
  25.         CHAR *name;
  26.         DWORD dwOffset;
  27.         DWORD dwVal;
  28.     } fields[30];
  29.  
  30.     int cmd;
  31.     int i;
  32.     int field_count;
  33.  
  34.     i = 0;
  35.     fields[i].name = "LAS0RR"; fields[i++].dwOffset = 0x00;
  36.     fields[i].name = "LAS0BA"; fields[i++].dwOffset = 0x04;
  37.     fields[i].name = "EROMRR"; fields[i++].dwOffset = 0x10;
  38.     fields[i].name = "EROMBA"; fields[i++].dwOffset = 0x14;
  39.     fields[i].name = "LBRD0"; fields[i++].dwOffset = 0x18;
  40.     fields[i].name = "MBOX0"; fields[i++].dwOffset = 0x40;
  41.     fields[i].name = "MBOX1"; fields[i++].dwOffset = 0x44;
  42.     fields[i].name = "MBOX2"; fields[i++].dwOffset = 0x48;
  43.     fields[i].name = "MBOX3"; fields[i++].dwOffset = 0x4c;
  44.     fields[i].name = "MBOX4"; fields[i++].dwOffset = 0x50;
  45.     fields[i].name = "MBOX5"; fields[i++].dwOffset = 0x54;
  46.     fields[i].name = "MBOX6"; fields[i++].dwOffset = 0x58;
  47.     fields[i].name = "MBOX7"; fields[i++].dwOffset = 0x5c;
  48.     fields[i].name = "P2LDBELL"; fields[i++].dwOffset = 0x60;
  49.     fields[i].name = "L2PDBELL"; fields[i++].dwOffset = 0x64;
  50.     fields[i].name = "INTCSR"; fields[i++].dwOffset = 0x68;
  51.     fields[i].name = "CNTRL"; fields[i++].dwOffset = 0x6c;
  52.     fields[i].name = "SECID"; fields[i++].dwOffset = 0x70;
  53.     fields[i].name = "REVISON"; fields[i++].dwOffset = 0x74;
  54.     field_count = i;
  55.     do
  56.     {
  57.         int row;
  58.         int col;
  59.         int row_count = field_count/2 + field_count%2;
  60.  
  61.         printf ("\n");
  62.         printf ("Edit PLX 9054 registers\n");
  63.         printf ("--------------------------------\n");
  64.         for (row = 0; row<row_count; row++)
  65.         {
  66.             for (col = 0; col<=1; col++)
  67.             {
  68.                 if (col==0) i = row;
  69.                 else i = row + row_count;
  70.  
  71.                 if (i<field_count)
  72.                 {
  73.                     char buf[10];
  74.                     fields[i].dwVal = P9054_ReadReg(hPlx, fields[i].dwOffset);
  75.                     sprintf(buf, "%08x",fields[i].dwVal);
  76.                     printf ("%2d. %8s : %s     ",i+1, fields[i].name, buf);
  77.                 }
  78.                 if (col==1) printf ("\n");
  79.             }
  80.         }
  81.  
  82.         printf ("99. Back to main menu\n");
  83.         printf ("Choose register to write to, or 99 to exit: ");
  84.         cmd = 0;
  85.         gets (line);
  86.         sscanf (line, "%d",&cmd);
  87.         if (cmd>=1 && cmd <=21)
  88.         {
  89.             i = cmd-1;
  90.             printf ("Enter value to write to %s register (or 'X' to cancel): ",fields[i].name);
  91.             gets (line);
  92.             if (toupper (line[0])!='X')
  93.             {
  94.                 DWORD dwVal;
  95.                 dwVal = 0;
  96.                 sscanf (line,"%x",&dwVal);
  97.                 P9054_WriteReg(hPlx, fields[i].dwOffset, dwVal);
  98.             }
  99.         }
  100.     } while (cmd!=99);
  101. }
  102.  
  103. char *PLX_GetAddrRangeName(P9054_ADDR addrSpace)
  104. {
  105.     return 
  106.         addrSpace==P9054_ADDR_SPACE0 ? "Addr Space 0 - (BAR2)" :
  107.         addrSpace==P9054_ADDR_SPACE1 ? "Addr Space 1 - (BAR3)" :
  108.         addrSpace==P9054_ADDR_SPACE2 ? "Addr Space 2 - (BAR4)" :
  109.         addrSpace==P9054_ADDR_SPACE3 ? "Addr Space 3 - (BAR5)" :
  110.         addrSpace==P9054_ADDR_EPROM ? "EEPROM Addr Space" : "Invalid";
  111. }
  112.  
  113. void PLX_BoardAccess(P9054_HANDLE hPlx, BOOL fLocalAddr)
  114. {
  115.     int cmd, cmd2;
  116.     DWORD addr, data, i;
  117.     P9054_ADDR ad_sp = P9054_ADDR_SPACE0;
  118.     P9054_MODE ad_mode = P9054_MODE_DWORD;
  119.  
  120.     char *pcMemoryType = fLocalAddr ? "local address" : "offset";
  121.  
  122.     if (!fLocalAddr)
  123.     {
  124.         for (; ad_sp<=P9054_ADDR_EPROM && !P9054_IsAddrSpaceActive(hPlx, ad_sp); ad_sp++)
  125.         if (ad_sp>P9054_ADDR_EPROM)
  126.         {
  127.             printf ("No active memory spaces on board!\n");
  128.             return;
  129.         }
  130.     }
  131.  
  132.     do
  133.     {
  134.         printf ("Access the board's %s ranges\n",pcMemoryType);
  135.         printf ("-------------------------------------------\n");
  136.         printf ("(Access to invalid %s may hang the computer!)\n", pcMemoryType);
  137.         if (!fLocalAddr)
  138.             printf ("1. Change active memory space: %s\n",PLX_GetAddrRangeName(ad_sp));
  139.         printf ("2. Toggle active mode: %s\n", 
  140.             ad_mode==P9054_MODE_BYTE ? "BYTE (8 bit)" :
  141.             ad_mode==P9054_MODE_WORD ? "WORD (16 bit)" : "DWORD (32 bit)");
  142.         printf ("3. Read from board\n");
  143.         printf ("4. Write to board\n");
  144.         printf ("99. Back to main menu\n");
  145.         printf ("\n");
  146.         printf ("Enter option: ");
  147.         cmd = 0;
  148.         gets (line);
  149.         sscanf (line, "%d",&cmd);
  150.         switch (cmd)
  151.         {
  152.         case 1:
  153.             if (!fLocalAddr)
  154.             {
  155.                 printf ("Choose memory space:\n");
  156.                 printf ("--------------------\n");
  157.                 for (i=P9054_ADDR_SPACE0; i<=P9054_ADDR_EPROM; i++)
  158.                 {
  159.                     printf ("%d. %s", i, PLX_GetAddrRangeName(i));
  160.                     if (P9054_IsAddrSpaceActive(hPlx, i)) printf ("\n");
  161.                     else printf (" - space not active\n");
  162.                 }
  163.                 printf ("Enter option: ");
  164.                 cmd2 = 99;
  165.                 gets (line);
  166.                 sscanf (line, "%d",&cmd2);
  167.                 if (cmd2>=P9054_ADDR_SPACE0 && cmd2<=P9054_ADDR_EPROM)
  168.                 {
  169.                     int new_ad_sp = cmd2;
  170.                     if (P9054_IsAddrSpaceActive(hPlx, new_ad_sp)) ad_sp = new_ad_sp;
  171.                     else printf ("Chosen space not active!\n");
  172.                 }
  173.             }
  174.             break;
  175.         case 2:
  176.             ad_mode = (ad_mode + 1) % 3;
  177.             break;
  178.         case 3:
  179.             printf ("Enter %s to read from: ", pcMemoryType);
  180.             gets (line);
  181.             sscanf (line, "%x", &addr);
  182.             switch (ad_mode)
  183.             {
  184.             case P9054_MODE_BYTE:
  185.                 if (fLocalAddr) data = P9054_ReadByteLocal(hPlx, addr);
  186.                 else data = P9054_ReadByte(hPlx, ad_sp, addr);
  187.                 break;
  188.             case P9054_MODE_WORD:
  189.                 if (fLocalAddr) data = P9054_ReadWordLocal(hPlx, addr);
  190.                 else data = P9054_ReadWord(hPlx, ad_sp, addr);
  191.                 break;
  192.             case P9054_MODE_DWORD:
  193.                 if (fLocalAddr) data = P9054_ReadDWordLocal(hPlx, addr);
  194.                 else data = P9054_ReadDWord(hPlx, ad_sp, addr);
  195.                 break;
  196.             }
  197.             printf ("Value read: %x\n", data);
  198.             break;
  199.         case 4:
  200.             printf ("Enter %s to write to: ", pcMemoryType);
  201.             gets (line);
  202.             sscanf (line, "%x", &addr);
  203.             printf ("Enter data to write %s: ",
  204.                 ad_mode==P9054_MODE_BYTE ? "BYTE (8 bit)" :
  205.                 ad_mode==P9054_MODE_WORD ? "WORD (16 bit)" : "DWORD (32 bit)");
  206.             gets (line);
  207.             sscanf (line, "%x",&data);
  208.             switch (ad_mode)
  209.             {
  210.             case P9054_MODE_BYTE:
  211.                 if (fLocalAddr) P9054_WriteByteLocal(hPlx, addr, (BYTE) data);
  212.                 else P9054_WriteByte(hPlx, ad_sp, addr, (BYTE) data);
  213.                 break;
  214.             case P9054_MODE_WORD:
  215.                 if (fLocalAddr) P9054_WriteWordLocal(hPlx, addr, (WORD) data);
  216.                 else P9054_WriteWord(hPlx, ad_sp, addr, (WORD) data);
  217.                 break;
  218.             case P9054_MODE_DWORD:
  219.                 if (fLocalAddr) P9054_WriteDWordLocal(hPlx, addr, data);
  220.                 else P9054_WriteDWord(hPlx, ad_sp, addr, data);
  221.                 break;
  222.             }
  223.             break;
  224.         }
  225.     } while (cmd!=99);
  226. }
  227.  
  228. void WINAPI PLX_IntHandlerRoutine(P9054_HANDLE hPlx, P9054_INT_RESULT *intResult)
  229. {
  230.     printf ("Got interrupt number %d\n", intResult->dwCounter);
  231. }
  232.  
  233. void PLX_EnableDisableInterrupts(P9054_HANDLE hPlx)
  234. {
  235.     int cmd;
  236.  
  237.     printf ("WARNING!!!\n");
  238.     printf ("----------\n");
  239.     printf ("Your hardware has level sensitive interrupts.\n");
  240.     printf ("You must modify the source code of P9054_IntEnable(), in the file P9054_lib.c,\n");
  241.     printf ("to acknowledge the interrupt before enabling interrupts.\n");
  242.     printf ("Without this modification, your PC will HANG upon interrupt!\n");
  243.  
  244.     do
  245.     {
  246.         printf ("Enable / Disable interrupts\n");
  247.         printf ("---------------------------\n");
  248.         printf ("1. %s interrupts\n", P9054_IntIsEnabled(hPlx) ? "Disable" : "Enable");
  249.         printf ("99. Back to main menu\n");
  250.         printf ("\n");
  251.         printf ("Enter option: ");
  252.         cmd = 0;
  253.         gets (line);
  254.         sscanf (line, "%d",&cmd);
  255.         switch (cmd)
  256.         {
  257.         case 1:
  258.             if (P9054_IntIsEnabled(hPlx))
  259.             {
  260.                 printf ("Disabling interrupt Int\n");
  261.                 P9054_IntDisable(hPlx);
  262.             }
  263.             else
  264.             {
  265.                 printf ("Enabling interrupts\n");
  266.                 if (!P9054_IntEnable(hPlx, PLX_IntHandlerRoutine))
  267.                     printf ("failed enabling interrupts\n");
  268.             }
  269.             break;
  270.         }
  271.     } while (cmd!=99);
  272. }
  273.  
  274. void PLX_EEPROMAccess(P9054_HANDLE hPlx)
  275. {
  276.     int cmd;
  277.     DWORD addr;
  278.     DWORD dwData;
  279.  
  280.     do
  281.     {
  282.         printf ("Access the board's serial EERPOM\n");
  283.         printf ("--------------------------------\n");
  284.         if (!P9054_EEPROMValid(hPlx))
  285.             printf ("Note: PLX EEPROM valid BIT is 0\n");
  286.         printf (" Note: reading/writing to odd addresses is meaningless,\n");
  287.         printf ("       as data is stored in words.\n");
  288.         printf ("1. Display EEPROM content\n");
  289.         printf ("2. Read dword from serial EEPROM on the board\n");
  290.         printf ("3. Write dword to the serial EEPROM on the board\n");
  291.         printf ("99. Back to main menu\n");
  292.         printf ("\n");
  293.         printf ("Enter option: ");
  294.         cmd = 0;
  295.         gets (line);
  296.         sscanf (line, "%d",&cmd);
  297.         switch (cmd)
  298.         {
  299.         case 1:
  300.             for (addr=0; addr<0xff; addr += 4)
  301.             {
  302.                 if (!(addr % 0x10))
  303.                 printf("\n %02x: ", addr);
  304.                 if (!P9054_EEPROMReadDWord(hPlx, addr, &dwData))
  305.                 {
  306.                     printf("\nError occured reading serial EEPROM - %s\n", P9054_ErrorString);
  307.                     break;
  308.                 }
  309.                 printf("%08x  ", dwData);
  310.             }
  311.             printf ("\n");
  312.             break;
  313.         case 2:
  314.             printf ("Enter addr to read from (0-ff): ");
  315.             gets (line);
  316.             sscanf (line, "%x", &addr);
  317.             if (P9054_EEPROMReadDWord(hPlx, addr, &dwData))
  318.                 printf ("Value read: %x\n", dwData);
  319.              else
  320.                 printf("Error occured reading serial EEPROM - %s\n", P9054_ErrorString);
  321.             break;
  322.  
  323.         case 3:
  324.             printf ("Enter addr to write to (0-ff): ");
  325.             gets (line);
  326.             sscanf (line, "%x", &addr);
  327.             printf ("Enter data to write: ");
  328.             gets (line);
  329.             sscanf (line, "%x",&dwData);
  330.             if (!P9054_EEPROMWriteDWord(hPlx, addr, dwData))
  331.                 printf("Error occured reading serial EEPROM - %s\n", P9054_ErrorString);
  332.             break;
  333.  
  334.         default:
  335.             break;
  336.         }
  337.     } while (cmd!=99);
  338. }
  339.  
  340. P9054_HANDLE PLX_LocateAndOpenBoard(DWORD dwVendorID, DWORD dwDeviceID, BOOL fUseInt)
  341. {
  342.     DWORD cards, my_card;
  343.     P9054_HANDLE hPlx = NULL;
  344.  
  345.     if (dwVendorID==0)
  346.     {
  347.         printf ("Enter VendorID: ");
  348.         gets (line);
  349.         sscanf (line, "%x",&dwVendorID);
  350.         if (dwVendorID==0) return NULL;
  351.  
  352.         printf ("Enter DeviceID: ");
  353.         gets (line);
  354.         sscanf (line, "%x",&dwDeviceID);
  355.     }
  356.     cards = P9054_CountCards (dwVendorID, dwDeviceID);
  357.     if (cards==0) 
  358.     {
  359.         printf("%s", P9054_ErrorString);
  360.         return NULL;
  361.     }
  362.     else if (cards==1) my_card = 1;
  363.     else
  364.     {
  365.         DWORD i;
  366.  
  367.         printf("Found %d matching PCI cards\n", cards);
  368.         printf("Select card (1-%d): ", cards);
  369.         i = 0;
  370.         gets (line);
  371.         sscanf (line, "%d",&i);
  372.         if (i>=1 && i <=cards) my_card = i;
  373.         else 
  374.         {
  375.             printf ("Choice out of range\n");
  376.             return NULL;
  377.         }
  378.     }
  379.     if (P9054_Open (&hPlx, dwVendorID, dwDeviceID, my_card - 1, fUseInt ? P9054_OPEN_USE_INT : 0))
  380.         printf ("PLX 9054 PCI card found!\n");
  381.     else printf ("%s", P9054_ErrorString);
  382.     return hPlx;
  383. }
  384.  
  385. int main(int argc, char *argv[])
  386. {
  387.     int cmd;
  388.     P9054_HANDLE hPlx = NULL;
  389.     HANDLE hWD;
  390.     BOOL fUseInt = FALSE; // by default - do not install interrupts
  391.     BOOL fOpenedWithInt = fUseInt;
  392.  
  393.     printf ("PLX 9054 diagnostic utility.\n");
  394.     printf ("Application accesses hardware using " WD_PROD_NAME ".\n");
  395.  
  396.     // make sure WinDriver is loaded
  397.     if (!PCI_Get_WD_handle(&hWD)) return 0;
  398.     WD_Close (hWD);
  399.  
  400.     hPlx = PLX_LocateAndOpenBoard(0x10b5, 0x1860, fUseInt);
  401.  
  402.     do
  403.     {
  404.         printf ("\n");
  405.         printf ("PLX 9054 main menu\n");
  406.         printf ("-------------------\n");
  407.         printf ("1. Scan PCI bus\n");
  408.         printf ("2. Set opening board %s interrupts\n", fUseInt ? "without" : "with");
  409.         printf ("3. Locate/Choose PLX 9054 board (%s interrupts)\n", fUseInt ? "with" : "without");
  410.         if (hPlx)
  411.         {
  412.             printf ("4. PCI configuration registers\n");
  413.             printf ("5. PLX 9054 local registers\n");
  414.             printf ("6. Access address spaces on the board\n");
  415.             printf ("7. Access local address ranges on the board\n");
  416.             if (fOpenedWithInt)
  417.                 printf ("8. Enable / Disable interrupts\n");
  418.             printf ("9. Access serial EEPROM on the board\n");
  419.         }
  420.         printf ("99. Exit\n");
  421.         printf ("Enter option: ");
  422.         cmd = 0;
  423.         gets (line);
  424.         sscanf (line, "%d",&cmd);
  425.         switch (cmd)
  426.         {
  427.         case 1: // Scan PCI bus
  428.             PCI_Print_all_cards_info();
  429.             break;
  430.         case 2: // Set open board with / without interrupts
  431.             fUseInt = !fUseInt;
  432.             break;
  433.         case 3: // Locate PLX 9054 board
  434.             if (hPlx) P9054_Close(hPlx);
  435.             hPlx = PLX_LocateAndOpenBoard(0, 0, fUseInt);
  436.             if (!hPlx) printf ("PLX card open failed!\n");
  437.             fOpenedWithInt = fUseInt;
  438.             break;
  439.         case 4: // PCI configuration registers
  440.             if (hPlx) 
  441.             {
  442.                 WD_PCI_SLOT pciSlot;
  443.                 P9054_GetPciSlot(hPlx, &pciSlot);
  444.                 PCI_EditConfigReg(pciSlot);
  445.             }
  446.             break;
  447.         case 5: // PLX 9054 local registers
  448.             if (hPlx) PLX_EditReg(hPlx);
  449.             break;
  450.         case 6: // Access address spaces on the board
  451.             if (hPlx) PLX_BoardAccess(hPlx, FALSE);
  452.             break;
  453.         case 7: // Access local address ranges on the board
  454.             if (hPlx) PLX_BoardAccess(hPlx, TRUE);
  455.             break;
  456.         case 8: // Enable / Disable interrupts
  457.             if (hPlx && fOpenedWithInt) PLX_EnableDisableInterrupts(hPlx);
  458.             break;
  459.         case 9: // Access serial EEPROM on the board
  460.             if (hPlx) PLX_EEPROMAccess(hPlx);
  461.             break;
  462.         }
  463.     } while (cmd!=99);
  464.  
  465.     if (hPlx) P9054_Close(hPlx);
  466.  
  467.     return 0;
  468. }
  469.  
  470.                                       
  471.