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

  1. ////////////////////////////////////////////////////////////////
  2. // File - P9080_DIAG.C
  3. //
  4. // o A simple diagnostics program that lets you access the
  5. //   PLX 9080 registers and local memory. 
  6. // o This program is meant to be used as an example for using the P9080_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/p9080_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(P9080_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.     field_count = i;
  53.     do
  54.     {
  55.         int row;
  56.         int col;
  57.         int row_count = field_count/2 + field_count%2;
  58.  
  59.         printf ("\n");
  60.         printf ("Edit PLX 9080 registers\n");
  61.         printf ("--------------------------------\n");
  62.         for (row = 0; row<row_count; row++)
  63.         {
  64.             for (col = 0; col<=1; col++)
  65.             {
  66.                 if (col==0) i = row;
  67.                 else i = row + row_count;
  68.  
  69.                 if (i<field_count)
  70.                 {
  71.                     char buf[10];
  72.                     fields[i].dwVal = P9080_ReadReg(hPlx, fields[i].dwOffset);
  73.                     sprintf(buf, "%08x",fields[i].dwVal);
  74.                     printf ("%2d. %7s : %s     ",i+1, fields[i].name, buf);
  75.                 }
  76.                 if (col==1) printf ("\n");
  77.             }
  78.         }
  79.  
  80.         printf ("99. Back to main menu\n");
  81.         printf ("Choose register to write to, or 99 to exit: ");
  82.         cmd = 0;
  83.         gets (line);
  84.         sscanf (line, "%d",&cmd);
  85.         if (cmd>=1 && cmd <=21)
  86.         {
  87.             i = cmd-1;
  88.             printf ("Enter value to write to %s register (or 'X' to cancel): ",fields[i].name);
  89.             gets (line);
  90.             if (toupper (line[0])!='X')
  91.             {
  92.                 DWORD dwVal;
  93.                 dwVal = 0;
  94.                 sscanf (line,"%x",&dwVal);
  95.                 P9080_WriteReg(hPlx, fields[i].dwOffset, dwVal);
  96.             }
  97.         }
  98.     } while (cmd!=99);
  99. }
  100.  
  101. char *PLX_GetAddrRangeName(P9080_ADDR addrSpace)
  102. {
  103.     return 
  104.         addrSpace==P9080_ADDR_SPACE0 ? "Addr Space 0 - (BAR2)" :
  105.         addrSpace==P9080_ADDR_SPACE1 ? "Addr Space 1 - (BAR3)" :
  106.         addrSpace==P9080_ADDR_SPACE2 ? "Addr Space 2 - (BAR4)" :
  107.         addrSpace==P9080_ADDR_SPACE3 ? "Addr Space 3 - (BAR5)" :
  108.         addrSpace==P9080_ADDR_EPROM ? "EEPROM Addr Space" : "Invalid";
  109. }
  110.  
  111. void PLX_BoardAccess(P9080_HANDLE hPlx, BOOL fLocalAddr)
  112. {
  113.     int cmd, cmd2;
  114.     DWORD addr, data, i;
  115.     P9080_ADDR ad_sp = P9080_ADDR_SPACE0;
  116.     P9080_MODE ad_mode = P9080_MODE_DWORD;
  117.  
  118.     char *pcMemoryType = fLocalAddr ? "local address" : "offset";
  119.  
  120.     if (!fLocalAddr)
  121.     {
  122.         for (; ad_sp<=P9080_ADDR_EPROM && !P9080_IsAddrSpaceActive(hPlx, ad_sp); ad_sp++)
  123.         if (ad_sp>P9080_ADDR_EPROM)
  124.         {
  125.             printf ("No active memory spaces on board!\n");
  126.             return;
  127.         }
  128.     }
  129.  
  130.     do
  131.     {
  132.         printf ("Access the board's %s ranges\n",pcMemoryType);
  133.         printf ("-------------------------------------------\n");
  134.         printf ("(Access to invalid %s may hang the computer!)\n", pcMemoryType);
  135.         if (!fLocalAddr)
  136.             printf ("1. Change active memory space: %s\n",PLX_GetAddrRangeName(ad_sp));
  137.         printf ("2. Toggle active mode: %s\n", 
  138.             ad_mode==P9080_MODE_BYTE ? "BYTE (8 bit)" :
  139.             ad_mode==P9080_MODE_WORD ? "WORD (16 bit)" : "DWORD (32 bit)");
  140.         printf ("3. Read from board\n");
  141.         printf ("4. Write to board\n");
  142.         printf ("99. Back to main menu\n");
  143.         printf ("\n");
  144.         printf ("Enter option: ");
  145.         cmd = 0;
  146.         gets (line);
  147.         sscanf (line, "%d",&cmd);
  148.         switch (cmd)
  149.         {
  150.         case 1:
  151.             if (!fLocalAddr)
  152.             {
  153.                 printf ("Choose memory space:\n");
  154.                 printf ("--------------------\n");
  155.                 for (i=P9080_ADDR_SPACE0; i<=P9080_ADDR_EPROM; i++)
  156.                 {
  157.                     printf ("%d. %s", i, PLX_GetAddrRangeName(i));
  158.                     if (P9080_IsAddrSpaceActive(hPlx, i)) printf ("\n");
  159.                     else printf (" - space not active\n");
  160.                 }
  161.                 printf ("Enter option: ");
  162.                 cmd2 = 99;
  163.                 gets (line);
  164.                 sscanf (line, "%d",&cmd2);
  165.                 if (cmd2>=P9080_ADDR_SPACE0 && cmd2<=P9080_ADDR_EPROM)
  166.                 {
  167.                     int new_ad_sp = cmd2;
  168.                     if (P9080_IsAddrSpaceActive(hPlx, new_ad_sp)) ad_sp = new_ad_sp;
  169.                     else printf ("Chosen space not active!\n");
  170.                 }
  171.             }
  172.             break;
  173.         case 2:
  174.             ad_mode = (ad_mode + 1) % 3;
  175.             break;
  176.         case 3:
  177.             printf ("Enter %s to read from: ", pcMemoryType);
  178.             gets (line);
  179.             sscanf (line, "%x", &addr);
  180.             switch (ad_mode)
  181.             {
  182.             case P9080_MODE_BYTE:
  183.                 if (fLocalAddr) data = P9080_ReadByteLocal(hPlx, addr);
  184.                 else data = P9080_ReadByte(hPlx, ad_sp, addr);
  185.                 break;
  186.             case P9080_MODE_WORD:
  187.                 if (fLocalAddr) data = P9080_ReadWordLocal(hPlx, addr);
  188.                 else data = P9080_ReadWord(hPlx, ad_sp, addr);
  189.                 break;
  190.             case P9080_MODE_DWORD:
  191.                 if (fLocalAddr) data = P9080_ReadDWordLocal(hPlx, addr);
  192.                 else data = P9080_ReadDWord(hPlx, ad_sp, addr);
  193.                 break;
  194.             }
  195.             printf ("Value read: %x\n", data);
  196.             break;
  197.         case 4:
  198.             printf ("Enter %s to write to: ", pcMemoryType);
  199.             gets (line);
  200.             sscanf (line, "%x", &addr);
  201.             printf ("Enter data to write %s: ",
  202.                 ad_mode==P9080_MODE_BYTE ? "BYTE (8 bit)" :
  203.                 ad_mode==P9080_MODE_WORD ? "WORD (16 bit)" : "DWORD (32 bit)");
  204.             gets (line);
  205.             sscanf (line, "%x",&data);
  206.             switch (ad_mode)
  207.             {
  208.             case P9080_MODE_BYTE:
  209.                 if (fLocalAddr) P9080_WriteByteLocal(hPlx, addr, (BYTE) data);
  210.                 else P9080_WriteByte(hPlx, ad_sp, addr, (BYTE) data);
  211.                 break;
  212.             case P9080_MODE_WORD:
  213.                 if (fLocalAddr) P9080_WriteWordLocal(hPlx, addr, (WORD) data);
  214.                 else P9080_WriteWord(hPlx, ad_sp, addr, (WORD) data);
  215.                 break;
  216.             case P9080_MODE_DWORD:
  217.                 if (fLocalAddr) P9080_WriteDWordLocal(hPlx, addr, data);
  218.                 else P9080_WriteDWord(hPlx, ad_sp, addr, data);
  219.                 break;
  220.             }
  221.             break;
  222.         }
  223.     } while (cmd!=99);
  224. }
  225.  
  226. void WINAPI PLX_IntHandlerRoutine(P9080_HANDLE hPlx, P9080_INT_RESULT *intResult)
  227. {
  228.     printf ("Got interrupt number %d\n", intResult->dwCounter);
  229. }
  230.  
  231. void PLX_EnableDisableInterrupts(P9080_HANDLE hPlx)
  232. {
  233.     int cmd;
  234.  
  235.     printf ("WARNING!!!\n");
  236.     printf ("----------\n");
  237.     printf ("Your hardware has level sensitive interrupts.\n");
  238.     printf ("You must modify the source code of P9080_IntEnable(), in the file P9080_lib.c,\n");
  239.     printf ("to acknowledge the interrupt before enabling interrupts.\n");
  240.     printf ("Without this modification, your PC will HANG upon interrupt!\n");
  241.  
  242.     do
  243.     {
  244.         printf ("Enable / Disable interrupts\n");
  245.         printf ("---------------------------\n");
  246.         printf ("1. %s interrupts\n", P9080_IntIsEnabled(hPlx) ? "Disable" : "Enable");
  247.         printf ("99. Back to main menu\n");
  248.         printf ("\n");
  249.         printf ("Enter option: ");
  250.         cmd = 0;
  251.         gets (line);
  252.         sscanf (line, "%d",&cmd);
  253.         switch (cmd)
  254.         {
  255.         case 1:
  256.             if (P9080_IntIsEnabled(hPlx))
  257.             {
  258.                 printf ("Disabling interrupt Int\n");
  259.                 P9080_IntDisable(hPlx);
  260.             }
  261.             else
  262.             {
  263.                 printf ("Enabling interrupts\n");
  264.                 if (!P9080_IntEnable(hPlx, PLX_IntHandlerRoutine))
  265.                     printf ("failed enabling interrupts\n");
  266.             }
  267.             break;
  268.         }
  269.     } while (cmd!=99);
  270. }
  271.  
  272. void PLX_EEPROMAccess(P9080_HANDLE hPlx)
  273. {
  274.     int cmd;
  275.     DWORD addr;
  276.     DWORD dwData;
  277.  
  278.     do
  279.     {
  280.         printf ("Access the board's serial EERPOM\n");
  281.         printf ("--------------------------------\n");
  282.         if (!P9080_EEPROMValid(hPlx))
  283.             printf ("Note: PLX EEPROM valid BIT is 0\n");
  284.         printf ("1. Display EEPROM content\n");
  285.         printf ("2. Read dword from serial EEPROM on the board\n");
  286.         printf ("3. Write dword to the serial EEPROM on the board\n");
  287.         printf ("99. Back to main menu\n");
  288.         printf ("\n");
  289.         printf ("Enter option: ");
  290.         cmd = 0;
  291.         gets (line);
  292.         sscanf (line, "%d",&cmd);
  293.         switch (cmd)
  294.         {
  295.         case 1:
  296.             for (addr=0; addr<0xff; addr += 4)
  297.             {
  298.                 if (!(addr % 0x10))
  299.                 printf("\n %02x: ", addr);
  300.                 if (!P9080_EEPROMReadDWord(hPlx, addr, &dwData))
  301.                 {
  302.                     printf("\nError occured reading serial EEPROM - %s\n", P9080_ErrorString);
  303.                     break;
  304.                 }
  305.                 printf("%08x  ", dwData);
  306.             }
  307.             printf ("\n");
  308.             break;
  309.         case 2:
  310.             printf ("Enter addr to read from (0-7f): ");
  311.             gets (line);
  312.             sscanf (line, "%x", &addr);
  313.             if (P9080_EEPROMReadDWord(hPlx, addr, &dwData))
  314.                 printf ("Value read: %08x\n", dwData);
  315.              else
  316.                 printf("Error occured reading serial EEPROM - %s\n", P9080_ErrorString);
  317.             break;
  318.  
  319.         case 3:
  320.             printf ("Enter addr to write to (0-7f): ");
  321.             gets (line);
  322.             sscanf (line, "%x", &addr);
  323.             printf ("Enter data to write: ");
  324.             gets (line);
  325.             sscanf (line, "%x",&dwData);
  326.             if (!P9080_EEPROMWriteDWord(hPlx, addr, dwData))
  327.                 printf("Error occured reading serial EEPROM - %s\n", P9080_ErrorString);
  328.  
  329.             break;
  330.  
  331.         default:
  332.             break;
  333.         }
  334.     } while (cmd!=99);
  335. }
  336.  
  337. P9080_HANDLE PLX_LocateAndOpenBoard(DWORD dwVendorID, DWORD dwDeviceID, BOOL fUseInt)
  338. {
  339.     DWORD cards, my_card;
  340.     DWORD dwOptions = 0;
  341.     P9080_HANDLE hPlx = NULL;
  342.  
  343.     if (dwVendorID==0)
  344.     {
  345.         printf ("Enter VendorID: ");
  346.         gets (line);
  347.         sscanf (line, "%x",&dwVendorID);
  348.         if (dwVendorID==0) return NULL;
  349.  
  350.         printf ("Enter DeviceID: ");
  351.         gets (line);
  352.         sscanf (line, "%x",&dwDeviceID);
  353.     }
  354.     cards = P9080_CountCards (dwVendorID, dwDeviceID);
  355.     if (cards==0) 
  356.     {
  357.         printf("%s", P9080_ErrorString);
  358.         return NULL;
  359.     }
  360.     else if (cards==1) my_card = 1;
  361.     else
  362.     {
  363.         DWORD i;
  364.  
  365.         printf("Found %d matching PCI cards\n", cards);
  366.         printf("Select card (1-%d): ", cards);
  367.         i = 0;
  368.         gets (line);
  369.         sscanf (line, "%d",&i);
  370.         if (i>=1 && i <=cards) my_card = i;
  371.         else 
  372.         {
  373.             printf ("Choice out of range\n");
  374.             return NULL;
  375.         }
  376.     }
  377.  
  378.     if (fUseInt)
  379.         dwOptions |= P9080_OPEN_USE_INT;
  380.  
  381.     dwOptions |= P9080_CS46_EEPROM;
  382.  
  383.     if (P9080_Open (&hPlx, dwVendorID, dwDeviceID, my_card - 1, dwOptions))
  384.         printf ("PLX 9080 PCI card found!\n");
  385.     else printf ("%s", P9080_ErrorString);
  386.     return hPlx;
  387. }
  388.  
  389. int main(int argc, char *argv[])
  390. {
  391.     int cmd;
  392.     P9080_HANDLE hPlx = NULL;
  393.     HANDLE hWD;
  394.     BOOL fUseInt = FALSE; // by default - do not install interrupts
  395.     BOOL fOpenedWithInt = fUseInt;
  396.  
  397.     printf ("PLX 9080 diagnostic utility.\n");
  398.     printf ("Application accesses hardware using " WD_PROD_NAME ".\n");
  399.  
  400.     // make sure WinDriver is loaded
  401.     if (!PCI_Get_WD_handle(&hWD)) return 0;
  402.     WD_Close (hWD);
  403.  
  404.     hPlx = PLX_LocateAndOpenBoard(0x10b5, 0x9080, fUseInt);
  405.  
  406.     do
  407.     {
  408.         printf ("\n");
  409.         printf ("PLX 9080 main menu\n");
  410.         printf ("-------------------\n");
  411.         printf ("1. Scan PCI bus\n");
  412.         printf ("2. Set opening board %s interrupts\n", fUseInt ? "without" : "with");
  413.         printf ("3. Locate/Choose PLX 9080 board (%s interrupts)\n", fUseInt ? "with" : "without");
  414.         if (hPlx)
  415.         {
  416.             printf ("4. PCI configuration registers\n");
  417.             printf ("5. PLX 9080 local registers\n");
  418.             printf ("6. Access address spaces on the board\n");
  419.             printf ("7. Access local address ranges on the board\n");
  420.             if (fOpenedWithInt)
  421.                 printf ("8. Enable / Disable interrupts\n");
  422.             printf ("9. Access serial EEPROM on the board\n");
  423.         }
  424.         printf ("99. Exit\n");
  425.         printf ("Enter option: ");
  426.         cmd = 0;
  427.         gets (line);
  428.         sscanf (line, "%d",&cmd);
  429.         switch (cmd)
  430.         {
  431.         case 1: // Scan PCI bus
  432.             PCI_Print_all_cards_info();
  433.             break;
  434.         case 2: // Set open board with / without interrupts
  435.             fUseInt = !fUseInt;
  436.             break;
  437.         case 3: // Locate PLX 9080 board
  438.             if (hPlx) P9080_Close(hPlx);
  439.             hPlx = PLX_LocateAndOpenBoard(0, 0, fUseInt);
  440.             if (!hPlx) printf ("PLX card open failed!\n");
  441.             fOpenedWithInt = fUseInt;
  442.             break;
  443.         case 4: // PCI configuration registers
  444.             if (hPlx) 
  445.             {
  446.                 WD_PCI_SLOT pciSlot;
  447.                 P9080_GetPciSlot(hPlx, &pciSlot);
  448.                 PCI_EditConfigReg(pciSlot);
  449.             }
  450.             break;
  451.         case 5: // PLX 9080 local registers
  452.             if (hPlx) PLX_EditReg(hPlx);
  453.             break;
  454.         case 6: // Access address spaces on the board
  455.             if (hPlx) PLX_BoardAccess(hPlx, FALSE);
  456.             break;
  457.         case 7: // Access local address ranges on the board
  458.             if (hPlx) PLX_BoardAccess(hPlx, TRUE);
  459.             break;
  460.         case 8: // Enable / Disable interrupts
  461.             if (hPlx && fOpenedWithInt) PLX_EnableDisableInterrupts(hPlx);
  462.             break;
  463.         case 9: // Access serial EEPROM on the board
  464.             if (hPlx) PLX_EEPROMAccess(hPlx);
  465.             break;
  466.         }
  467.     } while (cmd!=99);
  468.  
  469.     if (hPlx) P9080_Close(hPlx);
  470.  
  471.     return 0;
  472. }
  473.  
  474.