sysPci.c
上传用户:yingyi0918
上传日期:2022-06-26
资源大小:214k
文件大小:12k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* sysBusPci.c - IDT 79RC32438 PCI autoconfig support.  */
  2. /* Copyright 1984-2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5.  * This file has been developed or significantly modified by the
  6.  * MIPS Center of Excellence Dedicated Engineering Staff.
  7.  * This notice is as per the MIPS Center of Excellence Master Partner
  8.  * Agreement, do not remove this notice without checking first with
  9.  * WR/Platforms MIPS Center of Excellence engineering management.
  10.  */
  11. /*
  12. modification history
  13. --------------------
  14.  
  15. 01a,12jun02,krao  written
  16. */
  17. /*
  18. DESCRIPTION
  19. This module contains the "non-generic" or "board specific" PCI 
  20. initialization code, including initializing the PCI Host bridge, re-mapping
  21. PCI access regions with the TLB, and initiating PCI auto-config.
  22. It is assumed that this file is include by sysLib.c.
  23. */
  24. /* includes */
  25. #include "vxWorks.h"
  26. #include "logLib.h"
  27. #include "taskLib.h"
  28. #include "config.h"
  29. #include "drv/pci/pciAutoConfigLib.h"
  30. /* defines */
  31. /* typedefs */
  32. /* globals */
  33. /* externals */
  34. IMPORT void     sysSetPageSize () ;
  35. IMPORT void     sysSetTlbEntry () ;
  36. /* locals */
  37. LOCAL  PCI_SYSTEM sysParams;
  38. /* forward declarations */
  39. LOCAL void      sysPciTlbInit ();
  40. LOCAL void      sysPciHostBridgeInit ();
  41. /* subroutines */
  42. /***************************************************************************
  43. *
  44. * sysPciTlbInit - Initialize the TLB for the PCI->CPU Memory Windows
  45. *
  46. * The RC32334 has fixed physical memory windows for CPU->PCI memory and I/O
  47. * access. Two of the memory windows are in kuseg (4000_0000 and 6000_0000).
  48. * To better support vxWorks AE in the future, the TLB is employed to map
  49. * these regions into kseg2 virtual addresses.
  50. *
  51. * RETURNS: N/A
  52. */
  53. LOCAL void sysPciTlbInit (void)
  54.     {
  55.     UINT32 tlbAttrib;           /* TLB page attribute */
  56.     UINT32 tlbHi;               /* TLB Hi register value */
  57.     UINT32 tlbLo0;              /* TLB Lo0 register value */
  58.     UINT32 tlbLo1;              /* TLB Lo1 register value */
  59.     UINT32 pageSize;            /* Page size of mapped memory */
  60.     UINT32 pageFrame;           /* Page frame portion of TLB Lo regs */
  61.     UINT32 tlbInx;              /* TLB index */
  62.     /* Set Page size to 16 Mb. */
  63.     
  64.     pageSize = PCI_MMU_PAGEMASK;
  65.     pageSize = (pageSize << (PAGEMASK_SHIFT));
  66.     sysSetPageSize (pageSize);
  67.     
  68.     /* Uncached, Dirty, Global and Valid MMU page */
  69.     
  70.     tlbAttrib = PCI_MMU_PAGEATTRIB; 
  71.     /*
  72.      * MMU mapping for PCI_MEMORY_SPACE1
  73.      * Map 16MB pages
  74.      * Virtual 0xE0000000-0xE0ffffff to Physical 0x40000000 - 0x40ffffff
  75.      * Virtual 0xE1000000-0xE1ffffff to Physical 0x41000000 - 0x41ffffff
  76.      */
  77.     tlbHi = PCI_MEMORY_SPACE1_VIRT ;       /* VPN2:VirtualPageframeNumber%2 */
  78.     tlbHi = (tlbHi & TLB_HI_MASK);
  79.     pageFrame = PCI_MEMORY_SPACE1_PHYS;
  80.     pageFrame = pageFrame >> TLB_LO_SHIFT; /* Even PFN:Page Frame Number    */
  81.     tlbLo0 = pageFrame;
  82.     tlbLo0 = (tlbLo0 | tlbAttrib);
  83.     tlbLo0 = (tlbLo0 & TLB_LO_MASK);
  84.     pageFrame = (PCI_MEMORY_SPACE1_PHYS | PCI_TLB_PAGE_SIZE);
  85.     pageFrame = pageFrame >> TLB_LO_SHIFT ; /* Odd PFN:Page Frame Number     */
  86.     tlbLo1 = pageFrame;
  87.     tlbLo1 = (tlbLo1 | tlbAttrib);
  88.     tlbLo1 = (tlbLo1 & TLB_LO_MASK);
  89.     tlbInx = 0;
  90.     
  91.     sysSetTlbEntry (tlbInx, tlbHi, tlbLo0, tlbLo1);
  92.     /*
  93.      * MMU mapping for PCI_MEMORY_SPACE2
  94.      * Virtual 0xF0000000-0xF0ffffff to Physical 0x60000000 - 0x60ffffff
  95.      * Virtual 0xF1000000-0xF1ffffff to Physical 0x61000000 - 0x61ffffff
  96.      */
  97.     tlbHi = PCI_MEMORY_SPACE2_VIRT;        /* VPN2 */
  98.     tlbHi = (tlbHi & TLB_HI_MASK);
  99.     pageFrame = PCI_MEMORY_SPACE2_PHYS;
  100.     pageFrame = pageFrame >> TLB_LO_SHIFT; /* Even PFN */
  101.     tlbLo0 = pageFrame;
  102.     tlbLo0 = (tlbLo0 | tlbAttrib);
  103.     tlbLo0 = (tlbLo0 & TLB_LO_MASK);
  104.     pageFrame = (PCI_MEMORY_SPACE2_PHYS | PCI_TLB_PAGE_SIZE );
  105.     pageFrame = pageFrame >> TLB_LO_SHIFT; /* Odd PFN */
  106.     tlbLo1 = pageFrame;
  107.     tlbLo1 = (tlbLo1 | tlbAttrib);
  108.     tlbLo1 = (tlbLo1 & TLB_LO_MASK);
  109.     tlbInx = 1;
  110.     
  111.     sysSetTlbEntry (tlbInx, tlbHi, tlbLo0, tlbLo1);
  112.     }
  113. /***************************************************************************
  114. *
  115. * sysPciHostBridgeInit - Initialize RC32438 PCI host bridge 
  116. *
  117. * RETURNS: N/A
  118. */
  119. LOCAL void  sysPciHostBridgeInit (void)
  120.     {
  121.     int             loopCount = 0;
  122.     volatile UINT32 pcicValue = 0;
  123.     volatile UINT32 pcicData  = 0;
  124.     volatile UINT32 dummyRead = 0;
  125.     volatile UINT32 pciCntlVal;
  126.     volatile UINT32 pciConfigAddr;
  127.     unsigned int IDT32438CnfgRegs[25] = {
  128.                                 IDT32438_CNFG0,
  129.                                 IDT32438_CNFG1,
  130.                                 IDT32438_CNFG2,
  131.                                 IDT32438_CNFG3,
  132.                                 IDT32438_CNFG4,   
  133.                                 IDT32438_CNFG5,
  134.                                 IDT32438_CNFG6,
  135.                                 IDT32438_CNFG7,
  136.                                 IDT32438_CNFG8,
  137.                                 IDT32438_CNFG9,
  138.                                 IDT32438_CNFG10,
  139.                                 IDT32438_CNFG11,
  140.                                 IDT32438_CNFG12,
  141.                                 IDT32438_CNFG13,
  142.                                 IDT32438_CNFG14,
  143.                                 IDT32438_CNFG15,
  144.                                 IDT32438_CNFG16,
  145.                                 IDT32438_CNFG17,
  146.                                 IDT32438_CNFG18,
  147.                                 IDT32438_CNFG19,
  148.                                 IDT32438_CNFG20,
  149.                                 IDT32438_CNFG21,                          
  150.                                 IDT32438_CNFG22,
  151.                                 IDT32438_CNFG23,
  152.                                 IDT32438_CNFG24
  153.                                 };
  154.     
  155.                                
  156.     
  157.     pcicValue = PCI.pcic;
  158.     pcicValue = (pcicValue >> PCIM_SHFT) & PCIM_BIT_LEN;
  159.     if (!((pcicValue == PCIM_H_EA) ||
  160.          (pcicValue == PCIM_H_IA_FIX) ||
  161.          (pcicValue == PCIM_H_IA_RR)))
  162.         {
  163.                 
  164.         /* Not in Host mode, return ERROR */
  165.                           
  166.         }
  167.         
  168.   
  169.     /*
  170.      * Enable the PCI, while doing so also enable the Idle Grant mode & Enable 
  171.      * Arbiter Parking      
  172.      */
  173.      
  174.     pcicData = PCI.pcic;    
  175.     pcicData |= (PCIC_IGM |PCIC_EAP  |PCIC_EN);
  176.     PCI.pcic = pcicData;       
  177.       
  178.     /*
  179.      * Check if the reset is done by looking at the PCI status Reset in Progress     */
  180.        
  181.     for( ; ; )    
  182.         {
  183.         pcicData = PCI.pcis ;
  184.         if( !(pcicData & PCIS_RIP) )
  185.             break ;
  186.         } 
  187.              
  188.     /* Zero out the PCI status  */
  189.       
  190.  
  191.     PCI.pcis    = 0;
  192.     PCI.pcism   = 0xFFFFFFFF;
  193.     PCI.pcidac  = 0;           /* disable PCI decoupled accesses at */
  194.                                /* initialization */
  195.     PCI.pcidas  = 0;           /* clear the status */
  196.     PCI.pcidasm = 0x0000007F;  /* Mask all the interrupts */
  197.  
  198.     PCI_MSG.pciiic = 0;
  199.     PCI_MSG.pciiim = 0xFFFFFFFF;
  200.     PCI_MSG.pcioic = 0;
  201.     PCI_MSG.pcioim = 0;  
  202.  
  203.         
  204.     
  205.  
  206.      /* Setup PCILB0 as Memory Window */
  207.            
  208.     PCI.pcilba0 = (UINT32)PCI_MEMORY_SPACE1_PHYS;
  209.     
  210.      /* flush the CPU write Buffers */    
  211.  
  212.     /* setup the PCI map address as same as the local address */
  213.         
  214.     PCI.pcilba0m = (UINT32)(CPU_TO_PCI_MEM_BASE1);
  215.     
  216.      /* flush the CPU write Buffers */     
  217.     /* setup the PCI address window */
  218.               
  219.     /* Setup PCILBA1 as MEM Window */
  220.    
  221.     PCI.pcilba0c   = (PCILBAXC_SB|PCILBAXC_SIZE(SIZE_128MB));
  222.     dummyRead      = PCI.pcilba0c; /* flush the CPU write Buffers */ 
  223.  
  224.     
  225.     PCI.pcilba1  = (UINT32) PCI_MEMORY_SPACE2_PHYS;
  226.     PCI.pcilba1m = (UINT32) ( PCI_MEMORY_SPACE2_VIRT);
  227.     
  228.     PCI.pcilba1c = (PCILBAXC_SIZE(SIZE_1MB) | PCILBAXC_SB );
  229.     dummyRead    = PCI.pcilba1c; /* flush the CPU write Buffers */
  230.   
  231.     /* Setup PCILBA2 as IO */
  232.         
  233.     PCI.pcilba2  = (UINT32) 0x0;
  234.     PCI.pcilba2m = (UINT32) 0x0;        
  235.     PCI.pcilba2c = (UINT32) 0x0;    
  236.     dummyRead    = PCI.pcilba2c; /* flush the CPU write Buffers */
  237.     
  238.  
  239.     /* Setup PCILBA3 as IO Window */
  240.         
  241.     
  242.     PCI.pcilba3  = (UINT32) (PCI_IO_SPACE1_PHYS);
  243.     PCI.pcilba3m = (UINT32) (PCI_IO_SPACE1_VIRT);;
  244.     PCI.pcilba3c = (PCILBAXC_SIZE(SIZE_1MB) | PCILBAXC_MSI | PCILBAXC_SB);
  245.     dummyRead    = PCI.pcilba3c; /* flush the CPU write Buffers */
  246.                                   
  247.   
  248.  
  249.     /* Proceed with Host Bridge PCI Configuration register setting */
  250.       
  251.     pciConfigAddr = (UINT32)IDT32438_CONFIG0_ADDR;
  252.     for (loopCount = 0; loopCount < 25; loopCount++)
  253.         {
  254.         PCI.pcicfga   = pciConfigAddr;
  255.         dummyRead     = PCI.pcicfga;
  256.         PCI.pcicfgd   = IDT32438CnfgRegs[loopCount];
  257.         dummyRead     = PCI.pcicfgd;
  258.         pciConfigAddr += 4;
  259.         }
  260.  
  261.     /* Reset the target not ready bit in the PCI control register */
  262.     
  263.     pciCntlVal  =  PCI.pcic;
  264.     pciCntlVal  &= ~(PCIC_TNR);
  265.     PCI.pcic    =  pciCntlVal;
  266.     
  267.  
  268.     }
  269.  
  270. /******************************************************************************
  271. *
  272. * sysPciAutoConfigInclude - Determine if function is to be autoConfigured
  273. *
  274. * This function is called with PCI bus, device, function, and vendor 
  275. * information.  It returns an indication of whether or not the particular
  276. * function should be included in the automatic configuration process.
  277. * This capability is useful if it is desired that a particular function
  278. * NOT be automatically configured.  Of course, if the device is not
  279. * included in automatic configuration, it will be unusable unless the
  280. * user's code made provisions to configure the function outside of the
  281. * the automatic process.
  282. *
  283. * RETURNS: OK if device is to be included in automatic configuration,
  284. *          ERROR otherwise.
  285. */
  286. LOCAL STATUS sysPciAutoConfigInclude
  287.     (
  288.     PCI_SYSTEM *pSys, /* input: AutoConfig system information       */
  289.     PCI_LOC *pciLoc, /* input: PCI address of this function        */
  290.     UINT     devVend /* input: Device/vendor ID number             */
  291.     )
  292.     {
  293.     BOOL retVal = OK;           /* default to included                        */
  294.  
  295.     switch (devVend)
  296. {
  297. /* Exclude the RC32438 host bridge from auto-config */
  298. case IDT32438_DEV_VEND:
  299.     retVal = ERROR;
  300.     break;
  301. default:
  302.     retVal = OK;
  303.     break;
  304. }
  305.     return retVal;
  306.     }
  307. /*******************************************************************************
  308. * sysPciAutoConfig - PCI autoConfig support routine
  309. *
  310. * This routine instantiates the PCI_SYSTEM structure needed to configure
  311. * the system, calls pciAutoConfig to perform the configuration, and
  312. * then calls device-specific PCI initialization routines.
  313. *
  314. * RETURNS: N/A
  315. */
  316. void sysPciAutoConfig (void)
  317.     {
  318.     
  319.      
  320.     /* Configuration space parameters */
  321.     sysParams.cacheSize = IDT32438_CACHE_LINE_SIZE;
  322.     sysParams.maxLatency = PCI_MAX_LATENCY;
  323.     sysParams.autoIntRouting = TRUE;
  324.     sysParams.includeRtn = sysPciAutoConfigInclude;
  325.     sysParams.intAssignRtn = NULL;
  326.     sysParams.bridgePreConfigInit = NULL;
  327.     sysParams.bridgePostConfigInit = NULL;
  328.     /* Configure the memory ranges for the PCI spaces */
  329.     /* 32-bit Non-prefetchable Memory Space */
  330.  
  331.     sysParams.pciMemIo32 = CPU_TO_PCI_MEM_BASE1;
  332.     sysParams.pciMemIo32Size = CPU_TO_PCI_MEM_SIZE1;
  333.     /* 32-bit Prefetchable Memory Space
  334.      * From the CPU's perspective, this memory area has the same
  335.      * attributes as the "non-prefectable", above. (see sysPciTlbInit()).
  336.      * No caching is enabled, and no prefetching actually occurs.
  337.      * The initialization of these fields in the parameter structure
  338.      * is simply to allow PCI auto-config to utilize this memory.
  339.      */
  340.     sysParams.pciMem32 = CPU_TO_PCI_MEM_BASE2;
  341.     sysParams.pciMem32Size = CPU_TO_PCI_MEM_SIZE2;
  342.     /* 16-bit ISA I/O Space - First block of memory in the I/O space */
  343.     sysParams.pciIo16 = CPU_TO_PCI_IO_BASE;
  344.     sysParams.pciIo16Size = CPU_TO_PCI_IO16_SIZE;
  345.     /* 32-bit PCI I/O Space - Remaining memory in the I/O space */
  346.  
  347.     sysParams.pciIo32 = CPU_TO_PCI_IO_BASE + CPU_TO_PCI_IO16_SIZE;
  348.     sysParams.pciIo32Size = CPU_TO_PCI_IO_SIZE - CPU_TO_PCI_IO16_SIZE;
  349.  
  350.     /* Perform autoconfiguration */
  351.      sysPciBusErrDisable (); 
  352.      pciAutoConfig (&sysParams);
  353.     
  354.      sysPciBusErrEnable (); 
  355.     /* Now configure devices that were exposed by the autoconfig... */
  356. #if defined (INCLUDE_FEI_END)
  357.     sys557PciInit ();
  358. #endif
  359.     }