Пример #1
0
        public int Arm(IdeRequest !ideRequest)
        {
            byte value = BUSMASTER_CONTROL_MASK_START;

            if (ideRequest.Command == IdeCmdType.Read)
            {
                value |= BUSMASTER_CONTROL_MASK_WRITE;
            }
            commandPort.Write8(value);  // enable BM
            return(0);
        } // BmArm
Пример #2
0
        public void BmPrepareController(IdeRequest !ideRequest)
        {
            // Perform steps 1 and 2 above: set up PRD, clear
            // error snd interrupt

            // Init. Scatter Gather List Register
            uint thePrd = FillPrdTable(ideRequest);

            prdPort.Write32(thePrd);

            // Clear Errors
            byte status = (byte)(BUSMASTER_STATUS_MASK_INTERRUPT | BUSMASTER_STATUS_MASK_ERROR);

            statusPort.Write8(status);

            return;
        } // BmPrepareController
Пример #3
0
        private uint FillPrdTable(IdeRequest !ideRequest)
        {
            // given a memory address and a length generate
            // a Physical Region Descriptor Table (PDRT) to be used
            // in a IDE busmaster DMA transfer

            //a PRDT table is an array of PRD entries, each 8 bytes in
            //length. There is no count associated with this structure
            // Bit 7 of the last byte of the last entry signifies the
            //end of the table

            // PRD (Physical Region Descriptor)
            // the first 4 bytes of a PRD specify the memory address
            // Bytes 5 and 6 (16 bits) specify the length.
            // At most a PRD can specify a transfer of 64KB.
            // The memory specified by a PRD cannot cross a 64KB boundary
            // Any transfer that would cross such a boundary needs to be
            // split into to separate PRDs

            uint addr = (uint)((UIntPtr)ideRequest.BufferAddress + ideRequest.BufferOffset);
            uint len  = (uint)ideRequest.Length;

            // Write a bad entry at the end
            WritePrdEntry(PRD_MAX_ENTRIES - 1, 0, 0xbad1, true);

            uint baseAddr   = addr;
            uint bytesToMap = len;
            int  i          = 0;

            while (0 != bytesToMap)
            {
                uint did = WritePrdChunk(i, baseAddr, bytesToMap);
                baseAddr   += did;
                bytesToMap -= did;
                i++;
            }

            // DEBUG CHECK
            uint computedLen = 0;
            bool eotFound    = false;

            for (i = 0; i < PRD_MAX_ENTRIES; i++)
            {
                uint dummy;
                uint length;
                bool eot;
                ReadPrdEntry(i, out dummy, out length, out eot);
                computedLen = computedLen + length;
                if (eot)
                {
                    eotFound = true;
                    break;
                }
            }

            if (computedLen != len || !eotFound)
            {
                throw new ApplicationException("PRD length mismatch");
            }
            DumpPrd();

            return((uint)prdRegion.PhysicalAddress.Value);
        }