예제 #1
0
 internal static void Setup()
 {
     System.DebugStub.Print("Dma.Setup 1. ");
     try {
         CompilerIntrinsics.Cli();
         ioMemory   = NucleusCalls.PciDmaBuffer();
         ioPhysical = NucleusCalls.PciDmaPhysicalAddr();
         // The IO-MMU tables map 2MB, aligned by 2MB
         uint superPageSize = 0x200000;
         uint ioSuperPage   = (ioPhysical + 2 * superPageSize) - (ioPhysical & (superPageSize - 1));
         allocOffset = (int)(ioSuperPage - ioPhysical);
     }
     finally {
         CompilerIntrinsics.Sti();
     }
     System.DebugStub.Print("Dma.Setup 2. ioPhysical = 0x" + ioPhysical.ToString("X") + " allocOffset = 0x" + allocOffset.ToString("X") + ". ");
 }
예제 #2
0
 public bool TryWait()
 {
     try
     {
         CompilerIntrinsics.Cli();
         if (capacity <= 0)
         {
             return(false);
         }
         capacity--;
         return(true);
     }
     finally
     {
         CompilerIntrinsics.Sti();
     }
 }
예제 #3
0
 public void Release()
 {
     try
     {
         CompilerIntrinsics.Cli();
         if (lockDepth > 0)
         {
             lockDepth--;
             return;
         }
         lockHolder = 0xffffffff;
         lockSemaphore.SignalInterruptsDisabled();
     }
     finally
     {
         CompilerIntrinsics.Sti();
     }
 }
예제 #4
0
 internal DmaMemory(int length)
 {
     System.VTable.Assert(length >= 0);
     try {
         CompilerIntrinsics.Cli();
         this.offset = allocOffset;
         this.length = length;
         if (allocOffset + length <= ioMemory.Length)
         {
             allocOffset += length;
         }
     } finally {
         CompilerIntrinsics.Sti();
     }
     if (offset + length > ioMemory.Length)
     {
         throw new System.Exception("DmaMemory");
     }
 }
예제 #5
0
 private bool WaitOne(WakeUp wakeUp)
 {
     try
     {
         CompilerIntrinsics.Cli();
         if (isSet)
         {
             return(true);
         }
         else
         {
             return(waitSemaphore.WaitInterruptsDisabled(wakeUp));
         }
     }
     finally
     {
         CompilerIntrinsics.Sti();
     }
 }
예제 #6
0
 public void PulseAll()
 {
     try
     {
         CompilerIntrinsics.Cli();
         if (waitSemaphore == null)
         {
             return;
         }
         while (waitSemaphore.capacity != 0)
         {
             waitSemaphore.SignalInterruptsDisabled();
         }
     }
     finally
     {
         CompilerIntrinsics.Sti();
     }
 }
예제 #7
0
 public void Yield()
 {
     try
     {
         CompilerIntrinsics.Cli();
         if (collectionRequested)
         {
             EnqueueAndYield(collectionQueue);
         }
         else
         {
             EnqueueAndYield(readyQueue);
         }
     }
     finally
     {
         CompilerIntrinsics.Sti();
     }
 }
예제 #8
0
    private static void Main()
    {
        uint id = CurrentThread;

        if (id == 0)
        {
            kernel = new Kernel();
            kernel.KernelMain();
        }
        else
        {
            kernel.ThreadMain(id);
        }
        CompilerIntrinsics.Cli(); // TODO: superfluous
        NucleusCalls.DebugPrintHex(0, 0xdead0001);
        while (true)
        {
        }
    }
예제 #9
0
 public void Signal()
 {
     try
     {
         CompilerIntrinsics.Cli();
         capacity++;
         Thread t = waiters.Dequeue();
         if (t != null)
         {
             ThreadQueue ready = Kernel.kernel.readyQueue;
             ready.Enqueue(t);
             Kernel.kernel.EnqueueAndYield(ready);
         }
     }
     finally
     {
         CompilerIntrinsics.Sti();
     }
 }
예제 #10
0
 internal bool Acquire(WakeUp wakeUp)
 {
     try
     {
         CompilerIntrinsics.Cli();
         uint cur = Kernel.CurrentThread;
         if (lockHolder == cur)
         {
             lockDepth++;
             return(true);
         }
         bool gotIt = lockSemaphore.WaitInterruptsDisabled(wakeUp);
         lockHolder = cur;
         return(gotIt); // TODO: return value doesn't match documentation, but should it?
     }
     finally
     {
         CompilerIntrinsics.Sti();
     }
 }
예제 #11
0
        public override void Run()
        {
            System.DebugStub.Print(" PLASMA Verve.  ");
            System.DebugStub.Print("IoThread@" + Kernel.CurrentThread + ". ");
            byte[] pciDmaBuffer;
            try {
                CompilerIntrinsics.Cli();
                pciDmaBuffer = NucleusCalls.PciDmaBuffer();
            } finally {
                CompilerIntrinsics.Sti();
            }

            if (pciDmaBuffer == null)
            {
                System.DebugStub.Print("No IO-MMU. ");
                Kernel.kernel.NewSemaphore(0).Wait();
                return;
            }

            // Establish DMA buffer area
            Microsoft.Singularity.Io.DmaMemory.Setup();

            // Enumerate and initialize PCI devices
            for (uint id = 0; id < 65536; id += 8)
            {
                uint v;
                try {
                    CompilerIntrinsics.Cli();
                    v = NucleusCalls.PciConfigRead32(id, 0);
                } finally {
                    CompilerIntrinsics.Sti();
                }
                if (v == 0x107c8086)
                {
                    // Intel NIC
                    System.DebugStub.Print("Found Intel NIC. ");
                }
            }
            System.DebugStub.Print("IoThread done. ");
            Kernel.kernel.NewSemaphore(0).Wait();
        }
예제 #12
0
 public void Set()
 {
     try
     {
         CompilerIntrinsics.Cli();
         if (waitSemaphore.capacity == 0)
         {
             // no waiters
             isSet = true;
         }
         else
         {
             // signal a waiter
             isSet = false;
             waitSemaphore.SignalInterruptsDisabled();
         }
     }
     finally
     {
         CompilerIntrinsics.Sti();
     }
 }
예제 #13
0
 public bool TryAcquire()
 {
     try
     {
         CompilerIntrinsics.Cli();
         uint cur = Kernel.CurrentThread;
         if (lockHolder == cur)
         {
             lockDepth++;
             return(true);
         }
         bool gotIt = lockSemaphore.TryWaitInterruptsDisabled();
         if (gotIt)
         {
             lockHolder = cur;
         }
         return(gotIt);
     }
     finally
     {
         CompilerIntrinsics.Sti();
     }
 }
예제 #14
0
파일: Io.cs 프로젝트: Paul1nh0/Singularity
        public override void Run()
        {
            System.DebugStub.Print("IoThread@" + Kernel.CurrentThread + ". ");
            byte[] pciDmaBuffer;
            try {
                CompilerIntrinsics.Cli();
                pciDmaBuffer = NucleusCalls.PciDmaBuffer();
            } finally {
                CompilerIntrinsics.Sti();
            }

            if (pciDmaBuffer == null)
            {
                System.DebugStub.Print("No IO-MMU. ");
                Kernel.kernel.NewSemaphore(0).Wait();
                return;
            }
            // Set up networking
            Microsoft.Singularity.NetStack2.ARP arp =
                new Microsoft.Singularity.NetStack2.ARP();
            Microsoft.Singularity.NetStack2.IP.Initialize(arp);
            Microsoft.Singularity.NetStack2.Ethernet.Initialize(arp);

            //Microsoft.Singularity.NetStack2.Channels.Private.RoutingExpManager routingManager =
            //    new Microsoft.Singularity.NetStack2.Channels.Private.RoutingExpManager();
            Microsoft.Singularity.NetStack2.Channels.Private.IPContract ipManager =
                new Microsoft.Singularity.NetStack2.Channels.Private.IPContract();

            // Establish DMA buffer area
            Microsoft.Singularity.Io.DmaMemory.Setup();

            // Enumerate and initialize PCI devices
            for (uint id = 0; id < 65536; id += 8)
            {
                uint v;
                try {
                    CompilerIntrinsics.Cli();
                    v = NucleusCalls.PciConfigRead32(id, 0);
                } finally {
                    CompilerIntrinsics.Sti();
                }
                if (v == 0x107c8086)
                {
                    // Intel NIC
                    System.DebugStub.Print("Found Intel NIC. ");
                    Microsoft.Singularity.Drivers.Network.Intel.Intel intel =
                        new Microsoft.Singularity.Drivers.Network.Intel.Intel(
                            new Microsoft.Singularity.Io.PciDeviceConfig((ushort)id),
                            new Microsoft.Singularity.Io.PciMemory(id),
                            "82541 PI",
                            Microsoft.Singularity.Drivers.Network.Intel.CardType.I82541PI);
                    intel.Initialize();
                    Microsoft.Singularity.Io.Net.NicDeviceContract nicDev =
                        new Microsoft.Singularity.Drivers.Network.Intel.IntelDeviceChannel(intel);
                    bool ok = Microsoft.Singularity.NetStack2.Channels.Nic.Nic.CreateAndRegister(
                        nicDev, "/nic0");
                    System.VTable.Assert(ok);
                    ipManager.StartDhcp("/nic0");
                }
            }
            System.DebugStub.Print("IoThread done. ");
            Kernel.kernel.NewSemaphore(0).Wait();
        }
예제 #15
0
    internal void ScheduleNextThread()
    {
        Thread t = readyQueue.Dequeue();

        if (t == null)
        {
            if (collectionRequested)
            {
                CompilerIntrinsics.Cli(); // TODO: superfluous
                NucleusCalls.DebugPrintHex(70, ++gcCount);
                NucleusCalls.DebugPrintHex(60, 0);
                long t1 = NucleusCalls.Rdtsc();

                // No ready threads.
                // Make anyone waiting for GC ready:
                while (true)
                {
                    t = collectionQueue.Dequeue();
                    if (t == null)
                    {
                        break;
                    }
                    readyQueue.Enqueue(t);
                }

                t = readyQueue.Dequeue();

                // Garbage collect, then we're ready to go.
                CompilerIntrinsics.Sti();
                System.DebugStub.Print("GarbageCollecting. ");
                CompilerIntrinsics.Cli();
                NucleusCalls.GarbageCollect();
                collectionRequested = false;

                long t2   = NucleusCalls.Rdtsc();
                uint diff = (uint)((t2 - t1) >> 10);
                NucleusCalls.DebugPrintHex(60, diff);
            }

            while (t == null)
            {
                // TODO: let the CPU sleep here
                // TODO: enable interrupts
                CompilerIntrinsics.Cli(); // TODO: superfluous
                if (!CheckWakeUp())
                {
                    // No threads to run.  The system is finished.
                    CompilerIntrinsics.Cli(); // TODO: superfluous
                    NucleusCalls.DebugPrintHex(0, 0x76543210);
                    while (true)
                    {
                    }
                }

                t = readyQueue.Dequeue();
                CompilerIntrinsics.Cli(); // TODO: superfluous
            }
        }

        // Go to t.
        RunThread(t);

        // We're back.  Somebody (not necessarily t) yielded to us.
    }