Ejemplo n.º 1
0
        private static void OnTimerInterrupt(FOS_System.Object state)
        {
#if SCHEDULER_HANDLER_TRACE || SCHEDULER_HANDLER_MIN_TRACE
            BasicConsole.Write("T");
#endif

            //LockupCounter++;

            //if (LockupCounter > 2000)
            //{
            //    Enable();
            //}

            if (!Enabled || !Initialised)
            {
                return;
            }

            //LockupCounter = 0;

#if SCHEDULER_HANDLER_TRACE || SCHEDULER_HANDLER_MIN_TRACE
            BasicConsole.Write("E");
#endif

            //UpdateCountdown -= MSFreq;

            //if (UpdateCountdown <= 0)
            //{
            //    UpdateCountdown = UpdatePeriod;
            UpdateCurrentState();
            //}
        }
Ejemplo n.º 2
0
        private static void EnterCritical(FOS_System.String caller)
        {
            //BasicConsole.WriteLine("Entering critical section...");
            if (AccessLockInitialised)
            {
                if (AccessLock == null)
                {
                    BasicConsole.WriteLine("HeapAccessLock is initialised but null?!");
                    BasicConsole.DelayOutput(10);
                }
                else
                {
                    if (AccessLock.Locked && OutputTrace)
                    {
                        BasicConsole.SetTextColour(BasicConsole.warning_colour);
                        BasicConsole.WriteLine("Warning: Heap about to try to re-enter spin lock...");
                        BasicConsole.Write("Enter lock caller: ");
                        BasicConsole.WriteLine(caller);
                        BasicConsole.SetTextColour(BasicConsole.default_colour);
                    }

                    AccessLock.Enter();
                }
            }
            //else
            //{
            //    BasicConsole.WriteLine("HeapAccessLock not initialised - ignoring lock conditions.");
            //    BasicConsole.DelayOutput(5);
            //}
        }
Ejemplo n.º 3
0
        public ELFFile(File file)
        {
            theFile = file;
            if (theFile == null)
            {
                Console.Default.ErrorColour();
                Console.Default.Write("Error constructing ELF file! theFile is null");
                BasicConsole.Write("Error constructing ELF file! theFile is null");
                if (file == null)
                {
                    Console.Default.Write(" and file is null");
                    BasicConsole.Write(" and file is null");
                }
                else
                {
                    Console.Default.Write(" and file is NOT null");
                    BasicConsole.Write(" and file is NOT null");
                }
                Console.Default.WriteLine(".");
                BasicConsole.WriteLine(".");
                Console.Default.DefaultColour();
                ExceptionMethods.Throw(new FOS_System.Exception("Error loading ELF file! Supplied file is null."));
            }
            theStream = new CachedFileStream(theFile.GetStream());
            ReadHeader();

            if (IsValidFile())
            {
                ReadSectionHeaders();
                ReadSegmentHeaders();
            }
        }
Ejemplo n.º 4
0
        public static void UpdateCurrentState()
        {
#if SCHEDULER_HANDLER_TRACE
            BasicConsole.SetTextColour(BasicConsole.warning_colour);

            if (Processes.ProcessManager.Processes.Count > 1)
            {
                BasicConsole.WriteLine("Scheduler interrupt started...");
            }
#endif

            if (ProcessManager.CurrentProcess == null ||
                ProcessManager.CurrentThread == null ||
                ProcessManager.CurrentThread_State == null)
            {
                return;
            }

            UpdateInactiveThreads();

            UpdateActiveThreads();

            while (ActiveQueue.Count == 0)
            {
                //#if SCHEDULER_HANDLER_TRACE
                BasicConsole.WriteLine("WARNING: Scheduler preventing infinite loop by early-updating sleeping threads.");
                //#endif
                UpdateInactiveThreads();
            }

            Thread nextThread = (Thread)ActiveQueue.PeekMin();
#if SCHEDULER_HANDLER_TRACE || SCHEDULER_HANDLER_MIN_TRACE
            BasicConsole.Write("Active: ");
            BasicConsole.Write(nextThread.Owner.Name);
            BasicConsole.Write(" - ");
            BasicConsole.WriteLine(nextThread.Name);
#endif
            ProcessManager.SwitchProcess(nextThread.Owner.Id, (int)nextThread.Id);

            if (!ProcessManager.CurrentThread_State->Started)
            {
                SetupThreadForStart();
            }

#if SCHEDULER_HANDLER_TRACE
            if (Processes.ProcessManager.Processes.Count > 1)
            {
                BasicConsole.WriteLine("Scheduler interrupt ended.");
            }

            BasicConsole.SetTextColour(BasicConsole.default_colour);
#endif
        }
Ejemplo n.º 5
0
        protected void AnalysePortStatus(byte j, ushort val)
        {
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Anaylse port status");
            BasicConsole.DelayOutput(5);
#endif

            HCPort port = GetPort(j);
            if ((val & UHCI_Consts.PORT_LOWSPEED_DEVICE) != 0)
            {
#if UHCI_TRACE
                BasicConsole.Write("UHCI: Lowspeed device");
#endif
                port.speed = USBPortSpeed.Low; // Save lowspeed/fullspeed information in data
            }
            else
            {
#if UHCI_TRACE
                BasicConsole.Write("UHCI: Fullspeed device");
#endif
                port.speed = USBPortSpeed.Full; // Save lowspeed/fullspeed information in data
            }

            if (((val & UHCI_Consts.PORT_CS) != 0) && !port.connected)
            {
#if UHCI_TRACE
                BasicConsole.WriteLine(" attached.");
#endif
                port.connected = true;
                ResetPort(j);      // reset on attached

                SetupUSBDevice(j);
            }
            else if (port.connected)
            {
#if UHCI_TRACE
                BasicConsole.WriteLine(" removed.");
#endif
                port.connected = false;

                if (port.deviceInfo != null)
                {
                    port.deviceInfo.FreePort();
                }
            }
#if UHCI_TRACE
            else
            {
                BasicConsole.WriteLine(" not attached.");
            }
#endif
        }
Ejemplo n.º 6
0
        public static void Main()
        {
            while (!Terminate)
            {
                //bool reenable = Hardware.Processes.Scheduler.Enabled;
                try
                {
                    //if (reenable)
                    //{
                    //    Hardware.Processes.Scheduler.Disable();
                    //}

#if GCTASK_TRACE
                    BasicConsole.SetTextColour(BasicConsole.warning_colour);
                    BasicConsole.Write("GC cleaning...");
                    BasicConsole.WriteLine(Hardware.Processes.ProcessManager.CurrentProcess.Name);
                    BasicConsole.SetTextColour(BasicConsole.default_colour);
#endif

                    FOS_System.GC.Cleanup();

#if GCTASK_TRACE
                    BasicConsole.SetTextColour(BasicConsole.warning_colour);
                    BasicConsole.WriteLine("GC stopped (1).");
                    BasicConsole.SetTextColour(BasicConsole.default_colour);
#endif
                }
                catch
                {
#if GCTASK_TRACE
                    BasicConsole.SetTextColour(BasicConsole.error_colour);
                    BasicConsole.WriteLine("GC error.");
                    BasicConsole.SetTextColour(BasicConsole.default_colour);
#endif
                }

#if GCTASK_TRACE
                BasicConsole.SetTextColour(BasicConsole.warning_colour);
                BasicConsole.WriteLine("GC stopped (2).");
                BasicConsole.SetTextColour(BasicConsole.default_colour);
#endif
                //if (reenable)
                //{
                //    Hardware.Processes.Scheduler.Enable();
                //}
                Processes.SystemCalls.SleepThread(1000);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Initializes all available partitions looking for valid
        /// file systems.
        /// </summary>
        public static void InitPartitions()
        {
            for (int i = 0; i < Partitions.Count; i++)
            {
                try
                {
                    Partition aPartition = (Partition)Partitions[i];
                    if (!aPartition.Mapped)
                    {
                        //BasicConsole.WriteLine("Attempting to create FAT File System...");
                        FileSystem newFS = null;
                        if (aPartition is Disk.ISO9660.PrimaryVolumeDescriptor)
                        {
                            newFS = new ISO9660.ISO9660FileSystem((Disk.ISO9660.PrimaryVolumeDescriptor)aPartition);
                        }
                        else
                        {
                            newFS = new FOS_System.IO.FAT.FATFileSystem(aPartition);
                        }

                        if (newFS.IsValid)
                        {
                            FOS_System.String mappingPrefix = FOS_System.String.New(3);
                            mappingPrefix[0] = (char)((int)('A') + i);
                            mappingPrefix[1] = ':';
                            mappingPrefix[2] = PathDelimiter;
                            newFS.TheMapping = new FileSystemMapping(mappingPrefix, newFS);
                            FileSystemMappings.Add(newFS.TheMapping);
                            aPartition.Mapped = true;
                        }
                        //else
                        //{
                        //    BasicConsole.WriteLine("Partition not formatted as valid FAT file-system.");
                        //}
                    }
                }
                catch
                {
                    BasicConsole.Write("Error initialising partition: ");
                    BasicConsole.WriteLine(i);
                    BasicConsole.WriteLine(ExceptionMethods.CurrentException.Message);
                    //BasicConsole.DelayOutput(20);
                }
            }
        }
Ejemplo n.º 8
0
        public void LoadSegments(ELFFile fileToLoadFrom, ref bool OK, ref bool DynamicLinkingRequired, uint memBaseAddress)
        {
            uint fileBaseAddress = fileToLoadFrom.BaseAddress;
            List Segments        = fileToLoadFrom.Segments;

            for (int i = 0; i < Segments.Count; i++)
            {
                ELFSegment segment = (ELFSegment)Segments[i];

                if (segment.Header.Type == ELFSegmentType.Interp ||
                    segment.Header.Type == ELFSegmentType.Dynamic)
                {
                    DynamicLinkingRequired = true;
                }
                else if (segment.Header.Type == ELFSegmentType.Load)
                {
                    int bytesRead = segment.Read(fileToLoadFrom.TheStream);
                    if (bytesRead != segment.Header.FileSize)
                    {
                        OK = false;
                        ExceptionMethods.Throw(new FOS_System.Exception("Error loading ELF segments! Failed to load correct segment bytes from file."));
                    }

                    byte *destMemPtr            = (segment.Header.VAddr - fileBaseAddress) + memBaseAddress;
                    byte *pageAlignedDestMemPtr = (byte *)((uint)destMemPtr & 0xFFFFF000);

                    Console.Default.Write(" Loading segment from ");
                    Console.Default.Write_AsDecimal((uint)segment.Header.VAddr);
                    Console.Default.Write(" to ");
                    Console.Default.WriteLine_AsDecimal((uint)destMemPtr);

                    BasicConsole.Write(" Loading segment from ");
                    BasicConsole.Write((uint)segment.Header.VAddr);
                    BasicConsole.Write(" to ");
                    BasicConsole.WriteLine((uint)destMemPtr);
                    Hardware.Processes.Thread.Sleep(1000);

                    uint copyOffset     = (uint)(destMemPtr - pageAlignedDestMemPtr);
                    uint copyFromOffset = 0;

                    bool executable = (segment.Header.Flags & ELFFlags.Executable) != 0;

                    for (uint pageOffset = 0; pageOffset < segment.Header.MemSize; pageOffset += 4096)
                    {
                        uint physPageAddr = Hardware.VirtMemManager.FindFreePhysPage();
                        uint virtPageAddr = (uint)pageAlignedDestMemPtr + pageOffset;

                        Hardware.VirtMemManager.Map(
                            physPageAddr,
                            virtPageAddr,
                            4096,
                            theProcess.UserMode ? Hardware.VirtMem.VirtMemImpl.PageFlags.None : Hardware.VirtMem.VirtMemImpl.PageFlags.KernelOnly);
                        ProcessManager.CurrentProcess.TheMemoryLayout.AddDataPage(physPageAddr, virtPageAddr);

                        if (executable)
                        {
                            theProcess.TheMemoryLayout.AddCodePage(physPageAddr, virtPageAddr);
                        }
                        else
                        {
                            theProcess.TheMemoryLayout.AddDataPage(physPageAddr, virtPageAddr);
                        }

                        uint copySize = FOS_System.Math.Min((uint)bytesRead, 4096 - copyOffset);
                        if (copySize > 0)
                        {
                            Utilities.MemoryUtils.MemCpy_32(
                                (byte *)(virtPageAddr + copyOffset),
                                ((byte *)Utilities.ObjectUtilities.GetHandle(segment.Data)) + FOS_System.Array.FieldsBytesSize + pageOffset - copyFromOffset,
                                copySize);

                            bytesRead -= (int)copySize;
                        }

                        for (uint j = copySize + copyOffset; j < 4096; j++)
                        {
                            *(byte *)(virtPageAddr + j) = 0;
                        }

                        if (copyOffset > 0)
                        {
                            copyFromOffset += copyOffset;
                            copyOffset      = 0;
                        }
                    }
                }
            }
        }
Ejemplo n.º 9
0
        public static void DeferredSyscallsThread_Main()
        {
            while (!Terminating)
            {
                if (DeferredSyscallsInfo_Queued.Count == 0)
                {
                    SystemCalls.SleepThread(SystemCalls.IndefiniteSleepThread);
                }

                while (DeferredSyscallsInfo_Queued.Count > 0)
                {
                    // Scheduler must be disabled during pop/push from circular buffer or we can
                    //  end up in an infinite lock. Consider what happens if a process invokes
                    //  a deferred system call during the pop/push here and at the end of this loop.
#if DSC_TRACE
                    BasicConsole.WriteLine("DSC: Pausing scheduler...");
#endif
                    Scheduler.Disable(/*"DSC 1"*/);
#if DSC_TRACE
                    BasicConsole.WriteLine("DSC: Popping queued info object...");
#endif
                    DeferredSyscallInfo info = (DeferredSyscallInfo)DeferredSyscallsInfo_Queued.Pop();
#if DSC_TRACE
                    BasicConsole.WriteLine("DSC: Resuming scheduler...");
#endif
                    Scheduler.Enable();

#if DSC_TRACE
                    BasicConsole.WriteLine("DSC: Getting process & thread...");
#endif
                    Process CallerProcess = ProcessManager.GetProcessById(info.ProcessId);
                    Thread  CallerThread  = ProcessManager.GetThreadById(info.ThreadId, CallerProcess);

#if DSC_TRACE
                    BasicConsole.Write("DSC: Process: ");
                    BasicConsole.WriteLine(CallerProcess.Name);
                    BasicConsole.Write("DSC: Thread: ");
                    BasicConsole.WriteLine(CallerThread.Name);
#endif

                    ProcessManager.EnableKernelAccessToProcessMemory(CallerProcess);

#if DSC_TRACE
                    BasicConsole.WriteLine("DSC: Getting data...");
#endif
                    SystemCallNumbers SysCallNumber = (SystemCallNumbers)CallerThread.SysCallNumber;
                    uint Param1  = CallerThread.Param1;
                    uint Param2  = CallerThread.Param2;
                    uint Param3  = CallerThread.Param3;
                    uint Return2 = CallerThread.Return2;
                    uint Return3 = CallerThread.Return3;
                    uint Return4 = CallerThread.Return4;
#if DSC_TRACE
                    BasicConsole.WriteLine("DSC: Getting data done.");
#endif
                    ProcessManager.DisableKernelAccessToProcessMemory(CallerProcess);

#if DSC_TRACE
                    BasicConsole.WriteLine("DSC: Calling...");
#endif
                    SystemCallResults result = HandleDeferredSystemCall(
                        CallerProcess, CallerThread,
                        SysCallNumber, Param1, Param2, Param3,
                        ref Return2, ref Return3, ref Return4);

#if DSC_TRACE
                    BasicConsole.WriteLine("DSC: Ending call...");
#endif
                    if (result != SystemCallResults.Deferred)
                    {
                        EndDeferredSystemCall(CallerProcess, CallerThread, result, Return2, Return3, Return4);
                    }

#if DSC_TRACE
                    BasicConsole.WriteLine("DSC: Resetting info object...");
#endif
                    info.ProcessId = 0;
                    info.ThreadId  = 0;

                    // See comment at top of loop for why this is necessary
#if DSC_TRACE
                    BasicConsole.WriteLine("DSC: Pausing scheduler...");
#endif
                    Scheduler.Disable(/*"DSC 2"*/);
#if DSC_TRACE
                    BasicConsole.WriteLine("DSC: Queuing info object...");
#endif
                    DeferredSyscallsInfo_Unqueued.Push(info);
#if DSC_TRACE
                    BasicConsole.WriteLine("DSC: Resuming scheduler...");
#endif
                    Scheduler.Enable();
                }
            }
        }
Ejemplo n.º 10
0
        public static void *Alloc(UInt32 size, UInt32 boundary, FOS_System.String caller)
        {
#if HEAP_TRACE
            if (OutputTrace)
            {
                BasicConsole.SetTextColour(BasicConsole.warning_colour);
                BasicConsole.WriteLine("Attempt to alloc mem....");
                BasicConsole.SetTextColour(BasicConsole.default_colour);
            }
#endif

            if (PreventAllocation)
            {
                bool BCPOEnabled = BasicConsole.PrimaryOutputEnabled;
                BasicConsole.PrimaryOutputEnabled = true;
                BasicConsole.SetTextColour(BasicConsole.error_colour);
                BasicConsole.Write("Allocation of memory prevented! Reason: ");
                BasicConsole.WriteLine(PreventReason);
                BasicConsole.Write("    > Caller: ");
                BasicConsole.WriteLine(caller);
                BasicConsole.DelayOutput(5);
                BasicConsole.SetTextColour(BasicConsole.default_colour);
                BasicConsole.PrimaryOutputEnabled = BCPOEnabled;
                return(null);
            }

            EnterCritical("Alloc");

            HeapBlock *b;
            byte *     bm;
            UInt32     bcnt;
            UInt32     x, y, z;
            UInt32     bneed;
            byte       nid;

            if (boundary > 1)
            {
                size += (boundary - 1);
            }

            /* iterate blocks */
            for (b = fblock; (UInt32)b != 0; b = b->next)
            {
                /* check if block has enough room */
                if (b->size - (b->used * b->bsize) >= size)
                {
                    bcnt  = b->size / b->bsize;
                    bneed = (size / b->bsize) * b->bsize < size ? size / b->bsize + 1 : size / b->bsize;
                    bm    = (byte *)&b[1];

                    for (x = (b->lfb + 1 >= bcnt ? 0 : b->lfb + 1); x != b->lfb; ++x)
                    {
                        /* just wrap around */
                        if (x >= bcnt)
                        {
                            x = 0;
                        }

                        if (bm[x] == 0)
                        {
                            /* count free blocks */
                            for (y = 0; bm[x + y] == 0 && y < bneed && (x + y) < bcnt; ++y)
                            {
                                ;
                            }

                            /* we have enough, now allocate them */
                            if (y == bneed)
                            {
                                /* find ID that does not match left or right */
                                nid = GetNID(bm[x - 1], bm[x + y]);

                                /* allocate by setting id */
                                for (z = 0; z < y; ++z)
                                {
                                    bm[x + z] = nid;
                                }

                                /* optimization */
                                b->lfb = (x + bneed) - 2;

                                /* count used blocks NOT bytes */
                                b->used += y;

                                void *result = (void *)(x * b->bsize + (UInt32)(&b[1]));
                                if (boundary > 1)
                                {
                                    result = (void *)((((UInt32)result) + (boundary - 1)) & ~(boundary - 1));

//#if HEAP_TRACE
//                                    ExitCritical();
//                                    BasicConsole.WriteLine(((FOS_System.String)"Allocated address ") + (uint)result + " on boundary " + boundary + " for " + caller);
//                                    EnterCritical("Alloc:Boundary condition");
//#endif
                                }

                                ExitCritical();
                                return(result);
                            }

                            /* x will be incremented by one ONCE more in our FOR loop */
                            x += (y - 1);
                            continue;
                        }
                    }
                }
            }

            {
                bool BCPOEnabled = BasicConsole.PrimaryOutputEnabled;
                BasicConsole.PrimaryOutputEnabled = true;
                BasicConsole.Write("Heap (");
                BasicConsole.Write(name);
                BasicConsole.WriteLine(") out of memory!");
                if (fblock == null)
                {
                    BasicConsole.WriteLine(" !! fblock == null");
                }
                else if (GetTotalFreeMem() < size)
                {
                    if (GetTotalMem() == 0)
                    {
                        BasicConsole.WriteLine(" !! Out of free mem because total mem is zero.");
                    }
                    else if (GetTotalMem() <= 8092)
                    {
                        BasicConsole.WriteLine(" !! Out of free mem because total mem is <= 8092 bytes.");
                    }
                    else
                    {
                        BasicConsole.WriteLine(" !! Genuinely out of memory.");
                    }
                }
                BasicConsole.PrimaryOutputEnabled = BCPOEnabled;
            }

            ExitCritical();

            return(null);
        }
Ejemplo n.º 11
0
        public override void MapKernel()
        {
#if PAGING_TRACE
            BasicConsole.Write("Mapping 1st 1MiB...");
#endif

            uint VirtToPhysOffset = GetKernelVirtToPhysOffset();

            //Identity and virtual map the first 1MiB
            uint physAddr = 0;
            uint virtAddr = VirtToPhysOffset;
            for (; physAddr < 0x100000; physAddr += 4096, virtAddr += 4096)
            {
                Map(physAddr, physAddr, PageFlags.Present | PageFlags.Writeable);
                Map(physAddr, virtAddr, PageFlags.Present | PageFlags.Writeable);
            }

#if PAGING_TRACE
            BasicConsole.WriteLine("Done.");
            BasicConsole.WriteLine("Mapping kernel...");
#endif

            //Map in the main kernel memory

            //Map all the required pages in between these two pointers.
            uint KernelMemStartPtr = (uint)GetKernelMemStartPtr();
            uint KernelMemEndPtr   = (uint)GetKernelMemEndPtr();

#if PAGING_TRACE
            BasicConsole.WriteLine("Start pointer : " + (FOS_System.String)KernelMemStartPtr);
            BasicConsole.WriteLine("End pointer : " + (FOS_System.String)KernelMemEndPtr);
#endif

            // Round the start pointer down to nearest page
            KernelMemStartPtr = ((KernelMemStartPtr / 4096) * 4096);

            // Round the end pointer up to nearest page
            KernelMemEndPtr = (((KernelMemEndPtr / 4096) + 1) * 4096);

#if PAGING_TRACE
            BasicConsole.WriteLine("Start pointer : " + (FOS_System.String)KernelMemStartPtr);
            BasicConsole.WriteLine("End pointer : " + (FOS_System.String)KernelMemEndPtr);
#endif

            physAddr = KernelMemStartPtr - VirtToPhysOffset;

#if PAGING_TRACE
            BasicConsole.WriteLine("Phys addr : " + (FOS_System.String)physAddr);
            BasicConsole.DelayOutput(5);
#endif

            for (; KernelMemStartPtr <= KernelMemEndPtr; KernelMemStartPtr += 4096, physAddr += 4096)
            {
                Map(physAddr, KernelMemStartPtr, PageFlags.Present | PageFlags.Writeable | PageFlags.KernelOnly);
            }

#if PAGING_TRACE
            BasicConsole.WriteLine("Done.");
            BasicConsole.DelayOutput(5);
#endif
        }
Ejemplo n.º 12
0
        public static void Main()
        {
            OwnerThread = ProcessManager.CurrentThread;

            Thread.Sleep_Indefinitely();

            while (!Terminate)
            {
                //Scheduler.Disable();
                Awake = false;

                //BasicConsole.WriteLine("Playing notes...");

                while (LiveNoteRequests.Count > 0)
                {
                    //BasicConsole.WriteLine("Playing note...");

                    NoteRequest theReq = (NoteRequest)LiveNoteRequests.Pop();

                    try
                    {
                        Hardware.Timers.PIT.MusicalNote      note     = theReq.note;
                        Hardware.Timers.PIT.MusicalNoteValue duration = theReq.duration;
                        int bpm = theReq.bpm;

                        int  dur_ms = (int)duration * 60 * 1000 / (bpm * 16);
                        long do_ms  = dur_ms;
                        if (dur_ms >= 2000)
                        {
                            dur_ms -= 2000;
                            do_ms   = 2000;
                        }
                        else
                        {
                            dur_ms = 0;
                        }
                        NoteState state = new NoteState()
                        {
                            dur_ms = dur_ms
                        };

                        if (note != Timers.PIT.MusicalNote.Silent)
                        {
                            Hardware.Timers.PIT.ThePIT.PlaySound((int)note);
                        }

                        Playing = true;

                        state.handlerId = Hardware.Timers.PIT.ThePIT.RegisterHandler(new Hardware.Timers.PITHandler(SysCall_StopNoteHandler, state, 1000000L * do_ms, true));

                        while (Playing)
                        {
                            Thread.Sleep(50);
                        }
                    }
                    catch
                    {
                        BasicConsole.Write("Error processing note request! ");
                        if (ExceptionMethods.CurrentException != null)
                        {
                            BasicConsole.Write(ExceptionMethods.CurrentException.Message);
                        }
                        BasicConsole.WriteLine();
                        Playing = false;
                        Hardware.Timers.PIT.ThePIT.MuteSound();
                        BasicConsole.DelayOutput(15);
                    }
                    finally
                    {
                        DeadNoteRequests.Push(theReq);
                    }
                }

                //BasicConsole.WriteLine("Finished playing notes.");

                if (!Awake)
                {
                    //BasicConsole.WriteLine("Sleeping non-critical interrupts thread...");

                    //Scheduler.Enable();
                    if (!Thread.Sleep_Indefinitely())
                    {
                        BasicConsole.SetTextColour(BasicConsole.error_colour);
                        BasicConsole.WriteLine("Failed to sleep play notes thread!");
                        BasicConsole.SetTextColour(BasicConsole.default_colour);
                    }
                }
            }
        }
Ejemplo n.º 13
0
        protected override void _IssueTransfer(USBTransfer transfer)
        {
#if UHCI_TRACE
            BasicConsole.WriteLine("UHCI: Issue Transfer");
            BasicConsole.DelayOutput(5);
#endif

            UHCITransaction firstTransaction = (UHCITransaction)((USBTransaction)transfer.transactions[0]).underlyingTz;
            UHCITransaction lastTransaction  = (UHCITransaction)((USBTransaction)transfer.transactions[transfer.transactions.Count - 1]).underlyingTz;
            UHCI_qTD.SetIntOnComplete(lastTransaction.qTD, true);  // We want an interrupt after complete transfer
            CreateQH((UHCI_QueueHead_Struct *)transfer.underlyingTransferData, (uint)transfer.underlyingTransferData, firstTransaction.qTD);

#if UHCI_TRACE
            BasicConsole.WriteLine("    Queue head data:");
            BasicConsole.DumpMemory(transfer.underlyingTransferData, sizeof(UHCI_QueueHead_Struct));
            BasicConsole.WriteLine("    Transactions data:");
            for (int i = 0; i < transfer.transactions.Count; i++)
            {
                BasicConsole.Write(" ");
                BasicConsole.Write(i);
                BasicConsole.WriteLine(" : ");
                BasicConsole.WriteLine("  - qTD:");
                BasicConsole.DumpMemory(
                    ((UHCITransaction)((USBTransaction)transfer.transactions[i]).underlyingTz).qTD, sizeof(UHCI_qTD_Struct));
                BasicConsole.WriteLine("  - qTDBuffer:");
                BasicConsole.DumpMemory(
                    ((UHCITransaction)((USBTransaction)transfer.transactions[i]).underlyingTz).qTDBuffer, 16);
            }
            BasicConsole.DelayOutput(60);

            BasicConsole.WriteLine("UHCI: Issuing transfer...");
#endif

            for (byte i = 0; i < UHCI_Consts.NUMBER_OF_UHCI_RETRIES && !transfer.success; i++)
            {
                TransactionsCompleted = 0;
                for (int j = 0; j < transfer.transactions.Count; j++)
                {
                    USBTransaction  elem = (USBTransaction)transfer.transactions[j];
                    UHCITransaction uT   = (UHCITransaction)(elem.underlyingTz);
                    uT.qTD->u1 = uT.qTD->u1 & 0xFF00FFFF;
                    UHCI_qTD.SetActive(uT.qTD, true);
                }

                // stop scheduler
                USBSTS.Write_UInt16(UHCI_Consts.STS_MASK);
                USBCMD.Write_UInt16((ushort)(USBCMD.Read_UInt16() & ~UHCI_Consts.CMD_RS));
                while ((USBSTS.Read_UInt16() & UHCI_Consts.STS_HCHALTED) == 0)
                {
                    Hardware.Devices.Timer.Default.Wait(10);
                }

                // update scheduler
                uint qhPhysAddr = ((uint)VirtMemManager.GetPhysicalAddress(transfer.underlyingTransferData) | UHCI_Consts.BIT_QH);
                FrameList[0] = qhPhysAddr;
                FRBASEADD.Write_UInt32((uint)VirtMemManager.GetPhysicalAddress(FrameList));
                FRNUM.Write_UInt16(0);
                // start scheduler
                USBSTS.Write_UInt16(UHCI_Consts.STS_MASK);
                USBCMD.Write_UInt16((ushort)(USBCMD.Read_UInt16() | UHCI_Consts.CMD_RS));
                while ((USBSTS.Read_UInt16() & UHCI_Consts.STS_HCHALTED) != 0)
                {
                    Hardware.Devices.Timer.Default.Wait(10);
                }

#if UHCI_TRACE
                BasicConsole.WriteLine(((FOS_System.String) "USBINT val: ") + USBINTR.Read_UInt16());
#endif

                // run transactions
                bool active  = true;
                int  timeout = 100; //5 seconds
                while (active && timeout > 0)
                {
                    active = false;
                    for (int j = 0; j < transfer.transactions.Count; j++)
                    {
                        USBTransaction  elem = (USBTransaction)transfer.transactions[j];
                        UHCITransaction uT   = (UHCITransaction)(elem.underlyingTz);
                        active = active || ((uT.qTD->u1 & 0x00FF0000) == 0x00800000);
                    }

                    Hardware.Devices.Timer.Default.Wait(50);
                    timeout--;
                }

#if UHCI_TRACE
                BasicConsole.WriteLine("Finished waiting.");
#endif

                FrameList[0] = UHCI_Consts.BIT_T;

                if (timeout == 0 ||
                    TransactionsCompleted != transfer.transactions.Count)
                {
#if UHCI_TRACE
                    BasicConsole.SetTextColour(BasicConsole.error_colour);
                    BasicConsole.WriteLine("UHCI: Error! Transactions wait timed out or wrong number of transactions completed.");
                    BasicConsole.SetTextColour(BasicConsole.default_colour);

                    BasicConsole.WriteLine(((FOS_System.String) "Transactions completed: ") + TransactionsCompleted);

                    if (timeout == 0)
                    {
                        BasicConsole.SetTextColour(BasicConsole.error_colour);
                        BasicConsole.WriteLine("UHCI: Error! Transfer timed out.");
                        BasicConsole.SetTextColour(BasicConsole.default_colour);
                    }
#endif

                    transfer.success = false;

                    bool completeDespiteNoInterrupt = true;
                    for (int j = 0; j < transfer.transactions.Count; j++)
                    {
                        USBTransaction  elem = (USBTransaction)transfer.transactions[j];
                        UHCITransaction uT   = (UHCITransaction)(elem.underlyingTz);

#if UHCI_TRACE
                        BasicConsole.WriteLine(((FOS_System.String) "u1=") + uT.qTD->u1 + ", u2=" + uT.qTD->u2);
                        BasicConsole.WriteLine(((FOS_System.String) "Status=") + (byte)(uT.qTD->u1 >> 16));
#endif
                        completeDespiteNoInterrupt = completeDespiteNoInterrupt && isTransactionSuccessful(uT);
                    }

                    transfer.success = completeDespiteNoInterrupt;

#if UHCI_TRACE
                    BasicConsole.SetTextColour(BasicConsole.warning_colour);
                    BasicConsole.WriteLine(((FOS_System.String) "Complete despite no interrupts: ") + completeDespiteNoInterrupt);
                    BasicConsole.SetTextColour(BasicConsole.default_colour);

                    BasicConsole.DelayOutput(5);
#endif
                }
                else
                {
                    transfer.success = true;
                }

                if (transfer.success)
                {
                    // check conditions and save data
                    for (int j = 0; j < transfer.transactions.Count; j++)
                    {
                        USBTransaction  elem = (USBTransaction)transfer.transactions[j];
                        UHCITransaction uT   = (UHCITransaction)(elem.underlyingTz);
                        transfer.success = transfer.success && isTransactionSuccessful(uT); // executed w/o error

                        if (uT.inBuffer != null && uT.inLength != 0)
                        {
                            MemoryUtils.MemCpy_32((byte *)uT.inBuffer, (byte *)uT.qTDBuffer, uT.inLength);
                        }
                    }
                }

#if UHCI_TRACE
                if (!transfer.success)
                {
                    BasicConsole.SetTextColour(BasicConsole.error_colour);
                    BasicConsole.WriteLine("UHCI: Transfer failed.");
                    BasicConsole.SetTextColour(BasicConsole.default_colour);
                }
                else
                {
                    BasicConsole.SetTextColour((char)0x0200);
                    BasicConsole.WriteLine("Transfer succeeded.");
                    BasicConsole.SetTextColour(BasicConsole.default_colour);
                }
#endif
            }
        }
Ejemplo n.º 14
0
        public static void Main()
        {
            BasicConsole.WriteLine("Window Manager: Started.");

            // Initialise heap & GC
            Hardware.Processes.ProcessManager.CurrentProcess.InitHeap();

            // Start thread for calling GC Cleanup method
            if (SystemCalls.StartThread(GCCleanupTask.Main, out GCThreadId) != SystemCallResults.OK)
            {
                BasicConsole.WriteLine("Window Manager: GC thread failed to create!");
            }

            // Initialise connected pipes list
            ConnectedPipes = new List();

            // Start thread for handling background input processing
            if (SystemCalls.StartThread(InputProcessing, out InputProcessingThreadId) != SystemCallResults.OK)
            {
                BasicConsole.WriteLine("Window Manager: InputProcessing thread failed to create!");
            }

            BasicConsole.Write("WM > InputProcessing thread id: ");
            BasicConsole.WriteLine(InputProcessingThreadId);

            BasicConsole.Write("WM > Register RegisterPipeOutpoint syscall handler");
            SystemCalls.RegisterSyscallHandler(SystemCallNumbers.RegisterPipeOutpoint, SyscallHandler);


            // Start thread for handling background output processing
            if (SystemCalls.StartThread(OutputProcessing, out OutputProcessingThreadId) != SystemCallResults.OK)
            {
                BasicConsole.WriteLine("Window Manager: OutputProcessing thread failed to create!");
            }

            BasicConsole.WriteLine("WM > Init keyboard");
            Keyboard.InitDefault();
            BasicConsole.WriteLine("WM > Register IRQ 1 handler");
            SystemCalls.RegisterIRQHandler(1, HandleIRQ);

            BasicConsole.WriteLine("WM > Wait for pipe to be created");
            // Wait for pipe to be created
            ready_count++;
            SystemCalls.SleepThread(SystemCalls.IndefiniteSleepThread);

            PipeInfo CurrentPipeInfo = null;

            while (!Terminating)
            {
                try
                {
                    if (CurrentPipeIdx > -1)
                    {
                        if (CurrentPipeIndex_Changed)
                        {
                            CurrentPipeInfo          = ((PipeInfo)ConnectedPipes[CurrentPipeIdx]);
                            CurrentPipeIndex_Changed = false;

                            CurrentPipeInfo.TheConsole.Update();
                        }

                        CurrentPipeInfo.TheConsole.Write(CurrentPipeInfo.StdOut.Read(false));
                    }
                }
                catch
                {
                    if (ExceptionMethods.CurrentException is Pipes.Exceptions.RWFailedException)
                    {
                        SystemCalls.SleepThread(50);
                    }
                    else
                    {
                        BasicConsole.WriteLine("WM > Exception running window manager.");
                        BasicConsole.WriteLine(ExceptionMethods.CurrentException.Message);
                    }
                }
            }
        }
Ejemplo n.º 15
0
        public static void *NewObj(FOS_System.Type theType)
        {
            if (!Enabled)
            {
                BasicConsole.SetTextColour(BasicConsole.warning_colour);
                BasicConsole.WriteLine("Warning! GC returning null pointer because GC not enabled.");
                BasicConsole.Write("Last disabler: ");
                BasicConsole.WriteLine(lastDisabler);
                BasicConsole.DelayOutput(10);
                BasicConsole.SetTextColour(BasicConsole.default_colour);

                return(null);
            }

#if GC_TRACE
            if (OutputTrace)
            {
                BasicConsole.WriteLine("NewObj");
            }
#endif

            EnterCritical("NewObj");

            try
            {
                InsideGC = true;

                //Alloc space for GC header that prefixes object data
                //Alloc space for new object

                uint totalSize = theType.Size;
                totalSize += (uint)sizeof(GCHeader);

                GCHeader *newObjPtr = (GCHeader *)Heap.AllocZeroed(totalSize, "GC : NewObject");

                if ((UInt32)newObjPtr == 0)
                {
                    InsideGC = false;

                    BasicConsole.SetTextColour(BasicConsole.error_colour);
                    BasicConsole.WriteLine("Error! GC can't create a new object because the heap returned a null pointer.");
                    BasicConsole.DelayOutput(10);
                    BasicConsole.SetTextColour(BasicConsole.default_colour);

                    return(null);
                }

                NumObjs++;

                //Initialise the GCHeader
                SetSignature(newObjPtr);
                newObjPtr->RefCount = 1;
                //Initialise the object _Type field
                FOS_System.ObjectWithType newObj = (FOS_System.ObjectWithType)Utilities.ObjectUtilities.GetObject(newObjPtr + 1);
                newObj._Type = theType;

                //Move past GCHeader
                byte *newObjBytePtr = (byte *)(newObjPtr + 1);

                InsideGC = false;

                return(newObjBytePtr);
            }
            finally
            {
                ExitCritical();
            }
        }
Ejemplo n.º 16
0
        public static void *NewArr(int length, FOS_System.Type elemType)
        {
            if (!Enabled)
            {
                BasicConsole.SetTextColour(BasicConsole.warning_colour);
                BasicConsole.WriteLine("Warning! GC returning null pointer because GC not enabled.");
                BasicConsole.Write("Last disabler: ");
                BasicConsole.WriteLine(lastDisabler);
                BasicConsole.DelayOutput(10);
                BasicConsole.SetTextColour(BasicConsole.default_colour);

                return(null);
            }

#if GC_TRACE
            if (OutputTrace)
            {
                BasicConsole.WriteLine("NewArr");
            }
#endif

            EnterCritical("NewArr");

            try
            {
                if (length < 0)
                {
                    ExceptionMethods.Throw_OverflowException();
                }

                InsideGC = true;

                //Alloc space for GC header that prefixes object data
                //Alloc space for new array object
                //Alloc space for new array elems

                uint totalSize = ((FOS_System.Type) typeof(FOS_System.Array)).Size;
                if (elemType.IsValueType)
                {
                    totalSize += elemType.Size * (uint)length;
                }
                else
                {
                    totalSize += elemType.StackSize * (uint)length;
                }
                totalSize += (uint)sizeof(GCHeader);

                GCHeader *newObjPtr = (GCHeader *)Heap.AllocZeroed(totalSize, "GC : NewArray");

                if ((UInt32)newObjPtr == 0)
                {
                    InsideGC = false;

                    BasicConsole.SetTextColour(BasicConsole.error_colour);
                    BasicConsole.WriteLine("Error! GC can't create a new array because the heap returned a null pointer.");
                    BasicConsole.DelayOutput(10);
                    BasicConsole.SetTextColour(BasicConsole.default_colour);

                    return(null);
                }

                NumObjs++;

                //Initialise the GCHeader
                SetSignature(newObjPtr);
                newObjPtr->RefCount = 1;

                FOS_System.Array newArr = (FOS_System.Array)Utilities.ObjectUtilities.GetObject(newObjPtr + 1);
                newArr._Type    = (FOS_System.Type) typeof(FOS_System.Array);
                newArr.length   = length;
                newArr.elemType = elemType;

                //Move past GCHeader
                byte *newObjBytePtr = (byte *)(newObjPtr + 1);

                InsideGC = false;

                return(newObjBytePtr);
            }
            finally
            {
                ExitCritical();
            }
        }
Ejemplo n.º 17
0
        private static void UpdateList(Thread t, bool skipRemove)
        {
            Scheduler.Disable(/*"Scheduler UpdateList"*/);

#if SCHEDULER_UPDATE_LIST_TRACE
            BasicConsole.Write("S > UpdateList: ");
            BasicConsole.WriteLine(t.Name);
#endif
            if (!skipRemove)
            {
#if SCHEDULER_UPDATE_LIST_TRACE
                BasicConsole.WriteLine("S > UpdateList: No skip remove");
#endif
                switch (t.LastActiveState)
                {
                case Thread.ActiveStates.NotStarted:
#if SCHEDULER_UPDATE_LIST_TRACE
                    BasicConsole.WriteLine("S > UpdateList: LastActiveState: NotStarted");
#endif
                    ActiveQueue.Delete(t);
                    break;

                case Thread.ActiveStates.Terminated:
#if SCHEDULER_UPDATE_LIST_TRACE
                    BasicConsole.WriteLine("S > UpdateList: LastActiveState: Terminated");
#endif
                    break;

                case Thread.ActiveStates.Active:
#if SCHEDULER_TRACE
                    BasicConsole.WriteLine("Scheduler > Deleting thread from Active queue...");
#endif
                    //try
                    //{
#if SCHEDULER_UPDATE_LIST_TRACE
                    BasicConsole.WriteLine("S > UpdateList: LastActiveState: Active (1x1)");
#endif
                    ActiveQueue.Delete(t);
#if SCHEDULER_UPDATE_LIST_TRACE
                    BasicConsole.WriteLine("S > UpdateList: LastActiveState: Active - done.");
#endif
                    //}
                    //catch
                    //{
                    //    BasicConsole.WriteLine("Error removing from active list:");
                    //    BasicConsole.WriteLine(ExceptionMethods.CurrentException.Message);
                    //}
                    break;

                case Thread.ActiveStates.Inactive:
#if SCHEDULER_UPDATE_LIST_TRACE
                    BasicConsole.WriteLine("S > UpdateList: LastActiveState: Inactive");
#endif
                    InactiveQueue.Delete(t);
                    break;

                case Thread.ActiveStates.Suspended:
#if SCHEDULER_UPDATE_LIST_TRACE
                    BasicConsole.WriteLine("S > UpdateList: LastActiveState: Suspended");
#endif
                    //SuspendedList.Remove(t);
                    break;
                }
            }

#if SCHEDULER_UPDATE_LIST_TRACE
            BasicConsole.WriteLine("S > UpdateList: Handling active state");
#endif
            switch (t.ActiveState)
            {
            case Thread.ActiveStates.NotStarted:
#if SCHEDULER_UPDATE_LIST_TRACE
                BasicConsole.WriteLine("S > UpdateList: ActiveState: Not Started");
#endif
                //if (!ActiveQueue.Insert(t))
                //{
                //    BasicConsole.WriteLine(t.Name);
                //}
                ActiveQueue.Insert(t);
                break;

            case Thread.ActiveStates.Terminated:
#if SCHEDULER_UPDATE_LIST_TRACE
                BasicConsole.WriteLine("S > UpdateList: ActiveState: Terminated");
#endif
                break;

            case Thread.ActiveStates.Active:
#if SCHEDULER_UPDATE_LIST_TRACE
                BasicConsole.WriteLine("S > UpdateList: ActiveState: Active");
#endif
                //if (!ActiveQueue.Insert(t))
                //{
                //    BasicConsole.WriteLine(t.Name);
                //}
                ActiveQueue.Insert(t);
                break;

            case Thread.ActiveStates.Inactive:
#if SCHEDULER_UPDATE_LIST_TRACE
                BasicConsole.WriteLine("S > UpdateList: ActiveState: Inactive");
#endif
                //if (!InactiveQueue.Insert(t))
                //{
                //    BasicConsole.WriteLine(t.Name);
                //}
                InactiveQueue.Insert(t);
                break;

            case Thread.ActiveStates.Suspended:
#if SCHEDULER_UPDATE_LIST_TRACE
                BasicConsole.WriteLine("S > UpdateList: ActiveState: Suspended");
#endif
                //SuspendedList.Add(t);
                break;
            }
#if SCHEDULER_UPDATE_LIST_TRACE
            BasicConsole.WriteLine("S > UpdateList: Done.");
#endif
            Scheduler.Enable();
        }
Ejemplo n.º 18
0
        public bool IsValidFile()
        {
            #region CHECK : Signature
            if (!CheckSiganture())
            {
                Console.Default.WarningColour();
                Console.Default.WriteLine("ELF signature check failed!");
                Console.Default.DefaultColour();

                BasicConsole.WriteLine("ELF signature check failed!");
                return(false);
            }
            else
            {
                Console.Default.Colour(0x2F);
                Console.Default.WriteLine("ELF signature check passed.");
                Console.Default.DefaultColour();

                BasicConsole.WriteLine("ELF signature check passed.");
            }
            #endregion
            #region CHECK : File Class
            if (!CheckFileClass())
            {
                Console.Default.WarningColour();
                Console.Default.WriteLine("ELF file class check failed!");
                Console.Default.DefaultColour();

                BasicConsole.WriteLine("ELF file class check failed!");
                return(false);
            }
            else
            {
                Console.Default.Colour(0x2F);
                Console.Default.WriteLine("ELF file class check passed.");
                Console.Default.DefaultColour();

                BasicConsole.WriteLine("ELF file class check passed.");
            }
            #endregion
            #region CHECK : Data Encoding
            if (!CheckDataEncoding())
            {
                Console.Default.WarningColour();
                Console.Default.WriteLine("ELF data encoding check failed!");
                Console.Default.DefaultColour();

                BasicConsole.WriteLine("ELF data encoding check failed!");
                return(false);
            }
            else
            {
                Console.Default.Colour(0x2F);
                Console.Default.WriteLine("ELF data encoding check passed.");
                Console.Default.DefaultColour();

                BasicConsole.WriteLine("ELF data encoding check passed.");
            }
            #endregion
            #region CHECK : File Type
            if (!CheckFileType())
            {
                Console.Default.WarningColour();
                Console.Default.WriteLine("ELF file type check failed!");
                Console.Default.DefaultColour();

                BasicConsole.WriteLine("ELF file type check failed!");
                return(false);
            }
            else
            {
                Console.Default.Colour(0x2F);
                Console.Default.WriteLine("ELF file type check passed.");
                Console.Default.DefaultColour();

                BasicConsole.WriteLine("ELF file type check passed.");
            }
            #endregion
            #region CHECK : Machine
            if (!CheckMachine())
            {
                Console.Default.WarningColour();
                Console.Default.WriteLine("ELF machine check failed!");
                Console.Default.DefaultColour();

                BasicConsole.WriteLine("ELF machine check failed!");
                return(false);
            }
            else
            {
                Console.Default.Colour(0x2F);
                Console.Default.WriteLine("ELF machine check passed.");
                Console.Default.DefaultColour();

                BasicConsole.WriteLine("ELF machine check passed.");
            }
            #endregion
            #region INFO : Header Version
            Console.Default.Write("ELF Header version: ");
            Console.Default.WriteLine_AsDecimal(Header.HeaderVersion);

            BasicConsole.Write("ELF Header version: ");
            BasicConsole.WriteLine(Header.HeaderVersion);
            #endregion

            return(true);
        }
Ejemplo n.º 19
0
        public static void *NewString(int length)
        {
            if (!Enabled)
            {
                BasicConsole.SetTextColour(BasicConsole.warning_colour);
                BasicConsole.WriteLine("Warning! GC returning null pointer because GC not enabled.");
                BasicConsole.Write("Last disabler: ");
                BasicConsole.WriteLine(lastDisabler);
                BasicConsole.DelayOutput(10);
                BasicConsole.SetTextColour(BasicConsole.default_colour);

                return(null);
            }

#if GC_TRACE
            if (OutputTrace)
            {
                BasicConsole.WriteLine("NewString");
            }
#endif

            EnterCritical("NewString");

            try
            {
                if (length < 0)
                {
                    BasicConsole.SetTextColour(BasicConsole.error_colour);
                    BasicConsole.WriteLine("Error! GC can't create a new string because \"length\" is less than 0.");
                    BasicConsole.DelayOutput(5);
                    BasicConsole.SetTextColour(BasicConsole.default_colour);

                    ExceptionMethods.Throw_OverflowException();
                }

                InsideGC = true;

                //Alloc space for GC header that prefixes object data
                //Alloc space for new string object
                //Alloc space for new string chars

                uint totalSize = ((FOS_System.Type) typeof(FOS_System.String)).Size;
                totalSize += /*char size in bytes*/ 2 * (uint)length;
                totalSize += (uint)sizeof(GCHeader);

                GCHeader *newObjPtr = (GCHeader *)Heap.AllocZeroed(totalSize, "GC : NewString");

                if ((UInt32)newObjPtr == 0)
                {
                    InsideGC = false;

                    BasicConsole.SetTextColour(BasicConsole.error_colour);
                    BasicConsole.WriteLine("Error! GC can't create a new string because the heap returned a null pointer.");
                    BasicConsole.DelayOutput(10);
                    BasicConsole.SetTextColour(BasicConsole.default_colour);

                    return(null);
                }

                NumStrings++;

                //Initialise the GCHeader
                SetSignature(newObjPtr);
                //RefCount to 0 initially because of FOS_System.String.New should be used
                //      - In theory, New should be called, creates new string and passes it back to caller
                //        Caller is then required to store the string in a variable resulting in inc.
                //        ref count so ref count = 1 in only stored location.
                //        Caller is not allowed to just "discard" (i.e. use Pop IL op or C# that generates
                //        Pop IL op) so ref count will always at some point be incremented and later
                //        decremented by managed code. OR the variable will stay in a static var until
                //        the OS exits...

                newObjPtr->RefCount = 0;

                FOS_System.String newStr = (FOS_System.String)Utilities.ObjectUtilities.GetObject(newObjPtr + 1);
                newStr._Type  = (FOS_System.Type) typeof(FOS_System.String);
                newStr.length = length;

                //Move past GCHeader
                byte *newObjBytePtr = (byte *)(newObjPtr + 1);

                InsideGC = false;

                return(newObjBytePtr);
            }
            finally
            {
                ExitCritical();
            }
        }
Ejemplo n.º 20
0
        public static void SwitchProcess(uint processId, int threadId)
        {
            //Switch the current memory layout across.
            //  Don't touch register state etc, just the memory layout

            bool dontSwitchOutIn = false;

            if (CurrentProcess != null &&
                CurrentProcess.Id == processId)
            {
                if (CurrentThread != null &&
                    (CurrentThread.Id == threadId || threadId == THREAD_DONT_CARE))
                {
#if PROCESSMANAGER_SWITCH_TRACE
                    BasicConsole.WriteLine("No switch. (1)");
#endif
                    return;
                }
                else
                {
#if PROCESSMANAGER_SWITCH_TRACE
                    BasicConsole.WriteLine("No switch. (2)");
#endif
                    dontSwitchOutIn = true;
                }
            }

            if (!dontSwitchOutIn)
            {
#if PROCESSMANAGER_SWITCH_TRACE
                BasicConsole.Write("Switching out: ");
                BasicConsole.WriteLine(CurrentProcess.Name);
#endif
                CurrentProcess.UnloadHeap();
                CurrentProcess.UnloadMemLayout();

                CurrentProcess = GetProcessById(processId);

                // Process not found
                if (CurrentProcess == null)
                {
#if PROCESSMANAGER_SWITCH_TRACE
                    BasicConsole.WriteLine("Process not found.");
#endif
                    return;
                }

#if PROCESSMANAGER_SWITCH_TRACE
                BasicConsole.Write("Switching in: ");
                BasicConsole.WriteLine(CurrentProcess.Name);
#endif
                CurrentProcess.LoadMemLayout();
                CurrentProcess.LoadHeap();
            }

            CurrentThread       = null;
            CurrentThread_State = null;

            if (threadId == THREAD_DONT_CARE)
            {
                if (CurrentProcess.Threads.Count > 0)
                {
                    CurrentThread = (Thread)CurrentProcess.Threads[0];
                }
            }
            else
            {
                CurrentThread = GetThreadById((uint)threadId, CurrentProcess);
            }

            // No threads in the process (?!) or process not found
            if (CurrentThread == null)
            {
#if PROCESSMANAGER_SWITCH_TRACE
                BasicConsole.WriteLine("Thread not found.");
#endif
                return;
            }
#if PROCESSMANAGER_SWITCH_TRACE
            BasicConsole.WriteLine("Thread found.");
#endif

            CurrentThread_State = CurrentThread.State;
#if PROCESSMANAGER_SWITCH_TRACE
            BasicConsole.WriteLine("Thread state updated.");
#endif
        }
Ejemplo n.º 21
0
        public void Load(bool UserMode)
        {
            bool OK = true;

            try
            {
                bool DynamicLinkingRequired = false;

                ThreadStartMethod mainMethod = (ThreadStartMethod)Utilities.ObjectUtilities.GetObject(theFile.Header.EntryPoint);
                theProcess = ProcessManager.CreateProcess(
                    mainMethod, theFile.TheFile.Name, UserMode);

                uint threadStackVirtAddr = (uint)((Thread)theProcess.Threads[0]).State->ThreadStackTop - 4092;
                uint threadStackPhysAddr = (uint)Hardware.VirtMemManager.GetPhysicalAddress(threadStackVirtAddr);
                ProcessManager.CurrentProcess.TheMemoryLayout.AddDataPage(threadStackPhysAddr, threadStackVirtAddr);

                // Load the ELF segments (i.e. the program code and data)
                BaseAddress = theFile.BaseAddress;
                LoadSegments(theFile, ref OK, ref DynamicLinkingRequired, BaseAddress);

                //BasicConsole.WriteLine();

                #region Relocations

                // Useful articles / specifications on Relocations:
                //      - Useful / practical explanation of various relocation types: http://eli.thegreenplace.net/2011/08/25/load-time-relocation-of-shared-libraries/#id20
                //      - Orcale : ELF Specification copy: http://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-54839.html

                if (DynamicLinkingRequired)
                {
                    Console.Default.WriteLine("Dynamic Linking");
                    BasicConsole.WriteLine("Dynamic Linking");

                    ELFDynamicSection            dynamicSection        = theFile.DynamicSection;
                    ELFDynamicSymbolTableSection dynamicSymbolsSection = theFile.DynamicSymbolsSection;

                    ELFStringTable DynamicsStringTable = new ELFStringTable(
                        dynamicSection.StrTabDynamic.Val_Ptr, dynamicSection.StrTabSizeDynamic.Val_Ptr);

                    for (uint i = 0; i < dynamicSection.Dynamics.Count; i++)
                    {
                        ELFDynamicSection.Dynamic theDyn = dynamicSection[i];

                        //BasicConsole.WriteLine("     - Dynamic : ");
                        //BasicConsole.Write("         - Tag : ");
                        //BasicConsole.WriteLine((int)theDyn.Tag);
                        //BasicConsole.Write("         - Value or Pointer : ");
                        //BasicConsole.WriteLine(theDyn.Val_Ptr);

                        if (theDyn.Tag == ELFDynamicSection.DynamicTag.Needed)
                        {
                            BasicConsole.Write("         - Needed library name : ");

                            FOS_System.String libFullPath = DynamicsStringTable[theDyn.Val_Ptr];
                            Console.Default.WriteLine(libFullPath);
                            BasicConsole.WriteLine(libFullPath);

                            FOS_System.String libFileName = (FOS_System.String)libFullPath.Split('\\').Last();
                            libFileName = (FOS_System.String)libFileName.Split('/').Last();
                            FOS_System.String libTestPath = theFile.TheFile.Parent.GetFullPath() + libFileName;
                            File sharedObjectFile         = File.Open(libTestPath);
                            if (sharedObjectFile == null)
                            {
                                Console.Default.WarningColour();
                                Console.Default.WriteLine("Failed to find needed library file!");
                                BasicConsole.WriteLine("Failed to find needed library file!");
                                Console.Default.DefaultColour();
                                OK = false;
                            }
                            else
                            {
                                Console.Default.WriteLine("Found library file. Loading library...");
                                BasicConsole.WriteLine("Found library file. Loading library...");

                                ELFSharedObject sharedObject = DynamicLinkerLoader.LoadLibrary_FromELFSO(sharedObjectFile, this);
                                SharedObjectDependencies.Add(sharedObject);

                                Console.Default.WriteLine("Library loaded.");
                                BasicConsole.WriteLine("Library loaded.");
                            }
                        }
                    }

                    Console.Default.WriteLine("Library Relocations");
                    BasicConsole.WriteLine("Library Relocations");

                    // Perform relocation / dynamic linking of all libraries
                    for (int i = 0; i < SharedObjectDependencies.Count; i++)
                    {
                        ELFSharedObject SO = (ELFSharedObject)SharedObjectDependencies[i];

                        //BasicConsole.WriteLine("Shared Object base address : " + (FOS_System.String)SO.BaseAddress);
                        //BasicConsole.WriteLine("Shared Object file base address : " + (FOS_System.String)SO.TheFile.BaseAddress);

                        List SOSections = SO.TheFile.Sections;
                        for (int j = 0; j < SOSections.Count; j++)
                        {
                            ELFSection SOSection = (ELFSection)SOSections[j];
                            if (SOSection is ELFRelocationTableSection)
                            {
                                //BasicConsole.WriteLine(" - Normal Relocation");

                                ELFRelocationTableSection relocTableSection = (ELFRelocationTableSection)SOSection;
                                ELFSymbolTableSection     symbolTable       = (ELFSymbolTableSection)SO.TheFile.Sections[relocTableSection.SymbolTableSectionIndex];
                                ELFStringTableSection     symbolNamesTable  = (ELFStringTableSection)SO.TheFile.Sections[symbolTable.StringsSectionIndex];

                                List Relocations = relocTableSection.Relocations;
                                for (int k = 0; k < Relocations.Count; k++)
                                {
                                    // Reference: http://docs.oracle.com/cd/E19683-01/817-3677/chapter6-26/index.html

                                    ELFRelocationTableSection.Relocation relocation = (ELFRelocationTableSection.Relocation)Relocations[k];
                                    if (relocation.Type == ELFRelocationTableSection.RelocationType.R_386_NONE)
                                    {
                                        continue;
                                    }

                                    uint *resolvedRelLocation               = (uint *)(SO.BaseAddress + (relocation.Offset - SO.TheFile.BaseAddress));
                                    ELFSymbolTableSection.Symbol symbol     = (ELFSymbolTableSection.Symbol)symbolTable[relocation.Symbol];
                                    FOS_System.String            symbolName = symbolNamesTable[symbol.NameIdx];

                                    //BasicConsole.WriteLine("Relocation:");
                                    ////BasicConsole.WriteLine("    > Symbol index : " + (FOS_System.String)relocation.Symbol);
                                    //BasicConsole.WriteLine("    > Type : " + (FOS_System.String)(uint)relocation.Type);
                                    //BasicConsole.WriteLine("    > Offset : " + (FOS_System.String)(uint)relocation.Offset);
                                    //BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location address: ") + (uint)resolvedRelLocation);
                                    ////BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location start value: ") + *resolvedRelLocation);
                                    //BasicConsole.Write("    > Symbol name : ");
                                    //BasicConsole.WriteLine(symbolName);

                                    uint newValue = 0;
                                    switch (relocation.Type)
                                    {
                                    case ELFRelocationTableSection.RelocationType.R_386_32:
                                        newValue = GetSymbolAddress(symbol, symbolName) + *resolvedRelLocation;
                                        break;

                                    case ELFRelocationTableSection.RelocationType.R_386_PC32:
                                        newValue = GetSymbolAddress(symbol, symbolName) + *resolvedRelLocation - (uint)resolvedRelLocation;
                                        break;

                                    case ELFRelocationTableSection.RelocationType.R_386_RELATIVE:
                                        newValue = SO.BaseAddress + *resolvedRelLocation;
                                        break;

                                    //TODO: Support more relocation types
                                    default:
                                        Console.Default.WarningColour();
                                        Console.Default.Write("WARNING: Unrecognised relocation type! (");
                                        Console.Default.Write_AsDecimal((uint)relocation.Type);
                                        Console.Default.WriteLine(")");
                                        Console.Default.DefaultColour();

                                        BasicConsole.Write("WARNING: Unrecognised relocation type! (");
                                        BasicConsole.Write((uint)relocation.Type);
                                        BasicConsole.WriteLine(")");
                                        break;
                                    }

                                    *resolvedRelLocation = newValue;

                                    //BasicConsole.WriteLine("    > New value: " + (FOS_System.String)(newValue));
                                    //BasicConsole.WriteLine("    > Resolved location end value: " + (FOS_System.String)(*resolvedRelLocation));
                                }
                            }
                            else if (SOSection is ELFRelocationAddendTableSection)
                            {
                                //BasicConsole.WriteLine(" - Addend Relocation");

                                ELFRelocationAddendTableSection relocTableSection = (ELFRelocationAddendTableSection)SOSection;
                                ELFSymbolTableSection           symbolTable       = (ELFSymbolTableSection)SO.TheFile.Sections[relocTableSection.SymbolTableSectionIndex];
                                ELFStringTableSection           symbolNamesTable  = (ELFStringTableSection)SO.TheFile.Sections[symbolTable.StringsSectionIndex];

                                List Relocations = relocTableSection.Relocations;
                                for (int k = 0; k < Relocations.Count; k++)
                                {
                                    ELFRelocationAddendTableSection.RelocationAddend relocation = (ELFRelocationAddendTableSection.RelocationAddend)Relocations[k];
                                    if (relocation.Type == ELFRelocationTableSection.RelocationType.R_386_NONE)
                                    {
                                        continue;
                                    }

                                    ELFSymbolTableSection.Symbol symbol     = (ELFSymbolTableSection.Symbol)symbolTable[relocation.Symbol];
                                    FOS_System.String            symbolName = symbolNamesTable[symbol.NameIdx];
                                    uint *resolvedRelLocation = (uint *)(SO.BaseAddress + (relocation.Offset - SO.TheFile.BaseAddress));

                                    //BasicConsole.WriteLine("Relocation:");
                                    ////BasicConsole.WriteLine("    > Symbol index : " + (FOS_System.String)relocation.Symbol);
                                    //BasicConsole.WriteLine("    > Type : " + (FOS_System.String)(uint)relocation.Type);
                                    //BasicConsole.WriteLine("    > Offset : " + (FOS_System.String)(uint)relocation.Offset);
                                    //BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location address: ") + (uint)resolvedRelLocation);
                                    ////BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location start value: ") + *resolvedRelLocation);
                                    //BasicConsole.Write("    > Symbol name : ");
                                    //BasicConsole.WriteLine(symbolName);

                                    uint newValue = 0;
                                    switch (relocation.Type)
                                    {
                                    //TODO: Support more relocation types
                                    default:
                                        Console.Default.WarningColour();
                                        Console.Default.Write("WARNING: Unrecognised relocation type! (");
                                        Console.Default.Write_AsDecimal((uint)relocation.Type);
                                        Console.Default.WriteLine(")");
                                        Console.Default.DefaultColour();

                                        BasicConsole.Write("WARNING: Unrecognised relocation type! (");
                                        BasicConsole.Write((uint)relocation.Type);
                                        BasicConsole.WriteLine(")");
                                        break;
                                    }

                                    *resolvedRelLocation = newValue;

                                    //BasicConsole.WriteLine("    > New value: " + (FOS_System.String)(newValue));
                                    //BasicConsole.WriteLine("    > Resolved location end value: " + (FOS_System.String)(*resolvedRelLocation));
                                }
                            }
                        }
                    }

                    Console.Default.WriteLine("Executable Relocations");
                    BasicConsole.WriteLine("Executable Relocations");

                    //BasicConsole.WriteLine("Executable base address : " + (FOS_System.String)BaseAddress);
                    //BasicConsole.WriteLine("Executable file base address : " + (FOS_System.String)theFile.BaseAddress);

                    // Perform dynamic linking of executable
                    List ExeSections = theFile.Sections;
                    for (int j = 0; j < ExeSections.Count; j++)
                    {
                        ELFSection ExeSection = (ELFSection)ExeSections[j];
                        if (ExeSection is ELFRelocationTableSection)
                        {
                            //BasicConsole.WriteLine(" - Normal Relocations");

                            ELFRelocationTableSection relocTableSection = (ELFRelocationTableSection)ExeSection;
                            ELFSymbolTableSection     symbolTable       = (ELFSymbolTableSection)theFile.Sections[relocTableSection.SymbolTableSectionIndex];
                            ELFStringTableSection     symbolNamesTable  = (ELFStringTableSection)theFile.Sections[symbolTable.StringsSectionIndex];

                            List Relocations = relocTableSection.Relocations;
                            for (int k = 0; k < Relocations.Count; k++)
                            {
                                ELFRelocationTableSection.Relocation relocation = (ELFRelocationTableSection.Relocation)Relocations[k];
                                if (relocation.Type == ELFRelocationTableSection.RelocationType.R_386_NONE)
                                {
                                    continue;
                                }

                                uint *resolvedRelLocation               = (uint *)(BaseAddress + (relocation.Offset - theFile.BaseAddress));
                                ELFSymbolTableSection.Symbol symbol     = (ELFSymbolTableSection.Symbol)symbolTable[relocation.Symbol];
                                FOS_System.String            symbolName = symbolNamesTable[symbol.NameIdx];

                                //BasicConsole.WriteLine("Relocation:");
                                ////BasicConsole.WriteLine("    > Symbol index : " + (FOS_System.String)relocation.Symbol);
                                //BasicConsole.WriteLine("    > Type : " + (FOS_System.String)(uint)relocation.Type);
                                //BasicConsole.WriteLine("    > Offset : " + (FOS_System.String)(uint)relocation.Offset);
                                //BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location address: ") + (uint)resolvedRelLocation);
                                ////BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location start value: ") + *resolvedRelLocation);
                                //BasicConsole.Write("    > Symbol name : ");
                                //BasicConsole.WriteLine(symbolName);

                                bool setFromNewValue = true;
                                uint newValue        = 0;
                                switch (relocation.Type)
                                {
                                //TODO: Support more relocation types
                                case ELFRelocationTableSection.RelocationType.R_386_JMP_SLOT:
                                    newValue = GetSymbolAddress(symbol, symbolName);
                                    break;

                                case ELFRelocationTableSection.RelocationType.R_386_COPY:
                                    // Created by the link-editor for dynamic executables to preserve a read-only text segment.
                                    // Its offset member refers to a location in a writable segment. The symbol table index
                                    // specifies a symbol that should exist both in the current object file and in a shared object.
                                    // During execution, the runtime linker copies data associated with the shared object's symbol
                                    // to the location specified by the offset.
                                    // See Copy Relocations:
                                    //      http://docs.oracle.com/cd/E19683-01/817-3677/6mj8mbtbs/index.html#chapter4-84604

                                    setFromNewValue = false;
                                    uint symbolAddress = 0;
                                    uint symbolSize    = 0;

                                    if (GetSymbolAddressAndSize(symbol, symbolName, ref symbolAddress, ref symbolSize))
                                    {
                                        byte *symbolValuePtr = (byte *)symbolAddress;

                                        //BasicConsole.Write("    > Symbol size : ");
                                        //BasicConsole.WriteLine(symbolSize);

                                        for (int i = 0; i < symbolSize; i++)
                                        {
                                            resolvedRelLocation[i] = symbolValuePtr[i];
                                        }
                                    }
                                    else
                                    {
                                        BasicConsole.WriteLine("Failed to get symbol address and size for R_386_COPY relocation!");
                                    }
                                    break;

                                default:
                                    Console.Default.WarningColour();
                                    Console.Default.Write("WARNING: Unrecognised relocation type! (");
                                    Console.Default.Write_AsDecimal((uint)relocation.Type);
                                    Console.Default.WriteLine(")");
                                    Console.Default.DefaultColour();

                                    BasicConsole.Write("WARNING: Unrecognised relocation type! (");
                                    BasicConsole.Write((uint)relocation.Type);
                                    BasicConsole.WriteLine(")");
                                    break;
                                }
                                if (setFromNewValue)
                                {
                                    *resolvedRelLocation = newValue;
                                    //BasicConsole.WriteLine("    > New value: " + (FOS_System.String)(newValue));
                                    //BasicConsole.WriteLine("    > Resolved location end value: " + (FOS_System.String)(*resolvedRelLocation));
                                }
                            }
                        }
                        else if (ExeSection is ELFRelocationAddendTableSection)
                        {
                            //BasicConsole.WriteLine(" - Addend Relocations");

                            ELFRelocationAddendTableSection relocTableSection = (ELFRelocationAddendTableSection)ExeSection;
                            ELFSymbolTableSection           symbolTable       = (ELFSymbolTableSection)theFile.Sections[relocTableSection.SymbolTableSectionIndex];
                            ELFStringTableSection           symbolNamesTable  = (ELFStringTableSection)theFile.Sections[symbolTable.StringsSectionIndex];

                            List Relocations = relocTableSection.Relocations;
                            for (int k = 0; k < Relocations.Count; k++)
                            {
                                ELFRelocationAddendTableSection.RelocationAddend relocation = (ELFRelocationAddendTableSection.RelocationAddend)Relocations[k];
                                if (relocation.Type == ELFRelocationTableSection.RelocationType.R_386_NONE)
                                {
                                    continue;
                                }

                                uint *resolvedRelLocation               = (uint *)(BaseAddress + (relocation.Offset - theFile.BaseAddress));
                                ELFSymbolTableSection.Symbol symbol     = (ELFSymbolTableSection.Symbol)symbolTable[relocation.Symbol];
                                FOS_System.String            symbolName = symbolNamesTable[symbol.NameIdx];

                                //BasicConsole.WriteLine("Relocation:");
                                ////BasicConsole.WriteLine("    > Symbol index : " + (FOS_System.String)relocation.Symbol);
                                //BasicConsole.WriteLine("    > Type : " + (FOS_System.String)(uint)relocation.Type);
                                //BasicConsole.WriteLine("    > Offset : " + (FOS_System.String)(uint)relocation.Offset);
                                //BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location address: ") + (uint)resolvedRelLocation);
                                ////BasicConsole.WriteLine(((FOS_System.String)"    > Resolved location start value: ") + *resolvedRelLocation);
                                //BasicConsole.Write("    > Symbol name : ");
                                //BasicConsole.WriteLine(symbolName);

                                uint newValue = 0;
                                switch (relocation.Type)
                                {
                                //TODO: Support more relocation types
                                default:
                                    Console.Default.WarningColour();
                                    Console.Default.Write("WARNING: Unrecognised relocation type! (");
                                    Console.Default.Write_AsDecimal((uint)relocation.Type);
                                    Console.Default.WriteLine(")");
                                    Console.Default.DefaultColour();

                                    BasicConsole.Write("WARNING: Unrecognised relocation type! (");
                                    BasicConsole.Write((uint)relocation.Type);
                                    BasicConsole.WriteLine(")");
                                    break;
                                }
                                *resolvedRelLocation = newValue;
                                //BasicConsole.WriteLine("    > New value: " + (FOS_System.String)(newValue));
                                //BasicConsole.WriteLine("    > Resolved location end value: " + (FOS_System.String)(*resolvedRelLocation));
                            }
                        }
                    }

                    // TODO: Call Init functions of libraries
                }

                // Unmap processes' memory from current processes' memory
                for (int i = 0; i < SharedObjectDependencies.Count; i++)
                {
                    ELFSharedObject SO = (ELFSharedObject)SharedObjectDependencies[i];
                    uint            FileBaseAddress = SO.TheFile.BaseAddress;
                    uint            MemBaseAddress  = SO.BaseAddress;

                    List SOSegments = SO.TheFile.Segments;
                    for (int j = 0; j < SOSegments.Count; j++)
                    {
                        ELFSegment SOSegment = (ELFSegment)SOSegments[j];
                        ProcessManager.CurrentProcess.TheMemoryLayout.RemovePage(
                            (MemBaseAddress + ((uint)SOSegment.Header.VAddr - FileBaseAddress)) & 0xFFFFF000);
                    }
                }
                {
                    uint FileBaseAddress = theFile.BaseAddress;
                    uint MemBaseAddress  = BaseAddress;

                    List ExeSegments = theFile.Segments;
                    for (int j = 0; j < ExeSegments.Count; j++)
                    {
                        ELFSegment ExeSegment = (ELFSegment)ExeSegments[j];
                        ProcessManager.CurrentProcess.TheMemoryLayout.RemovePage(
                            (MemBaseAddress + ((uint)ExeSegment.Header.VAddr - FileBaseAddress)) & 0xFFFFF000);
                    }
                }

                #endregion

                ProcessManager.CurrentProcess.TheMemoryLayout.RemovePage(threadStackVirtAddr);
            }
            finally
            {
                if (!OK)
                {
                    theProcess = null;
                }
            }
        }