internal void ConfigurePciInterrupt(IoApic ioApic, MpInterruptEntry e) { byte vector = IrqToInterrupt(e.ApicLine); IoBits iobits = (e.PolarityType == Polarity.ActiveHigh) ? IoBits.IntPolActiveHigh : IoBits.IntPolActiveLow; iobits |= (e.TriggerType == Trigger.Edge) ? IoBits.TriggerModeEdge : IoBits.TriggerModeLevel; iobits |= IoBits.DstPhysical; iobits |= IoBits.DelModFixed; iobits |= IoBits.IrqMask; RedirectionEntry r = new RedirectionEntry(this.Id, iobits, vector); ioApic.SetRedirectionEntry(e.ApicLine, ref r); #if PRINT_IO_APICS DebugStub.Print("Added PCI interrupt for apic 0x{0:x}: Line 0x{1:x} => 0x{2:x}\n", __arglist(ioApic.GetId(), e.ApicLine, vector)); #endif }
private unsafe void VerifyOwner(UIntPtr startAddr, UIntPtr limitAddr, uint tag) { #if DEBUG DebugStub.Assert(startAddr >= dataStart); DebugStub.Assert(limitAddr <= rangeLimit); UIntPtr startIdx = PageFromAddr(startAddr); UIntPtr limitIdx = MemoryManager.PagesFromBytes(limitAddr - descrBase); DebugStub.Assert(limitIdx <= PageCount); tag &= MemoryManager.ProcessPageMask; for (UIntPtr i = startIdx; i < limitIdx; i++) { DebugStub.Assert ((pageTable[(uint)i] & MemoryManager.ProcessPageMask) == tag, "VirtualMemoryRange.VerifyOwner page={0} i={1} tag={2}", __arglist(i, i, tag)); } #endif }
/* * internal static UIntPtr GetPhysicalAddress(UIntPtr va) * { * UIntPtr pa; // Physical address * UIntPtr paLeft; // Bytes remaining on physical page * if (!DeviceService.GetDmaPhysicalAddress(va, out pa, out paLeft) || * pa == UIntPtr.Zero || * paLeft < Intel.IEEE8023FrameBytes) { * throw new ApplicationException("Bad DMA pointer"); * } * return pa; * } */ internal void Dump(string preamble, uint count) { if (count > this.capacity) { count = this.capacity; } Intel.DebugWriteLine("Head {0} Tail {1}\n", DebugStub.ArgList(this.Head, this.Tail)); for (uint i = 0; i < count; i++) { ulong address = this.region.Read64((int)(i * 16)); ulong fields = this.region.Read64((int)(i * 16 + 8)); Intel.DebugWriteLine("{0}: [{1}] Address {2:x16} Sp={3:x4} Err={4:x1} Sta={5:x2} Checksum {6:x4} Length {7:x4}", DebugStub.ArgList(preamble, i, address, (fields >> 48) & 0xffff, (fields >> 40) & 0xff, (fields >> 32) & 0xff, (fields >> 16) & 0xffff, fields & 0xffff)); } }
internal bool SendReceive(byte[] request, out byte[] response) { bool Status; response = null; Status = Send(request); if (!Status) { return(Status); } Status = Receive(out response); if (Status) { DebugStub.WriteLine("Tpm: SendReceive(), success"); } return(Status); }
internal unsafe void MarkAsFree(uint pageIdx) { CheckConsistency(); fixed( uint *pBeforeRegions = &blockMap ) { uint* pRegions = pBeforeRegions; // Point just before regions pRegions++; // Advance to the first region word uint regionIdx = pageIdx / 32; uint bitIdx = pageIdx % 32; DebugStub.Assert(pageIdx < PagesPerBlock, "PhysicalPages.PageBlock.MarkAsFree: Bad page index"); DebugStub.Assert(PageInUse(pageIdx), "PhysicalPages.PageBlock.MarkAsFree: Page already free"); // Mark the page free in its subregion pRegions[regionIdx] &= ~((uint)1 << (int)bitIdx); // Mark our subregion as being usable blockMap &= ~((uint)1 << (int)regionIdx); } CheckConsistency(); }
private unsafe void CheckConsistency() { #if SELF_TEST // Top bits should be kept clear DebugStub.Assert((blockMap & UnusedMask) == 0); fixed ( uint* pBeforeRegions = &blockMap ) { uint* pRegion = pBeforeRegions; pRegion++; for (uint i = 0; i < RegionsPerBlock; i++, pRegion++) { if ((*pRegion) != FullRegion) { DebugStub.Assert((blockMap & ((uint)1 << (int)i)) == 0, "PhysicalPages.PageBlock.CheckConsistency: blockMap shows a free region as full"); } else { DebugStub.Assert((blockMap & ((uint)1 << (int)i)) != 0, "PhysicalPages.PageBlock.CheckConsistency: blockMap shows a full region as free"); } } } #endif }
private byte Initialize() { if ((ReadRtc(DS1287_D) & DS1287_D_VRT) == 0) { DebugStub.Print("RTClock weak or defective power source.\n"); } rtcBootTime = PullRtcTime(); DebugStub.Print("RTClock::Start()\n"); // Enable and clear interrupts // NB it may take 500ms for first interrupt to be generated. WriteRtc(DS1287_B, DS1287_B_UTI); WriteRtc(DS1287_A, DS1287_A_2HZ); WriteRtc(DS1287_A, DS1287_A_DIVON | DS1287_A_2HZ); WriteRtc(DS1287_B, DS1287_B_HF_24H | DS1287_B_DF_BCD | DS1287_B_PIE | DS1287_B_SQWE); // apic.SetIrqPriority(irq, IrqPriority.High); apic.EnableIrq(irq); // Here we wait for the first interrupt to be // raised, which might be upto 0.5 seconds. This // wait is based on experience, ie not waiting with // some boxes (the infamous Ryan's TPM machine for // instance) leads to the clock interrupt never being // raised. while ((ReadRtc(DS1287_C) & DS1287_C_PF) != DS1287_C_PF) { // TODO: Break out after 1 second and // report an error. } firstStatus = DS1287_C_PF; byte ivValue = apic.IrqToInterrupt(irq); return(ivValue); }
public unsafe static bool Create( string implName, Allocation * /*EndpointCore* opt(ExHeap)!*/ endpoint, out DeliveryHandle handle) { DeliveryImpl deliveryImpl; switch (implName) { case SingleAddrSpaceDelivery.ImplName: deliveryImpl = new SingleAddrSpaceDelivery(endpoint); break; #if PAGING // TODO paging #endif default: throw new DeliveryHandleException( "Unknown channel delivery implementation \"" + implName + "\" requested"); } if (!deliveryImpl.IsMechanismInitialized()) { DebugStub.Print("Ack! IsMechInit returns false!\n"); DebugStub.Break(); handle = Zero; return(false); } handle = new DeliveryHandle( Process.kernelProcess.AllocateHandle(deliveryImpl)); #if false unsafe { DebugStub.WriteLine("DeliveryHandle.Create: got handle {0,8:x}\n", __arglist((uint)handle.id)); } #endif return(true); }
private void DumpRegisters() { IoResult result = IoResult.Success; ushort currentIrqNumber = (ushort)(intcps_sir_irq.Read16NoThrow(ref result) & INTCPS_SIR_IRQ_ACTIVEIRQ_Mask); ushort currentIrqPriority = (ushort)(intcps_irq_priority.Read16NoThrow(ref result) & (ushort)INTCPS_IRQ_PRIORITY_Mask); DebugStub.WriteLine("PIC Current IRQ: {0:x4} Priority: {0:x4}", __arglist(currentIrqNumber, currentIrqPriority)); ushort currentFiqNumber = (ushort)(intcps_sir_fiq.Read16NoThrow(ref result) & INTCPS_SIR_FIQ_ACTIVEFIQ_Mask); ushort currentFiqPriority = (ushort)(intcps_fiq_priority.Read16NoThrow(ref result) & INTCPS_FIQ_PRIORITY_Mask); DebugStub.WriteLine("PIC Current FIQ: {0:x4} Priority: {0:x4}", __arglist(currentFiqNumber, currentFiqPriority)); DumpBits("PIC raw interrupt status: {2:x8}{1:x8}{0:x8}", intcps_itr); DumpBits("PIC interrupt mask: {2:x8}{1:x8}{0:x8}", intcps_mir); DumpBits("PIC software interrupts: {2:x8}{1:x8}{0:x8}", intcps_isr_set); DumpBits("PIC pending IRQs: {2:x8}{1:x8}{0:x8}", intcps_pending_irq); DumpBits("PIC pending FIQs: {2:x8}{1:x8}{0:x8}", intcps_pending_fiq); for (uint i = 0; i < INTCPS_Vectors; ++i) { uint ilr = intcps_ilr.Read32NoThrow(i * INTCPS_ILR_Offset, ref result); string interruptType = ((ilr & INTCPS_ILR_FIQNIRQ) != 0) ? "fiq" : "irq"; byte priority = (byte)((ilr & INTCPS_ILR_PRIORITY_Mask) >> INTCPS_ILR_PRIORITY_Shift); DebugStub.WriteLine("PIC ILR[{0}]: {1} Priority: {2:x2}", __arglist(i, interruptType, priority)); } DebugStub.Assert(IoResult.Success == result); }
internal override void EnterEvent() { // Yay! We got DHCP configuration information DateTime now = DateTime.Now; // Set up renewal timer DhcpDWordOption renewalOption = hostOptions[DhcpRenewalTime.OptionCode] as DhcpDWordOption; uint renewalSeconds = 3600; if (renewalOption != null) { renewalSeconds = renewalOption.Value; } client.SetRenewalTimeout(now + TimeSpan.FromSeconds(renewalSeconds)); // Set up rebinding timer DhcpDWordOption rebindOption = hostOptions[DhcpRebindingTime.OptionCode] as DhcpDWordOption; uint rebindSeconds = renewalSeconds + 60; if (rebindOption != null) { rebindSeconds = Math.Max(rebindOption.Value, renewalSeconds + 1); } client.SetRebindTimeout(now + TimeSpan.FromSeconds(rebindSeconds)); // Add host address as a dhcp option and then get client // to install settings. hostOptions[DhcpRequestedIPAddress.OptionCode] = DhcpRequestedIPAddress.Create(hostAddress); if (client.InstallDhcpOptions(hostOptions) == false) { client.ChangeState(new DhcpClientStateInitialize(client)); } DebugStub.Print("DHCP client acquired lease of " + hostAddress + " for " + rebindSeconds + " seconds. "); }
/// <summary> /// Create and Register a TcpSessionEventsSource. /// </summary> /// <devdoc> /// This should be a Generic when supported. Or use more of the base class (Static?) // BUGBUG AM (later?) /// </devdoc> public static TcpSessionEventsSource Create(string sourceName, uint size, uint storageOptions, // BUGBUG AM: [Flags] enum uint sourceFlags, uint debugFlags) { TcpSessionEventsSource tcpSessionEventsSource = null; EventingStorage eventStorage = EventingStorage.CreateLocalStorage(storageOptions, size); if (eventStorage == null) { DebugStub.WriteLine("Failure to obtain storage for TcpSessionEvents"); DebugStub.Break(); } else { tcpSessionEventsSource = new TcpSessionEventsSource(sourceName, eventStorage, sourceFlags, debugFlags); if (tcpSessionEventsSource == null) { // TODO: Is EventStorage returned here and below if failures occur? DebugStub.WriteLine("Failure to construct TcpSessionEventsSource instance."); DebugStub.Break(); } else { bool registerSucceeded = tcpSessionEventsSource.Register(); if (registerSucceeded == false) { tcpSessionEventsSource = null; DebugStub.WriteLine("Failure to register TcpSessionEventsSource."); DebugStub.Break(); } } } return(tcpSessionEventsSource); }
private unsafe static void MakeRangeL1Entries(UIntPtr start, UIntPtr length) { DebugStub.Assert(RangeIsPageAligned(start, length, L1SectionSize)); for (UIntPtr limit = start + length; start != limit; start += L1SectionSize) { uint *entryPtr = ((uint *)ttb) + (start >> L1SectionShift); uint type = *entryPtr & L1.TypeMask; if (type == L1.CoarsePageTableType) { uint *l2Start = (uint *)(*entryPtr & L1.CoarsePageTableAddressMask); uint l2Entry = *l2Start; for (int i = 0; i < L2TableEntries; i++) { // Invalidate translations for entries in L2 table InvalidateDTlbEntry(l2Start[i] & L2Coarse.ExtendedSmallPageAddressMask); } FreeL2Table((UIntPtr)l2Start); CleanInvalidateDCacheLines((UIntPtr)l2Start, L2TableSize); // Change entry from L2 Table pointer to L1 Section Entry uint l1Entry = *entryPtr; l1Entry &= (L1.DomainMask | L1.PBit); l1Entry |= (l2Entry & (L2Coarse.ExtendedSmallPageTexMask | L2Coarse.Ap0Mask)) << (L1.ApRoll - L2Coarse.Ap0Roll); l1Entry |= l2Entry & (L2Coarse.CBit | L2Coarse.BBit); l1Entry |= L1.SectionType; l1Entry |= start & L1.SectionAddressMask; *entryPtr = l1Entry; InvalidateDTlbEntry(start); } else { DebugStub.Assert(IsSectionType(*entryPtr)); } } }
public override void DisableIrq(byte irq) { if (irq == 2 || irq >= PIC_VECTORS) { DebugStub.Break(); // throw new OverflowException // (String.Format("irq {0} out of range.", irq)); } #if DEBUG_INTERRUPTS DebugStub.Print("Int{0:x2} Disable\n", __arglist(irq + baseVector)); #endif bool saved = Processor.DisableInterrupts(); try { Mask(irq); DumpRegisters(); } finally { Processor.RestoreInterrupts(saved); } }
internal unsafe void Unlink(ref uint listHead) { DebugStub.Assert(IsLinked(listHead)); if (prevIdx != Sentinel) { DebugStub.Assert(GetBlock(prevIdx)->nextIdx == Index, "PhysicalPages.PageBlock.Unlink: inconsistent prev->next"); GetBlock(prevIdx)->nextIdx = nextIdx; } else { // We are the list head. DebugStub.Assert(listHead == Index, "PhysicalPages.PageBlock.Unlink: inconsistent head"); listHead = nextIdx; } if (nextIdx != Sentinel) { DebugStub.Assert(GetBlock(nextIdx)->prevIdx == Index, "PhysicalPages.PageBlock.Unlink: inconsistent next->prev"); GetBlock(nextIdx)->prevIdx = prevIdx; } nextIdx = Sentinel; prevIdx = Sentinel; }
// Dump Srat Important fields public void DumpSratImportantFields() { DebugStub.Print("\n\n\n SRAT Important Fields: \n"); DebugStub.Print("------------------------------------\n"); for (int i = 0; i < processorOffsets.Length; i++) { DebugStub.Print(" PROCESSOR {0}\n", __arglist(i)); DebugStub.Print(" Domain : {0}\n", __arglist(GetProcessorDomain(i))); DebugStub.Print(" APIC ID : {0}\n", __arglist(GetProcessorApicId(i))); DebugStub.Print(" Ignore : {0}\n", __arglist(GetProcessorFlagIgnore(i))); } for (int i = 0; i < memoryOffsets.Length; i++) { DebugStub.Print(" MEMORY {0}\n", __arglist(i)); DebugStub.Print(" Domain : {0}\n", __arglist(GetMemoryDomain(i))); DebugStub.Print(" Base : {0} KB\n", __arglist(GetMemoryBaseAddress(i) / 1024)); DebugStub.Print(" End : {0} KB\n", __arglist(GetMemoryEndAddress(i) / 1024)); DebugStub.Print(" MemSize : {0} KB\n", __arglist(GetMemorySize(i) / 1024)); DebugStub.Print(" Ignore : {0}\n", __arglist(GetMemoryFlagIgnore(i))); DebugStub.Print(" HotPlug : {0}\n", __arglist(GetMemoryFlagHotPluggable(i))); DebugStub.Print(" NonVol : {0}\n", __arglist(GetMemoryFlagNonVolatile(i))); } DebugStub.Print("\n\n\n"); }
internal bool SetFrequency(uint frequency) { if (frequency > 8192 || frequency < 2) { return(false); } if (Processor.SamplingEnabled()) { frequency = 8192; } int a = DS1287_A_DIVON; a |= (0xf - (Log2(frequency) - 1)) & 0xf; DebugStub.Assert((a & 0xf0) == DS1287_A_DIVON); WriteRtc(DS1287_A, (byte)a); WriteRtc(DS1287_B, DS1287_B_HF_24H | DS1287_B_DF_BCD | DS1287_B_PIE | DS1287_B_SQWE); return(true); }
public override bool InternalInterrupt(byte interrupt) { // Strictly there are no interrupts internal to // this Hal instance. In practice, some hardware seems // intent on firing an interrupt even if it is masked. // // Return true if interrupt appears to be valid but // is masked, false otherwise. byte irq = pic.InterruptToIrq(interrupt); #if DEBUG_SPURIOUS DebugStub.Break(); #endif if (pic.IrqMasked(irq) == true) { DebugStub.WriteLine("--- Acked spurious Irq={0:x2}", __arglist(irq)); pic.AckIrq(irq); return(true); } return(false); }
internal unsafe UIntPtr Free(UIntPtr startPage, UIntPtr numPages, Process process) { DebugStub.Assert(startPage >= dataStart); DebugStub.Assert(MemoryManager.IsPageAligned(startPage)); UIntPtr blockLimit = startPage + MemoryManager.BytesFromPages(numPages); DebugStub.Assert(blockLimit <= rangeLimit); // // NOTE: This is strictly a sanity check. The pagetable // is ultimately not trustworthy because it is writeable by // user-mode code. // uint tag = process != null ? process.ProcessTag : MemoryManager.KernelPage; VerifyOwner(startPage, blockLimit, tag); // Do it return(FreeAndUncommit(startPage, numPages)); }
private unsafe void CheckAddressSpace() { #if DEBUG UIntPtr rangeLimit; if (indirect) { rangeLimit = pRange->DataLimitAddr; } else { rangeLimit = range.DataLimitAddr; } if (rangeLimit > Platform.KERNEL_BOUNDARY) { // We are a user-space range. We had better // be using the right address space! DebugStub.Assert(parentDomain.AddressSpace == Processor.GetCurrentAddressSpace()); } // else we are a kernel range and are always mapped. #endif }
public SortedList Enumerate() { SortedList found = new SortedList(); int node = 0x100; foreach (AcpiDevice !deviceInfo in deviceInfoEntries) { IoConfig !ioConfig = ResourceDescriptorsToIoConfig(deviceInfo.DeviceId, (!)deviceInfo.ResourceDescriptors); DebugStub.Write("Detected ACPI device "); DebugStub.WriteLine(ioConfig.Id); System.Text.StringBuilder descriptionBuilder = new System.Text.StringBuilder(); ioConfig.DumpRanges(descriptionBuilder); DebugStub.WriteLine(descriptionBuilder.ToString()); found.Add(String.Format("/{0,3:x3}", node++), ioConfig); } return(found); }
internal static IDevice CreateDevice(IoConfig config, string name) { PnpConfig pnpConfig = config as PnpConfig; if (pnpConfig == null) { return(null); } IoMemoryRange imr = config.DynamicRanges[0] as IoMemoryRange; if (imr == null) { return(null); } int imrBytes = (int)imr.Length.ToUInt32(); if (imrBytes < Hpet.MinRegionBytes) { DebugStub.Write( "HPET failed as region too small ({0} bytes).\n", __arglist(imrBytes)); return(null); } Hpet hpet = new Hpet(pnpConfig); if (hpet.MainCounterWorks()) { HalDevicesApic.SwitchToHpetClock(hpet); } else { DebugStub.Print("WARNING: HPET main counter does not work!\n"); } return(hpet); }
public static void InvalidateDCacheLines(UIntPtr start, UIntPtr length) { if (length == 0) { return; } DebugStub.Assert(length < new UIntPtr(256 * 1024 * 1024)); bool en = Processor.DisableInterrupts(); FlushPrefetch(); MemoryFence(); try { if ((start & (CacheLineSize - 1)) != 0) { // Start is not aligned, line may other data on it. CleanInvalidateDCacheLine(start); } if (((start + length) & (CacheLineSize - 1)) != 0) { // End is not aligned, line may other data on it. CleanInvalidateDCacheLine((start + length) & ~(CacheLineSize - 1)); } // NB Invalidate lines over specified range, never // invalidate entire cache since it likely contains // other peoples modified data. InvalidateL1DCacheLines((uint)start, (uint)length); InvalidateL2CacheLines((uint)start, (uint)length); } finally { FlushPrefetch(); MemoryFence(); Processor.RestoreInterrupts(en); } }
internal virtual void PrintGCTiming() { if (VTable.enableGCTiming || VTable.enableFinalGCTiming) { #if SINGULARITY DebugStub.WriteLine("Total GC Time (ms): {0}", __arglist(gcTotalTime)); #else Console.Error.WriteLine("Total GC Time (ms): " + gcTotalTime); Console.Error.WriteLine("Max. Pause Time (ms): " + maxPauseTime); if (BaseCollector.pauseCount != 0) { Console.Error.WriteLine("Avg. Pause Time (ms): " + gcTotalTime / pauseCount); } else { Console.Error.WriteLine("Avg. Pause Time (ms): 0"); } #endif } }
public bool RemoveTcpSession(TCP tcpSession, LinkedListNode tcpLLNode) //requires tcpSession.chainedHashLLNode != null; { byte hash = Hash(tcpSession.localIPAddress, tcpSession.remoteIPAddress, tcpSession.localPort, tcpSession.remotePort); ChainedHashNode chainedHashNode = chainedHash[hash]; VTable.Assert(chainedHashNode != null); if (tcpSession == chainedHashNode.sideCache) { chainedHashNode.sideCache = null; } LinkedList linkedList = chainedHashNode.linkedList; VTable.Assert(linkedList != null); TCP returnedSession = linkedList.Remove(tcpLLNode) as TCP; DebugStub.Assert(tcpSession == returnedSession); VTable.Assert(tcpSession == returnedSession); return(true); }
public void WatchdogThreadMain() { TimeSpan delta = TimeSpan.FromSeconds(timeoutSeconds); int now = this.generation; int last = 0; do { last = now; if (finishedEvent.WaitOne(delta)) { return; } Yield(); now = this.generation; if (last == now) { DebugStub.Break(); // break if we made no progress } } while (true); }
internal static void AddEntry(int who, RtcPitState rps, TimerOmap3430 timer, long cookie) { if (ignoreCount != 0) { ignoreCount--; return; } if (currentRecord == entries.Length) { return; } entries[currentRecord].who = who; entries[currentRecord].cookie = cookie; entries[currentRecord].when = Processor.CycleCount; // int pitNow = timer.Timer2Read(); int pitNow = 0; entries[currentRecord].currentTime = (ulong)rps.GetKernelTicks(pitNow); entries[currentRecord].upTime = rps.upTime; entries[currentRecord].pitLastClock = rps.pitLastClock; entries[currentRecord].pitNow = pitNow; currentRecord = currentRecord + 1; if (currentRecord == entries.Length) { bool iflag = Processor.DisableInterrupts(); try { DumpEntries(); DebugStub.Assert(false); } finally { Processor.RestoreInterrupts(iflag); } } }
private void PitWriteReadTest() { DebugStub.Print("PitWriteRead() test...\n"); int pitLast = 0x4fff; int pitNow; int pitEnd = 0x3fff; PitWrite(pitLast); do { pitNow = PitRead(); if (pitNow > pitLast) { DebugStub.Print("({0} > {1})\n", __arglist(pitNow, pitLast)); break; } pitLast = pitNow; } while (pitNow > pitEnd); DebugStub.Print((pitNow <= pitEnd) ? "PASSED\n" : "FAILED\n"); }
internal int Timer2Read() { timer2reads++; DebugStub.Assert(timer2reads == 1); IoResult result = CWPort.Write8NoThrow(i8254_RB_NOSTATUS | i8254_RB_SEL2); DebugStub.Assert(IoResult.Success == result); byte lo, hi; result = C2Port.Read8NoThrow(out lo); DebugStub.Assert(IoResult.Success == result); result = C2Port.Read8NoThrow(out hi); DebugStub.Assert(IoResult.Success == result); timer2reads--; DebugStub.Assert(timer2reads == 0); return((int)lo | ((int)hi << 8)); }
public static bool IsChecksumValid(IPFormat.IPHeader !ipHeader, UdpHeader udpHeader, NetPacket !payload) { // Compute partial checksums of headers ushort checksum = IPFormat.SumPseudoHeader(ipHeader); checksum = IPFormat.SumShortValues(checksum, UdpFormat.SumHeader(udpHeader)); // Checksum payload int length = payload.Available; int end = length & ~1; int i = 0; while (i != end) { int x = ((((int)payload.PeekAvailable(i++)) << 8) + (int)payload.PeekAvailable(i++)); checksum = IPFormat.SumShortValues(checksum, (ushort)x); } if (i != length) { int x = (((int)payload.PeekAvailable(i++)) << 8); checksum = IPFormat.SumShortValues(checksum, (ushort)x); } checksum = IPFormat.ComplementAndFixZeroChecksum(checksum); if (udpHeader.checksum != checksum) { DebugStub.WriteLine("Bad UDP checksum {0:x4} != {1:x4}", __arglist(udpHeader.checksum, checksum)); } return(udpHeader.checksum == checksum); }
/// <summary> /// Given a buffer and a pointer into it, unmarshalls a byte array /// from the buffer, advancing the pointer by 4 bytes. /// </summary> /// <param name="bytes">The buffer from which the byte array is /// unmarshalled.</param> /// <param name="offset">The position in the buffer where the Handle /// starts. /// After completion, offset is the next position after the Handle. /// </param> /// <returns>The byte array that was unmarshalled.</returns> /// /// Note that our marshall and unmarshall routines are not symmetric /// I.e., We marshall a null string as a string of zero length. But /// unmarshalling a 0 length string does not result in a null string /// but in a string with zero length. /// I believe the B-Tree recovery procedures cannot deal with an /// unmarshalled string that is a null. public static byte[] Unmarshall(byte[] bytes, ref int offset) { int len = Int.Unmarshall(bytes, ref offset); if (len == MIN) { return(Minimum); } else if (len == MAX) { return(Maximum); } else { if (len < 0) { DebugStub.WriteLine("ba len is negative " + len); system.panic("bad len"); } if (len == 0) { //Console.WriteLine("BA LEN is 0 "); } byte[] b = new byte[len]; try { Array.Copy(bytes, offset, b, 0, b.Length); offset += b.Length; return(b); } catch (Exception) { DebugStub.WriteLine("len = " + len + " b.Length " + b.Length + " offset: " + offset + " bytes.Length " + bytes.Length); throw; } } }