Esempio n. 1
0
 public PCIE_Device(DWORD dwVendorId, DWORD dwDeviceId,
                    WD_PCI_SLOT slot)
 {
     m_wdcDevice = new WDC_DEVICE();
     m_wdcDevice.id.pciId.dwVendorId = dwVendorId;
     m_wdcDevice.id.pciId.dwDeviceId = dwDeviceId;
     m_wdcDevice.slot.pciSlot        = slot;
     m_wdcDeviceMarshaler            = new MarshalWdcDevice();
     m_eventHandler = new EVENT_HANDLER_DOTNET(NEWAMD86_EventHandler);
     m_regs         = new PCIE_Regs();
     SetDescription();
     m_dmaMarshaler = new MarshalWdDma();
 }
Esempio n. 2
0
        public void ReadDMA(uint uLocalAddr, uint dwBytes, ref IntPtr data)
        {
            //开DMA Buffer

            IntPtr pDMA = IntPtr.Zero;

            wdc_lib_decl.WDC_DMAContigBufLock(this.Handle, ref data, (uint)WD_DMA_OPTIONS.DMA_FROM_DEVICE, dwBytes, ref pDMA);

            MarshalWdDma m_wdDmaMarshaler = new MarshalWdDma();
            WD_DMA       dma = (WD_DMA)m_wdDmaMarshaler.MarshalNativeToManaged(pDMA);

            //配置buffer的物理地址到DSP的outbound

            wdc_lib_decl.WDC_WriteAddr32(this.Handle, 0, 0x30, 0x0); // 1MB outbound translation size
            uint pageBase = (uint)(dma.Page[0].pPhysicalAddr & 0x100000);

            wdc_lib_decl.WDC_WriteAddr32(this.Handle, 0, 0x200, pageBase | 0x1);
            wdc_lib_decl.WDC_WriteAddr32(this.Handle, 0, 0x204, 0x0);

            //将EDMA配置空间(0x02700000)映射到DSP的IB_OFFSET(3),以便于PC控制DSP的EDMA

            wdc_lib_decl.WDC_WriteAddr32(this.Handle, 0, 0x33C, 0x02700000);

            /* EDMA registers */
            //#define EDMA_TPCC0_BASE_ADDRESS      0x02700000
            //#define DMAQNUM0                     0x0240
            //#define ESR                          0x1010
            //#define EESR                         0x1030
            //#define IESR                         0x1060
            //#define IPR                          0x1068
            //#define ICR                          0x1070
            //#define PARAM_0_OPT                  0x4000
            //#define PARAM_0_SRC                  0x4004
            //#define PARAM_0_A_B_CNT              0x4008
            //#define PARAM_0_DST                  0x400C
            //#define PARAM_0_SRC_DST_BIDX         0x4010
            //#define PARAM_0_LINK_BCNTRLD         0x4014
            //#define PARAM_0_SRC_DST_CIDX         0x4018
            //#define PARAM_0_CCNT                 0x401C
            //#define PCIE_DATA                    0x60000000
            //#define DMA_TRANSFER_SIZE            0x400000   /* 4MB */

            /* Payload size in bytes over PCIE link. PCIe module supports
             * outbound payload size of 128 bytes and inbound payload size of 256 bytes */
            //#define PCIE_TRANSFER_SIZE           0x80

            ///* For 1MB outbound translation window size */
            //#define PCIE_ADLEN_1MB               0x00100000
            //#define PCIE_1MB_BITMASK             0xFFF00000

            //启动DMA传输
            while (true)
            {
                /* Use TC0 for DBS = 128 bytes */
                wdc_lib_decl.WDC_WriteAddr32(this.Handle, 3, 0x0240, 0x0);

                //* Set the interrupt enable for 1st Channel (IER). */
                wdc_lib_decl.WDC_WriteAddr32(this.Handle, 3, 0x1060, 0x1);

                //* Clear any pending interrupt (IPR). */
                wdc_lib_decl.WDC_WriteAddr32(this.Handle, 3, 0x1070, 0x1);

                //* Populate the Param entry. */
                wdc_lib_decl.WDC_WriteAddr32(this.Handle, 3, 0x4000, 0x00100004);    /* Enable SYNCDIM and TCINTEN, TCC = 0 */

                //* Calculate the DSP PCI address for the PC address */
                uint tmp = (uint)(0x60000000 + (dma.Page[0].pPhysicalAddr & ~0xFFF00000));
                wdc_lib_decl.WDC_WriteAddr32(this.Handle, 3, 0x400C, tmp);//dst address目标地址

                //PARAM_0_A_B_CNT
                wdc_lib_decl.WDC_WriteAddr32(this.Handle, 3, 0x4008, 0x10000 | dwBytes);

                //PARAM_0_SRC
                wdc_lib_decl.WDC_WriteAddr32(this.Handle, 3, 0x4004, (DWORD)uLocalAddr);//src address 源地址

                wdc_lib_decl.WDC_WriteAddr32(this.Handle, 3, 0x4010, ((0x80 << 16) | 0x80));
                wdc_lib_decl.WDC_WriteAddr32(this.Handle, 3, 0x4014, 0xFFFF);
                wdc_lib_decl.WDC_WriteAddr32(this.Handle, 3, 0x4018, 0x0);

                //* C Count is set to 1 since mostly size will not be more than 1.75GB */
                wdc_lib_decl.WDC_WriteAddr32(this.Handle, 3, 0x401C, 0x1);

                //* Set the Event Enable Set Register. */
                wdc_lib_decl.WDC_WriteAddr32(this.Handle, 3, 0x1030, 0x1);

                //* Set the event set register. */
                wdc_lib_decl.WDC_WriteAddr32(this.Handle, 3, 0x1010, 0x1);

                //等待dma结束
                while (true)
                {
                    wdc_lib_decl.WDC_ReadAddr32(this.Handle, 3, 0x1068, ref tmp);
                    if ((tmp & 0x1) == 1)
                    {
                        break;
                    }
                }
                break;
            }
            //恢复inbound配置
            wdc_lib_decl.WDC_WriteAddr32(this.Handle, 0, 0x33C, 0x80000000);
        }