Beispiel #1
0
        internal IntelRingBuffer(uint capacity)
            //requires capacity > 0 && IsPowerOf2(capacity);
        {
            uint length  = capacity * DescriptorBytes;
            DmaMemory region = new DmaMemory((int)length); //TODO: DmaMemory.AllocatePhysical(length, AlignmentBytes);

            // (ARM only, not x86) PlatformService.SetCacheAttributes(region.VirtualAddress,
            //                                   (UIntPtr)region.Length,
            //                                   false,
            //                                   false);

            this.region     = region;
            this.mapEntries = new MapEntry [capacity];
            for (int i = 0; i < capacity; i++) {
                 this.mapEntries[i].mem = new DmaMemory((int)Intel.IEEE8023FrameBytes);
            }
            this.capacity   = capacity;

            this.head       = 0;
            this.tail       = 0;
            this.count      = 0;

            // Clear out ring buffer
            for (int i = 0; i < region.Length; i += 4) {
                region.Write32(i, 0);
            }
        }
        private Packet MakePacketFromDescriptor(DmaMemory mem, ulong controlBits)
        {
            PacketFifo inDevPkts = rxPacketsInDevice.Acquire();
            Packet     packet    = inDevPkts.Pop();
            int        length    = (int)((controlBits & RxDescriptor.LENGTH_MASK)
                                         >> RxDescriptor.LENGTH_SHIFT);
            uint stat_err = (uint)((controlBits & RxDescriptor.ERR_STAT_MASK)
                                   >> RxDescriptor.ERR_STAT_SHIFT);

            // can't deal with fragments yet
            if ((stat_err & RxErrStatFields.END_OF_PACKET) == 0)
            {
                INucleusCalls.DebugPrintHex(40, 0xd0);
                DebugStub.Print("FRAGMENT\n");
                throw new Exception();
            }

            //DebugStub.Assert((stat_err & RxErrStatFields.END_OF_PACKET) != 0);
            //DebugStub.Assert(packet.GetFragmentVirtualAddress(0) == fragmentVirtAddr);
            packet.FromDeviceFlags = GetRecvPktFlags(stat_err);
            packet.SetFragment(0, mem.BytesRef(0, length));
            rxPacketsInDevice.Release(inDevPkts);

            return(packet);
        }
Beispiel #3
0
 // Returns true if hardware is done with this descriptor.
 internal bool Peek(out DmaMemory mem,
                    out ulong controlBits)
 {
     if (this.count > 0) {
         UIntPtr pa;
         ReadDescriptor(this.tail, out pa, out controlBits);
         DebugStub.Assert(pa == this.mapEntries[tail].PhysicalAddress);
         mem = this.mapEntries[tail].mem;
         return ((controlBits & Descriptor.DESCRIPTOR_DONE) != 0);
     } else {
         mem = null;
         controlBits = 0;
         return false;
     }
 }
        ///////////////////////////////////////////////////////////////////////
        //
        // Buffer Operations, should only be called when a lock is held
        // this ring buffer.
        //
        private void _LockedPushTsmtBuffer(Packet packet)
        {
            // (ARM only, not x86) PlatformService.CleanAndInvalidateDCache(packetVirtAddr, (UIntPtr)length);
            int length = packet.GetLength();

            ulong controlBits = (ulong)ByteOrder.HostToLittleEndian(length);

            // set necessary command fields
            controlBits |= (TxCmdFields.END_OF_PACKET | TxCmdFields.INSERT_FCS |
                            TxCmdFields.REPORT_STATUS);

            DmaMemory mem = txRingBuffer.PeekHead();

            packet.CopyToBytes(mem.BytesRef());
            txRingBuffer.Push(controlBits);
        }