📄 pci.c
字号:
MCF_PCI_PCICAR = (MCF_PCI_PCICAR & 0xFFFFFF00) + 0x08; device->classCode = (uint8)(((swap32(*(uint32*)PCI_HOST_CFG)) & 0xFF000000)>>24); device->subClass = (uint8)(((swap32(*(uint32*)PCI_HOST_CFG)) & 0x00FF0000)>>16); device->progIf = (uint8)(((swap32(*(uint32*)PCI_HOST_CFG)) & 0x0000FF00)>>8); device->revisionId = (uint8)(((swap32(*(uint32*)PCI_HOST_CFG)) & 0x000000FF)); MCF_PCI_PCICAR = (MCF_PCI_PCICAR & 0xFFFFFF00) + 0x0C; device->bist = (uint8)(((swap32(*(uint32*)PCI_HOST_CFG)) & 0xFF000000)>>24); device->headerType = (uint8)(((swap32(*(uint32*)PCI_HOST_CFG)) & 0x00FF0000)>>16); device->latency = (uint8)(((swap32(*(uint32*)PCI_HOST_CFG)) & 0x0000FF00)>>8); device->cacheLine = (uint8)(((swap32(*(uint32*)PCI_HOST_CFG)) & 0x000000FF)); MCF_PCI_PCICAR = (MCF_PCI_PCICAR & 0xFFFFFF00) + 0x10; device->base0 = swap32(*(uint32*)PCI_HOST_CFG); MCF_PCI_PCICAR = (MCF_PCI_PCICAR & 0xFFFFFF00) + 0x14; device->base1 = swap32(*(uint32*)PCI_HOST_CFG); MCF_PCI_PCICAR = (MCF_PCI_PCICAR & 0xFFFFFF00) + 0x18; device->base2 = swap32(*(uint32*)PCI_HOST_CFG); MCF_PCI_PCICAR = (MCF_PCI_PCICAR & 0xFFFFFF00) + 0x1C; device->base3 = swap32(*(uint32*)PCI_HOST_CFG); MCF_PCI_PCICAR = (MCF_PCI_PCICAR & 0xFFFFFF00) + 0x20; device->base4 = swap32(*(uint32*)PCI_HOST_CFG); MCF_PCI_PCICAR = (MCF_PCI_PCICAR & 0xFFFFFF00) + 0x24; device->base5 = swap32(*(uint32*)PCI_HOST_CFG); MCF_PCI_PCICAR = (MCF_PCI_PCICAR & 0xFFFFFF00) + 0x2C; device->cis = swap32(*(uint32*)PCI_HOST_CFG); MCF_PCI_PCICAR = (MCF_PCI_PCICAR & 0xFFFFFF00) + 0x2C; device->subSystemId= (uint16)(((swap32(*(uint32*)PCI_HOST_CFG)) & 0xFFFF0000)>>16); device->subVendorId= (uint16)(((swap32(*(uint32*)PCI_HOST_CFG)) & 0x0000FFFF)); MCF_PCI_PCICAR = (MCF_PCI_PCICAR & 0xFFFFFF00) + 0x30; device->romBase = swap32(*(uint32*)PCI_HOST_CFG); MCF_PCI_PCICAR = (MCF_PCI_PCICAR & 0xFFFFFF00) + 0x3C; device->maxLatency = (uint8)(((swap32(*(uint32*)PCI_HOST_CFG)) & 0xFF000000)>>24); device->minGrant = (uint8)(((swap32(*(uint32*)PCI_HOST_CFG)) & 0x00FF0000)>>16); device->intPin = (uint8)(((swap32(*(uint32*)PCI_HOST_CFG)) & 0x0000FF00)>>8); device->intLine = (uint8)(((swap32(*(uint32*)PCI_HOST_CFG)) & 0x000000FF)); #endif } else { /* it is empty: clear IA bit */ MCF_PCI_PCIISR |= MCF_PCI_PCIISR_IA; targ1 = PCI_NO_DEV; return PCI_NO_DEV; } return PCI_OK;}/*** ===================================================================** Function : printpciheaderinfo**** Description : Print out PCI header info**** Parameters** ---------- ** -slot : Slot number (also the IDSEL AD line).**** Return Value : none** ** ===================================================================*/void printpciheaderinfo(int slot){ int i; pci_device device; char *vendorshort, *vendorfull; char *devname, *devdesc; char *basedesc, *subdesc, *progdesc; uint32 baseaddr[6]; uint32 tmp, memsize; printf ("PCI IDSEL AD%d\n", slot); if (PCI_OK == pciGetConfHeader (slot, 0, &device)) {#ifdef PCI_TEST_SMALL printf("Device Detected \n");#else if (PCI_OK != pciGetVendorName (&device, &vendorshort, &vendorfull)) { printf ("Vendor: 0x%04X (vendor not found in data base)\n", device.vendorId); } else { printf ("Vendor: %s - %s (0x%04X)\n", vendorshort, vendorfull, device.vendorId); } if (PCI_OK != pciGetDevName (&device, &devname, &devdesc)) { printf ("Device: 0x%04X (device not found in data base)\n", device.deviceId); } else { printf ("Device: %s - %s (0x%04X)\n", devname, devdesc, device.deviceId); } if (PCI_OK != pciGetClassName (&device, &basedesc, &subdesc, &progdesc)) { printf ("Class: 0x%02X (class not found in data base)\n", device.classCode); printf ("Sub-Class: 0x%02X (sub-class not found in data base)\n", device.subClass); printf ("Prog. I/F: 0x%02X (prog. i/f not found in data base)\n", device.progIf); } else { printf ("Class: %s (0x%02X)\n", basedesc, device.classCode); printf ("Sub-Class: %s (0x%02X)\n", subdesc, device.subClass); printf ("Prog. I/F: %s (0x%02X)\n", progdesc, device.progIf); } printf ("Silicon Revision: 0x%02X\n", device.revisionId); printf ("Status Register: 0x%04X\n", device.status); printf ("Command Register: 0x%04X\n", device.command); printf ("BIST: 0x%02X\n", device.bist); printf ("Header Type: 0x%02X\n", device.headerType); printf ("Latency Timer: 0x%02X\n", device.latency); printf ("Cache Line Size: 0x%02X\n", device.cacheLine); baseaddr[0] = device.base0; baseaddr[1] = device.base1; baseaddr[2] = device.base2; baseaddr[3] = device.base3; baseaddr[4] = device.base4; baseaddr[5] = device.base5; for (i=0; i<6; i++) { printf("BAR%d ", i); if (baseaddr[i] !=0) { // Memory vs I/O space if (baseaddr[i] & 0x00000001UL) { printf("points to: I/O space, "); } else { printf("points to: Memory space, "); } // Decoder Type switch (baseaddr[i] & 0x00000006UL) { case 2: printf("\n\t\t must be located below 1 MB\n"); break; case 4: printf("\n\t\t 64 bit decoder\n"); break; case 6: printf("\n\t\t RESERVED CONFIGURATON\n"); break; default: printf("\n\t\t 32 bit decoder\n"); break; } // Memory is prefetchable? if(baseaddr[i] & 0x00000008UL) { printf("\t\t Prefetchable "); } else { printf("\t\t Non-Prefetchable "); } // Get Memory Size /* Form config address for 'slot' */ MCF_PCI_PCICAR = (0 | MCF_PCI_PCICAR_DEVNUM(slot)| MCF_PCI_PCICAR_FUNCNUM(0)| MCF_PCI_PCICAR_BUSNUM(0)| MCF_PCI_PCICAR_E); MCF_PCI_PCICAR = (MCF_PCI_PCICAR & 0xFFFFFF00) + 0x10 + (i*4); /* get BAR */ tmp = *(uint32*)PCI_HOST_CFG; /* write BAR will all F's */ *(uint32*)PCI_HOST_CFG = swap32(0xFFFFFFF0); /* Read Back BAR to see what Mem size we have */ memsize = (~(swap32(*(uint32*)PCI_HOST_CFG)&0xFFFFFFF0))+0x1; if(memsize < 1024) printf("\n\t\t Size = %d Bytes ", memsize); else if(memsize < 0x00100000) { printf("\n\t\t Size = %d KBytes ", (memsize>>10)); } else { printf("\n\t\t Size = %d MBytes ", (memsize>>20)); } /* put back BAR */ *(uint32*)PCI_HOST_CFG = tmp; /* put back the PCICAR */ MCF_PCI_PCICAR &= ~(MCF_PCI_PCICAR_E); // Raw contents printf ("\n\t\t @ PCI address 0x%08X\n", baseaddr[i]); } else { printf("is not implemented\n"); } }#endif } else { printf ("No PCI device detected on IDSEL AD%d\n", slot); } printf ("\n\n");} #if 0//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////// DMA ///////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /*** ===================================================================** Function : init_pci_dma**** Description : initializes the DMA API and sets up DMA Interrupts**** Parameters : none** ** Return Value: none** ** ===================================================================*/void init_pci_dma(void){ int result,i; /* enable some DMA interrupts */ dma_irq_enable(3,3); /* set the channel for the TX DMA */ dma_set_channel(DMA_PCI_TX,pci_dma_tx_handler); /* set the channel for the RX DMA */ dma_set_channel(DMA_PCI_RX,pci_dma_rx_handler); /* Set-up TX DMA task */ result = MCD_initDma ((dmaRegs*)(MBAR_ADDRESS+0x8000), (void *)SYS_SRAM_ADDRESS, 0 | MCD_RELOC_TASKS); if(result != MCD_OK) { /* There was a problem */ printf("error: MCD_initDma\n" ); } }/*** ===================================================================**** THIS FUNCTION SHOULD NOT BE USED, FOR TEST ONLY** --please use 'pci_start_dma_tx' ****** Function : pci_dma_tx**** Description : Transmit data from CF memory to PCI memory space ** using the DMA**** Parameters** ---------- ** -source : Pointer to source address in ColdFire memory space.** Must be longword aligned.** -destination: Pointer to destination address in PCI memory space.** Must be longword aligned.** -length : Length in Bytes to tansmit, must be in longword ** increments**** Return Value: none** ** ===================================================================*/void pci_dma_tx(uint8* source, uint8* destination, uint32 length){ int result,i; int pkt_start =0; int pkt_done =0; uint32 index = 0; int test; /* Set-up TX FIFO's */ /* Hold Tx controller at reset */ MCF_PCI_PCITER |= MCF_PCI_PCITER_RC; /* Set PCI Command, Max_Retries, and Max_Beats */ /* MCF_PCI_PCITTCR = MCF_PCI_PCITTCR_PCICMD(0x7); same as default out of reset */ /* Set Mode, Continuous or Non-continuous */ MCF_PCI_PCITER |= MCF_PCI_PCITER_CM; /* Reset FIFO */ MCF_PCI_PCITER |= MCF_PCI_PCITER_RF; for(i=0;i<100;i++); /* wait */ MCF_PCI_PCITER &= ~(0|MCF_PCI_PCITER_RF); /* Set the FIFO Alarm and Granularity Fields */ MCF_PCI_PCITFCR |= MCF_PCI_PCITFCR_GR(4); /* high water mark = 128 bytes -(4*4) = 16 bytes free in the FIFO */ MCF_PCI_PCITFAR |= MCF_PCI_PCITFAR_ALARM(32); /* low water mark = 16 bytes */ /* Set Master Enable Bit and some error stuff*/ MCF_PCI_PCITER |= MCF_PCI_PCITER_IAE | MCF_PCI_PCITER_TAE | MCF_PCI_PCITER_ME; /* Configure PCI destination */ MCF_PCI_PCITSAR = (uint32)destination; /* Set the Reset Controller bit Low */ MCF_PCI_PCITER &= ~(MCF_PCI_PCITER_RC); /* Clear the NT bit in the PCITSR */ MCF_PCI_PCITSR |= MCF_PCI_PCITSR_NT; while(index < length) { /* Write Packet Size value to begin the transfer if length is < max packet size*/ if((length-index) <= PCI_MAX_PKT_SIZE) { /* Make sure I've completed the packet from before (if there was one) by checking the NT bit in the PCITSR */ while(pkt_start > pkt_done) { if(MCF_PCI_PCITSR&MCF_PCI_PCITSR_NT) { /* increment the packets done */ pkt_done++; /* Clear the NT bit in the PCITSR */ MCF_PCI_PCITSR |= MCF_PCI_PCITSR_NT; } } MCF_PCI_PCITPSR = MCF_PCI_PCITPSR_PKTSIZE(length-index); /* size of length*/ pkt_start++; /* Stuff FIFO */ /* kick off DMA */ result = MCD_startDma(dma_get_channel(DMA_PCI_TX), /* channel */ (s8*)source, /* source buffer address */ 4, /* source increment */ (s8*)(MBAR_ADDRESS+0x8440), /* destination buffer address */ 0, /* destination increment */ length-index, /* number of bytes to transfer */ 4, /* width of transfers */ dma_get_initiator(DMA_PCI_TX), /* initiator to use PCI Tx*/ 5, /* priority */ 0 | MCD_SINGLE_DMA, 0 | MCD_NO_CSUM | MCD_NO_BYTE_SWAP);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -