internal static long GetUtcTimeInterruptsDisabled() { CompilerIntrinsics.Cli(); // TODO: superfluous long tsc = NucleusCalls.Rdtsc(); return(unchecked (tsc >> 8)); }
internal static void Throw() { CompilerIntrinsics.Cli(); NucleusCalls.Throw(); while (true) { } }
private bool RunThread(Thread t) { uint id = t.id; CurrentThread = id; NucleusCalls.YieldTo(id); return(true); }
public uint Read32(int offset) { try { CompilerIntrinsics.Cli(); return(NucleusCalls.PciMemRead32(id, (uint)offset)); } finally { CompilerIntrinsics.Sti(); } }
public void Write32(int offset, uint val) { try { CompilerIntrinsics.Cli(); NucleusCalls.PciMemWrite32(id, (uint)offset, val); } finally { CompilerIntrinsics.Sti(); } }
private void KernelMain() { CompilerIntrinsics.Cli(); // TODO: superfluous for (uint i = 0; i < 50 * 80; i++) { NucleusCalls.VgaTextWrite(i, 0); } Thread init = new Thread(new InitThread(), true); _NewThread(init); uint x = 0xe100; uint y = 0; while (true) { CompilerIntrinsics.Cli(); // TODO: superfluous NucleusCalls.VgaTextWrite(79, x); x++; // Schedule thread, wait for exception or interrupt ScheduleNextThread(); // CurrentThread received exception, interrupt, or exited voluntarily uint cid = CurrentThread; Thread t = threadTable[cid]; CompilerIntrinsics.Cli(); // TODO: superfluous uint cState = NucleusCalls.GetStackState(cid); if (cState == STACK_EMPTY) { // Thread received an exception. Kill it. t.alive = false; } CompilerIntrinsics.Cli(); // TODO: superfluous if (t.alive) { // Thread was interrupted. It's still ready to run. NucleusCalls.SendEoi(); CheckWakeUp(); CompilerIntrinsics.Cli(); // TODO: superfluous NucleusCalls.StartTimer(0); readyQueue.Enqueue(t); } else { NucleusCalls.VgaTextWrite(78, (uint)(0x5b00 + 0x1100 * (y++) + 48 + cid)); // Thread is dead. Dead threads always jump back to stack 0. threadTable[cid] = null; NucleusCalls.ResetStack(cid); } } }
/*TODO * public byte Read8(int offset) { * return (byte)(Read32(offset)); * } * * public ushort Read16(int offset) { * return (ushort)(Read32(offset)); * } */ public uint Read32(int offset) { System.VTable.Assert((offset & 3) == 0); try { CompilerIntrinsics.Cli(); return(NucleusCalls.PciConfigRead32(id, (uint)offset)); } finally { CompilerIntrinsics.Sti(); } }
internal static void VgaTextWrite(uint position, uint data) { try { CompilerIntrinsics.Cli(); NucleusCalls.VgaTextWrite(position, data); } finally { CompilerIntrinsics.Sti(); } }
internal static uint TryReadKeyboard() { try { CompilerIntrinsics.Cli(); return(NucleusCalls.TryReadKeyboard()); } finally { CompilerIntrinsics.Sti(); } }
internal static long Rdtsc() { try { CompilerIntrinsics.Cli(); return(NucleusCalls.Rdtsc()); } finally { CompilerIntrinsics.Sti(); } }
internal PciMemory(uint id) { this.id = id; try { CompilerIntrinsics.Cli(); size = (int)NucleusCalls.PciMemSetup(id); } finally { CompilerIntrinsics.Sti(); } System.DebugStub.Print("PCI size = 0x" + size.ToString("X") + ". "); }
internal static void Print(char c) { CompilerIntrinsics.Cli(); NucleusCalls.VgaTextWrite(offset, (uint)(0x1e00 | c)); offset++; if (offset == 40 * 80) { offset = 80; } NucleusCalls.VgaTextWrite(offset, (uint)(0x3b00 | 33)); CompilerIntrinsics.Sti(); }
internal static void DebugPrintHex(uint screenOffset, uint hexMessage) { try { CompilerIntrinsics.Cli(); NucleusCalls.DebugPrintHex(screenOffset, hexMessage); } finally { CompilerIntrinsics.Sti(); } }
private void ThreadMain(uint id) { Thread t = threadTable[id]; CompilerIntrinsics.Sti(); t.start.Run(); CompilerIntrinsics.Cli(); t.alive = false; NucleusCalls.YieldTo(0); // Should never be reached: NucleusCalls.DebugPrintHex(0, 0xdead0002); while (true) { } }
public override void Run() { int nIter = 1048576; if (me == 0) { myId = Kernel.CurrentThread; Thread otherT = kernel.NewThread(other); uint otherId = otherT.id; kernel.Yield(); try { CompilerIntrinsics.Cli(); NucleusCalls.DebugPrintHex(50, 0); long t1 = NucleusCalls.Rdtsc(); for (int i = 0; i < nIter; i++) { NucleusCalls.YieldTo(otherId); } long t2 = NucleusCalls.Rdtsc(); uint diff = (uint)((t2 - t1) >> 20); NucleusCalls.DebugPrintHex(50, diff); } finally { CompilerIntrinsics.Sti(); } doneSemaphore.Signal(); } else { uint otherId = other.myId; kernel.Yield(); try { CompilerIntrinsics.Cli(); for (int i = 0; i < nIter; i++) { NucleusCalls.YieldTo(otherId); } } finally { CompilerIntrinsics.Sti(); } } }
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") + ". "); }
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) { } }
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(); }
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. }
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(); }