Example #1
0
        public static int SyscallHandler(uint syscallNumber, uint param1, uint param2, uint param3,
                                         ref uint Return2, ref uint Return3, ref uint Return4,
                                         uint callerProcesId, uint callerThreadId)
        {
            SystemCallResults result = SystemCallResults.Unhandled;

            switch ((SystemCallNumbers)syscallNumber)
            {
            case SystemCallNumbers.RegisterPipeOutpoint:
                BasicConsole.WriteLine("WM > IH > Actioning Register Pipe Outpoint system call...");
                Pipes.PipeClasses    Class    = (Pipes.PipeClasses)param1;
                Pipes.PipeSubclasses Subclass = (Pipes.PipeSubclasses)param2;
                if (Class == Pipes.PipeClasses.Standard &&
                    Subclass == Pipes.PipeSubclasses.Standard_Out)
                {
                    BasicConsole.WriteLine("WM > IH > Register Pipe Outpoint has desired pipe class and subclass.");
                    result  = SystemCallResults.RequestAction_WakeThread;
                    Return2 = InputProcessingThreadId;
                    InputProcessingThreadAwake = true;
                }
                break;
            }

            return((int)result);
        }
Example #2
0
        public static int SyscallHandler(uint syscallNumber, uint param1, uint param2, uint param3,
                                         ref uint Return2, ref uint Return3, ref uint Return4,
                                         uint callerProcessId, uint callerThreadId)
        {
            SystemCallResults result = HandleSystemCallForKernel(syscallNumber,
                                                                 param1, param2, param3,
                                                                 ref Return2, ref Return3, ref Return4,
                                                                 callerProcessId, callerThreadId);

            if (result == SystemCallResults.Deferred || result == SystemCallResults.Deferred_PermitActions)
            {
                //BasicConsole.WriteLine("Deferring syscall...");
                //BasicConsole.WriteLine("Popping unqueued info object...");
                DeferredSyscallInfo info = (DeferredSyscallInfo)DeferredSyscallsInfo_Unqueued.Pop();
                //BasicConsole.WriteLine("Setting info...");
                info.ProcessId = callerProcessId;
                info.ThreadId  = callerThreadId;

                //BasicConsole.WriteLine("Queuing info object...");
                DeferredSyscallsInfo_Queued.Push(info);

                //BasicConsole.WriteLine("Waking deferred syscalls thread...");
                DeferredSyscallsThread._Wake();
            }

            return((int)result);
        }
Example #3
0
        /// <summary>
        /// Waits for a pipe to connect to the outpoint.
        /// </summary>
        /// <returns>The Id of the newly connected pipe.</returns>
        public int WaitForConnect()
        {
            int aPipeId;
            SystemCallResults SysCallResult = SystemCalls.WaitOnPipeCreate(Class, Subclass, out aPipeId);

            switch (SysCallResult)
            {
            case SystemCallResults.Unhandled:
                //BasicConsole.WriteLine("BasicOutPipe > WaitOnPipeCreate: Unhandled!");
                ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicOutPipe : Wait On Pipe Create unhandled!"));
                break;

            case SystemCallResults.Fail:
                //BasicConsole.WriteLine("BasicOutPipe > WaitOnPipeCreate: Failed!");
                ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicOutPipe : Wait On Pipe Create failed!"));
                break;

            case SystemCallResults.OK:
                //BasicConsole.WriteLine("BasicOutPipe > WaitOnPipeCreate: Succeeded.");
                //BasicConsole.Write("BasicOutPipe > New pipe id: ");
                //BasicConsole.WriteLine(aPipeId);
                break;

            default:
                //BasicConsole.WriteLine("BasicOutPipe > WaitOnPipeCreate: Unexpected system call result!");
                ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicOutPipe : Wait On Pipe Create unexpected result!"));
                break;
            }
            return(aPipeId);
        }
Example #4
0
        /// <summary>
        /// Creates and registers a new outpoint of the specified class and subclass.
        /// </summary>
        /// <param name="aClass">The class of pipe allowed to connect to the outpoint.</param>
        /// <param name="aSubclass">The subclass of pipe allowed to connect to the outpoint.</param>
        /// <param name="MaxConnections">
        /// The maximum number of connections allowed. Use <see cref="PipeConstants.UnlimitedConnections"/> for unlimited connections.
        /// </param>
        public BasicOutpoint(PipeClasses aClass, PipeSubclasses aSubclass, int MaxConnections)
        {
            Class    = aClass;
            Subclass = aSubclass;

            SystemCallResults SysCallResult = SystemCalls.RegisterPipeOutpoint(Class, Subclass, MaxConnections);

            switch (SysCallResult)
            {
            case SystemCallResults.Unhandled:
                //BasicConsole.WriteLine("BasicOutPipe > RegisterPipeOutpoint: Unhandled!");
                ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicOutPipe : Register Pipe Outpoint system call unhandled!"));
                break;

            case SystemCallResults.Fail:
                //BasicConsole.WriteLine("BasicOutPipe > RegisterPipeOutpoint: Failed!");
                ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicOutPipe : Register Pipe Outpoint system call failed!"));
                break;

            case SystemCallResults.OK:
                //BasicConsole.WriteLine("BasicOutPipe > RegisterPipeOutpoint: Succeeded.");
                break;

            default:
                //BasicConsole.WriteLine("BasicOutPipe > RegisterPipeOutpoint: Unexpected system call result!");
                ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicOutPipe : Register Pipe Outpoint system call unexpected result!"));
                break;
            }
        }
Example #5
0
        /// <summary>
        /// Reads up to the specified length of data into the specified buffer at the specified offset in the buffer.
        /// </summary>
        /// <param name="Data">The buffer to read into.</param>
        /// <param name="Offset">The offset in the buffer to write data to.</param>
        /// <param name="Length">The maximum length of data to read.</param>
        /// <param name="Blocking">Whether the read should be blocking or non-blocking.</param>
        /// <returns>The actual number of bytes read.</returns>
        public int Read(byte[] Data, int Offset, int Length, bool Blocking)
        {
            int BytesRead = 0;

            Pipes.ReadPipeRequest *ReadPipeRequestPtr = (Pipes.ReadPipeRequest *)Heap.AllocZeroed((uint)sizeof(Pipes.ReadPipeRequest), "BasicInPipe : Alloc ReadPipeRequest");
            try
            {
                if (ReadPipeRequestPtr != null)
                {
                    ReadPipeRequestPtr->PipeId    = PipeId;
                    ReadPipeRequestPtr->Offset    = Offset;
                    ReadPipeRequestPtr->Length    = FOS_System.Math.Min(Data.Length - Offset, Length);
                    ReadPipeRequestPtr->OutBuffer = (byte *)Utilities.ObjectUtilities.GetHandle(Data) + FOS_System.Array.FieldsBytesSize;
                    ReadPipeRequestPtr->Blocking  = Blocking;

                    SystemCallResults SysCallResult = SystemCalls.ReadPipe(ReadPipeRequestPtr, out BytesRead);
                    switch (SysCallResult)
                    {
                    case SystemCallResults.Unhandled:
                        //BasicConsole.WriteLine("BasicInPipe > ReadPipe: Unhandled!");
                        ExceptionMethods.Throw(new Exceptions.RWUnhandledException("BasicInPipe : Read Pipe unexpected unhandled!"));
                        break;

                    case SystemCallResults.Fail:
                        //BasicConsole.WriteLine("BasicInPipe > ReadPipe: Failed!");
                        if (Blocking)
                        {
                            ExceptionMethods.Throw(new Exceptions.RWFailedException("BasicInPipe : Write Pipe unexpected failed! (Blocking call)"));
                        }
                        else
                        {
                            ExceptionMethods.Throw(new Exceptions.RWFailedException("BasicInPipe : Write Pipe failed. (Non-blocking call)"));
                        }
                        break;

                    case SystemCallResults.OK:
                        //BasicConsole.WriteLine("BasicInPipe > ReadPipe: Succeeded.");
                        break;

                    default:
                        //BasicConsole.WriteLine("BasicInPipe > ReadPipe: Unexpected system call result!");
                        ExceptionMethods.Throw(new Exceptions.RWUnhandledException("BasicInPipe : Read Pipe unexpected result!"));
                        break;
                    }
                }
                else
                {
                    ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicInPipe : Couldn't allocate memory to read from pipe!"));
                }
            }
            finally
            {
                if (ReadPipeRequestPtr != null)
                {
                    Heap.Free(ReadPipeRequestPtr);
                }
            }

            return(BytesRead);
        }
Example #6
0
        /// <summary>
        /// Gets the number of available outpoints of the specified class and subclass.
        /// </summary>
        /// <param name="numOutpoints">Out : The number of outpoints (correct iff SysCallResult is OK).</param>
        /// <param name="SysCallResult">Out : The result of the system call. Check this is set to OK.</param>
        /// <param name="Class">The class of pipe to search for.</param>
        /// <param name="Subclass">The subclass of pipe to search for.</param>
        public static void GetNumPipeOutpoints(out int numOutpoints, out SystemCallResults SysCallResult, Pipes.PipeClasses Class, Pipes.PipeSubclasses Subclass)
        {
            SysCallResult = SystemCalls.GetNumPipeOutpoints(Class, Subclass, out numOutpoints);
            switch (SysCallResult)
            {
            case SystemCallResults.Unhandled:
                //BasicConsole.WriteLine("BasicServerHelpers > GetNumPipeOutpoints: Unhandled!");
                break;

            case SystemCallResults.Fail:
                //BasicConsole.WriteLine("BasicServerHelpers > GetNumPipeOutpoints: Failed!");
                break;

            case SystemCallResults.OK:
                //BasicConsole.WriteLine("BasicServerHelpers > GetNumPipeOutpoints: Succeeded.");

                //BasicConsole.Write("BasicServerHelpers > Num pipe outpoints: ");
                //BasicConsole.WriteLine(numOutpoints);
                break;

            default:
                //BasicConsole.WriteLine("BasicServerHelpers > GetNumPipeOutpoints: Unexpected system call result!");
                break;
            }
        }
Example #7
0
        //private static Pipes.Standard.StandardInpoint StdIn;

        public static void Main()
        {
            BasicConsole.WriteLine("Device Manager started.");

            Hardware.Processes.ProcessManager.CurrentProcess.InitHeap();
            SystemCallResults SysCallResult = SystemCalls.StartThread(GCCleanupTask.Main, out GCThreadId);

            if (SysCallResult != SystemCallResults.OK)
            {
                BasicConsole.WriteLine("Device Manager: GC thread failed to create!");
            }

            try
            {
                StdOut = new Pipes.Standard.StandardOutpoint(true);
                int StdOutPipeId = StdOut.WaitForConnect();

                //int numOutpoints;
                //Pipes.BasicOutpoint.GetNumPipeOutpoints(out numOutpoints, out SysCallResult, Pipes.PipeClasses.Standard, Pipes.PipeSubclasses.Standard_In);
                //if (SysCallResult == SystemCallResults.OK && numOutpoints > 0)
                //{
                //    Pipes.PipeOutpointDescriptor[] OutpointDescriptors;
                //    Pipes.BasicOutpoint.GetOutpointDescriptors(numOutpoints, out SysCallResult, out OutpointDescriptors, Pipes.PipeClasses.Standard, Pipes.PipeSubclasses.Standard_In);
                //
                //    if (SysCallResult == SystemCallResults.OK)
                //    {
                //        for (int i = 0; i < OutpointDescriptors.Length; i++)
                //        {
                //            Pipes.PipeOutpointDescriptor Descriptor = OutpointDescriptors[i];
                //            //TODO: Filter to target
                //            StdIn = new Pipes.Standard.StandardInpoint(Descriptor.ProcessId, false);
                //        }
                //    }
                //}

                uint loops = 0;
                while (!Terminating)
                {
                    try
                    {
                        //StdOut.Write(StdOutPipeId, "Hello, world! (" + (FOS_System.String)loops++ + ")\n", true);
                        SystemCalls.SleepThread(-1);
                    }
                    catch
                    {
                        BasicConsole.WriteLine("DM > Error writing to StdOut!");
                        BasicConsole.WriteLine(ExceptionMethods.CurrentException.Message);
                    }

                    SystemCalls.SleepThread(1000);
                }
            }
            catch
            {
                BasicConsole.WriteLine("DM > Error initialising!");
                BasicConsole.WriteLine(ExceptionMethods.CurrentException.Message);
            }
        }
Example #8
0
        public static void EndDeferredSystemCall(Thread CallerThread, SystemCallResults result, uint Return2, uint Return3, uint Return4)
        {
            CallerThread.Return1 = (uint)result;
            CallerThread.Return2 = Return2;
            CallerThread.Return3 = Return3;
            CallerThread.Return4 = Return4;

            CallerThread._Wake();
        }
Example #9
0
        public static void DeferredSyscallsThread_Main()
        {
            while (!Terminating)
            {
                if (DeferredSyscallsInfo_Queued.Count == 0)
                {
                    Thread.Sleep_Indefinitely();
                }

                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.
                    //BasicConsole.WriteLine("DSC: Pausing scheduler...");
                    //Scheduler.Disable();
                    //BasicConsole.WriteLine("DSC: Popping queued info object...");
                    DeferredSyscallInfo info = (DeferredSyscallInfo)DeferredSyscallsInfo_Queued.Pop();
                    //BasicConsole.WriteLine("DSC: Resuming scheduler...");
                    //Scheduler.Enable();

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

                    //BasicConsole.WriteLine("DSC: Getting data & calling...");
                    uint Return2             = CallerThread.Return2;
                    uint Return3             = CallerThread.Return3;
                    uint Return4             = CallerThread.Return4;
                    SystemCallResults result = HandleDeferredSystemCall(
                        CallerProcess, CallerThread,
                        (SystemCallNumbers)CallerThread.SysCallNumber, CallerThread.Param1, CallerThread.Param2, CallerThread.Param3,
                        ref Return2, ref Return3, ref Return4);

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

                    //BasicConsole.WriteLine("DSC: Resetting info object...");
                    info.ProcessId = 0;
                    info.ThreadId  = 0;

                    // See comment at top of loop for why this is necessary
                    //BasicConsole.WriteLine("DSC: Pausing scheduler...");
                    //Scheduler.Disable();
                    //BasicConsole.WriteLine("DSC: Queuing info object...");
                    DeferredSyscallsInfo_Unqueued.Push(info);
                    //BasicConsole.WriteLine("DSC: Resuming scheduler...");
                    //Scheduler.Enable();
                }
            }
        }
Example #10
0
        /// <summary>
        /// Gets the outpoint desciptors of the available outpoints of the specified class and subclass.
        /// </summary>
        /// <param name="numOutpoints">The known number of available outpoints. Use GetNumPipeOutpoints to obtain this number.</param>
        /// <param name="SysCallResult">Out : The result of the system call. Check this is set to OK.</param>
        /// <param name="OutpointDescriptors">Out : The array of outpoint descriptors.</param>
        /// <param name="Class">The class of pipe to search for.</param>
        /// <param name="Subclass">The subclass of pipe to search for.</param>
        public static void GetOutpointDescriptors(int numOutpoints, out SystemCallResults SysCallResult, out Pipes.PipeOutpointDescriptor[] OutpointDescriptors, Pipes.PipeClasses Class, Pipes.PipeSubclasses Subclass)
        {
            OutpointDescriptors = new Pipes.PipeOutpointDescriptor[numOutpoints];

            Pipes.PipeOutpointsRequest *RequestPtr = (Pipes.PipeOutpointsRequest *)Heap.AllocZeroed((uint)sizeof(Pipes.PipeOutpointsRequest), "BasicServerHelpers : Alloc PipeOutpointsRequest");
            if (RequestPtr != null)
            {
                try
                {
                    RequestPtr->MaxDescriptors = numOutpoints;
                    RequestPtr->Outpoints      = (Pipes.PipeOutpointDescriptor *)((byte *)Utilities.ObjectUtilities.GetHandle(OutpointDescriptors) + FOS_System.Array.FieldsBytesSize);
                    if (RequestPtr->Outpoints != null)
                    {
                        SysCallResult = SystemCalls.GetPipeOutpoints(Class, Subclass, RequestPtr);
                        switch (SysCallResult)
                        {
                        case SystemCallResults.Unhandled:
                            //BasicConsole.WriteLine("BasicServerHelpers > GetPipeOutpoints: Unhandled!");
                            break;

                        case SystemCallResults.Fail:
                            //BasicConsole.WriteLine("BasicServerHelpers > GetPipeOutpoints: Failed!");
                            break;

                        case SystemCallResults.OK:
                            //BasicConsole.WriteLine("BasicServerHelpers > GetPipeOutpoints: Succeeded.");
                            break;

                        default:
                            //BasicConsole.WriteLine("BasicServerHelpers > GetPipeOutpoints: Unexpected system call result!");
                            break;
                        }
                    }
                    else
                    {
                        SysCallResult = SystemCallResults.Fail;
                        //BasicConsole.WriteLine("BasicServerHelpers > RequestPtr->Outpoints null! No memory allocated.");
                        ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicServerHelpers : Couldn't allocate memory outpoints list in outpoints request!"));
                    }
                }
                finally
                {
                    Heap.Free(RequestPtr);
                }
            }
            else
            {
                SysCallResult = SystemCallResults.Fail;
                //BasicConsole.WriteLine("BasicServerHelpers > RequestPtr null! No memory allocated.");
                ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicServerHelpers : Couldn't allocate memory get outpoints request!"));
            }
        }
Example #11
0
        /// <summary>
        /// Creates and connects a new pipe to the specified target process.
        /// </summary>
        /// <param name="anOutProcessId">The target process to connect to.</param>
        /// <param name="aClass">The class of pipe to create.</param>
        /// <param name="aSubclass">The subclass of pipe to create.</param>
        /// <param name="aBufferSize">The size of buffer to use within the core OS.</param>
        public BasicInpoint(uint anOutProcessId, PipeClasses aClass, PipeSubclasses aSubclass, int aBufferSize)
        {
            OutProcessId = anOutProcessId;
            Class        = aClass;
            Subclass     = aSubclass;
            BufferSize   = aBufferSize;

            Pipes.CreatePipeRequest *RequestPtr = (Pipes.CreatePipeRequest *)Heap.AllocZeroed((uint)sizeof(Pipes.CreatePipeRequest), "BasicInPipe : Alloc CreatePipeRequest");
            if (RequestPtr != null)
            {
                try
                {
                    RequestPtr->BufferSize = aBufferSize;
                    RequestPtr->Class      = aClass;
                    RequestPtr->Subclass   = aSubclass;

                    SystemCallResults SysCallResult = SystemCalls.CreatePipe(anOutProcessId, RequestPtr);
                    switch (SysCallResult)
                    {
                    case SystemCallResults.Unhandled:
                        //BasicConsole.WriteLine("BasicInPipe > CreatePipe: Unhandled!");
                        break;

                    case SystemCallResults.Fail:
                        //BasicConsole.WriteLine("BasicInPipe > CreatePipe: Failed!");
                        break;

                    case SystemCallResults.OK:
                        //BasicConsole.WriteLine("BasicInPipe > CreatePipe: Succeeded.");
                        PipeId = RequestPtr->Result.Id;

                        //BasicConsole.Write("BasicInPipe > CreatePipe: New pipe id = ");
                        //BasicConsole.WriteLine(PipeId);
                        break;

                    default:
                        //BasicConsole.WriteLine("BasicInPipe > CreatePipe: Unexpected system call result!");
                        break;
                    }
                }
                finally
                {
                    Heap.Free(RequestPtr);
                }
            }
            else
            {
                ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicInPipe : Couldn't allocate memory to create pipe!"));
                //BasicConsole.WriteLine("BasicInPipe > RequestPtr null! No memory allocated.");
            }
        }
Example #12
0
        /// <summary>
        /// Main interrupt handler routine for system calls.
        /// </summary>
        /// <remarks>
        /// Prevents direct invocation of the Receive Message system call, since that's not allowed.
        /// </remarks>
        public static void InterruptHandler()
        {
#if SYSCALLS_TRACE
            BasicConsole.WriteLine();
            BasicConsole.WriteLine("----- Syscall -----");
            BasicConsole.WriteLine(ProcessManager.CurrentProcess.Name);
#endif

            Process currProcess = ProcessManager.CurrentProcess;
            Thread  currThread  = ProcessManager.CurrentThread;
            bool    switched    = false;

#if SYSCALLS_TRACE
            BasicConsole.WriteLine("Getting param values...");
#endif

            uint syscallNumber = currThread.SysCallNumber;
            uint param1        = currThread.Param1;
            uint param2        = currThread.Param2;
            uint param3        = currThread.Param3;

            SystemCallResults result = SystemCallResults.Unhandled;
            uint Return2             = 0;
            uint Return3             = 0;
            uint Return4             = 0;

            if (syscallNumber != (uint)SystemCallNumbers.ReceiveMessage)
            {
                Process handlerProcess = null;

#if SYSCALLS_TRACE
                BasicConsole.WriteLine("Enumerating processes...");
#endif

                bool PermitActionResulted = false;
                for (int i = 0; i < ProcessManager.Processes.Count; i++)
                {
                    handlerProcess = (Process)ProcessManager.Processes[i];
                    if (handlerProcess.SyscallsToHandle.IsSet((int)syscallNumber))
                    {
                        ProcessManager.SwitchProcess(handlerProcess.Id, ProcessManager.THREAD_DONT_CARE);
                        switched = true;

#if SYSCALLS_TRACE
                        BasicConsole.WriteLine("Calling handler...");

                        //if (process == null)
                        //{
                        //    BasicConsole.WriteLine(" > process is null?!");
                        //}
                        //else if (process.SyscallHandler == null)
                        //{
                        //    BasicConsole.WriteLine(" > process.SysCallHandler is null?!");
                        //}
#endif

                        uint TempReturn2             = 0;
                        uint TempReturn3             = 0;
                        uint TempReturn4             = 0;
                        SystemCallResults tempResult = (SystemCallResults)handlerProcess.SyscallHandler(syscallNumber,
                                                                                                        param1, param2, param3,
                                                                                                        ref TempReturn2, ref TempReturn3, ref TempReturn4,
                                                                                                        currProcess.Id, currThread.Id);

                        if (tempResult == SystemCallResults.RequestAction_WakeThread)
                        {
#if SYSCALLS_TRACE
                            asicConsole.WriteLine("System calls : Performing action - wake thread");
#endif
                            ProcessManager.WakeThread(handlerProcess, TempReturn2);
                            tempResult = SystemCallResults.Unhandled;
                        }

                        if (tempResult != SystemCallResults.Unhandled && !PermitActionResulted)
                        {
#if SYSCALLS_TRACE
                            BasicConsole.WriteLine("Result achieved.");
#endif
                            Return2 = TempReturn2;
                            Return3 = TempReturn3;
                            Return4 = TempReturn4;

                            if (tempResult == SystemCallResults.OK_PermitActions)
                            {
                                result = SystemCallResults.OK;
                                PermitActionResulted = true;
                            }
                            else if (tempResult == SystemCallResults.Deferred_PermitActions)
                            {
                                result = SystemCallResults.Deferred;
                                PermitActionResulted = true;
                            }
                            else
                            {
                                result = tempResult;
                                break;
                            }
                        }
                    }
                }

                if (switched)
                {
#if SYSCALLS_TRACE
                    BasicConsole.WriteLine("Switching back...");
#endif

                    ProcessManager.SwitchProcess(currProcess.Id, (int)currThread.Id);
                }
            }

#if SYSCALLS_TRACE
            BasicConsole.WriteLine("Setting result values...");
#endif

            if (result == SystemCallResults.Deferred)
            {
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("Deferring thread (by indefinite sleep)...");
#endif
                currThread._EnterSleep(Thread.IndefiniteSleep);
            }
            else
            {
                currThread.Return1 = (uint)result;
                currThread.Return2 = Return2;
                currThread.Return3 = Return3;
                currThread.Return4 = Return4;
            }

            if (currThread.TimeToSleep != 0)
            {
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("Updating thread state...");
#endif
                Scheduler.UpdateCurrentState();
            }

#if SYSCALLS_TRACE
            BasicConsole.WriteLine("Syscall handled.");
            BasicConsole.WriteLine("---------------");
#endif
        }
Example #13
0
        /// <summary>
        /// Special handler method for system calls recognised/handlded by the kernel task.
        /// </summary>
        /// <param name="syscallNumber">The system call number that has been invoked.</param>
        /// <param name="param1">The value of the first parameter.</param>
        /// <param name="param2">The value of the second parameter.</param>
        /// <param name="param3">The value of the third parameter.</param>
        /// <param name="Return2">Reference to the second return value.</param>
        /// <param name="Return3">Reference to the third return value.</param>
        /// <param name="Return4">Reference to the fourth return value.</param>
        /// <param name="callerProcesId">The Id of the process which invoked the system call.</param>
        /// <param name="callerThreadId">The Id of the thread which invoked the system call.</param>
        /// <returns>A system call result indicating what has occurred and what should occur next.</returns>
        /// <remarks>
        /// Executes within the interrupt handler. Usual restrictions apply.
        /// </remarks>
        public static SystemCallResults HandleSystemCallForKernel(uint syscallNumber,
                                                                  uint param1, uint param2, uint param3,
                                                                  ref uint Return2, ref uint Return3, ref uint Return4,
                                                                  uint callerProcesId, uint callerThreadId)
        {
            SystemCallResults result = SystemCallResults.Unhandled;

            switch ((SystemCallNumbers)syscallNumber)
            {
            case SystemCallNumbers.SleepThread:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Sleep Thread");
#endif
                SysCall_Sleep((int)param1, callerProcesId, callerThreadId);
                result = SystemCallResults.OK;
                break;

            case SystemCallNumbers.WakeThread:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Wake Thread");
#endif
                SysCall_Wake(callerProcesId, param1);
                result = SystemCallResults.OK;
                break;

            case SystemCallNumbers.RegisterISRHandler:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Register ISR Handler");
#endif
                if (SysCall_RegisterISRHandler((int)param1, param2, callerProcesId))
                {
                    result = SystemCallResults.OK;
                }
                else
                {
                    result = SystemCallResults.Fail;
                }
                break;

            case SystemCallNumbers.DeregisterISRHandler:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Deregister ISR Handler");
#endif
                SysCall_DeregisterISRHandler((int)param1, callerProcesId);
                result = SystemCallResults.OK;
                break;

            case SystemCallNumbers.RegisterIRQHandler:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Register IRQ Handler");
#endif
                if (SysCall_RegisterIRQHandler((int)param1, param2, callerProcesId))
                {
                    result = SystemCallResults.OK;
                }
                else
                {
                    result = SystemCallResults.Fail;
                }
                break;

            case SystemCallNumbers.DeregisterIRQHandler:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Deregister IRQ Handler");
#endif
                SysCall_DeregisterIRQHandler((int)param1, callerProcesId);
                result = SystemCallResults.OK;
                break;

            case SystemCallNumbers.RegisterSyscallHandler:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Register Syscall Handler");
#endif
                if (SysCall_RegisterSyscallHandler((int)param1, param2, callerProcesId))
                {
                    result = SystemCallResults.OK;
                }
                else
                {
                    result = SystemCallResults.Fail;
                }
                break;

            case SystemCallNumbers.DeregisterSyscallHandler:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Deregister Syscall Handler");
#endif
                SysCall_DeregisterSyscallHandler((int)param1, callerProcesId);
                result = SystemCallResults.OK;
                break;

            case SystemCallNumbers.StartThread:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Start Thread");
#endif
                result = SystemCallResults.Deferred;
                break;

            case SystemCallNumbers.RegisterPipeOutpoint:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Register Pipe Outpoint");
#endif
                result = SystemCallResults.Deferred_PermitActions;
                break;

            case SystemCallNumbers.GetNumPipeOutpoints:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Get Num Pipe Outpoints");
#endif
                result = SystemCallResults.Deferred;
                break;

            case SystemCallNumbers.GetPipeOutpoints:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Get Pipe Outpoints");
#endif
                result = SystemCallResults.Deferred;
                break;

            case SystemCallNumbers.CreatePipe:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Create Pipe");
#endif
                result = SystemCallResults.Deferred;
                break;

            case SystemCallNumbers.WaitOnPipeCreate:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Wait On Pipe Create");
#endif
                result = SystemCallResults.Deferred;
                break;

            case SystemCallNumbers.ReadPipe:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Read Pipe");
#endif
                result = SystemCallResults.Deferred;
                break;

            case SystemCallNumbers.WritePipe:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("System call : Write Pipe");
#endif
                result = SystemCallResults.Deferred;
                break;

            case SystemCallNumbers.SendMessage:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("Syscall: Send message");
#endif
                result = SysCall_SendMessage(callerProcesId, callerThreadId, param1, param2, param3) ? SystemCallResults.OK : SystemCallResults.Fail;
                break;

            case SystemCallNumbers.ReceiveMessage:
#if SYSCALLS_TRACE
                BasicConsole.WriteLine("Syscall: Receive message");
#endif
                Tasks.KernelTask.ReceiveMessage(callerProcesId, param1, param2);
                break;

//#if SYSCALLS_TRACE
            default:
                BasicConsole.WriteLine("System call unrecognised/unhandled by Kernel Task.");
                break;
//#endif
            }

            return(result);
        }
Example #14
0
        public static void EndDeferredSystemCall(Thread CallerThread, SystemCallResults result, uint Return2, uint Return3, uint Return4)
        {
            CallerThread.Return1 = (uint)result;
            CallerThread.Return2 = Return2;
            CallerThread.Return3 = Return3;
            CallerThread.Return4 = Return4;

            CallerThread._Wake();
        }
Example #15
0
 public static void EndDeferredSystemCall(Process CallerProcess, Thread CallerThread, SystemCallResults result, uint Return2, uint Return3, uint Return4)
 {
     ProcessManager.EnableKernelAccessToProcessMemory(CallerProcess);
     CallerThread.Return1 = (uint)result;
     CallerThread.Return2 = Return2;
     CallerThread.Return3 = Return3;
     CallerThread.Return4 = Return4;
     ProcessManager.DisableKernelAccessToProcessMemory(CallerProcess);
     
     CallerThread._Wake();
 }
Example #16
0
        public static void EndDeferredSystemCall(Process CallerProcess, Thread CallerThread, SystemCallResults result, uint Return2, uint Return3, uint Return4)
        {
            ProcessManager.EnableKernelAccessToProcessMemory(CallerProcess);
            CallerThread.Return1 = (uint)result;
            CallerThread.Return2 = Return2;
            CallerThread.Return3 = Return3;
            CallerThread.Return4 = Return4;
            ProcessManager.DisableKernelAccessToProcessMemory(CallerProcess);

            CallerThread._Wake();
        }
Example #17
0
        public static unsafe SystemCallResults HandleDeferredSystemCall(
            Process CallerProcess, Thread CallerThread,
            SystemCallNumbers syscallNumber, uint Param1, uint Param2, uint Param3,
            ref uint Return2, ref uint Return3, ref uint Return4)
        {
            SystemCallResults result = SystemCallResults.Unhandled;

            switch (syscallNumber)
            {
            case SystemCallNumbers.StartThread:
#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Start Thread");
#endif
                Return2 = CallerProcess.CreateThread((ThreadStartMethod)Utilities.ObjectUtilities.GetObject((void *)Param1), "[From sys call]").Id;
#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Start Thread - done.");
#endif
                result = SystemCallResults.OK;
                break;

            case SystemCallNumbers.RegisterPipeOutpoint:
            {
#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Register Pipe Outpoint");
#endif
                Pipes.PipeOutpoint outpoint;
                bool registered = Pipes.PipeManager.RegisterPipeOutpoint(CallerProcess.Id, (Pipes.PipeClasses)Param1, (Pipes.PipeSubclasses)Param2, (int)Param3, out outpoint);
                if (registered)
                {
                    result = SystemCallResults.OK;
                }
                else
                {
                    result = SystemCallResults.Fail;
                }
#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Register Pipe Outpoint - done.");
#endif
            }
            break;

            case SystemCallNumbers.GetNumPipeOutpoints:
            {
#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Get Num Pipe Outpoints");
#endif
                int  numOutpoints;
                bool obtained = Pipes.PipeManager.GetNumPipeOutpoints((Pipes.PipeClasses)Param1, (Pipes.PipeSubclasses)Param2, out numOutpoints);
                if (obtained)
                {
                    result  = SystemCallResults.OK;
                    Return2 = (uint)numOutpoints;
                }
                else
                {
                    result = SystemCallResults.Fail;
                }
#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Get Num Pipe Outpoints - done");
#endif
            }
            break;

            case SystemCallNumbers.GetPipeOutpoints:
            {
#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Get Pipe Outpoints");
#endif

                bool obtained = Pipes.PipeManager.GetPipeOutpoints(CallerProcess, (Pipes.PipeClasses)Param1, (Pipes.PipeSubclasses)Param2, (Pipes.PipeOutpointsRequest *)Param3);
                if (obtained)
                {
                    result = SystemCallResults.OK;
                }
                else
                {
                    result = SystemCallResults.Fail;
                }

#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Get Pipe Outpoints - done");
#endif
            }
            break;

            case SystemCallNumbers.CreatePipe:
            {
#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Create Pipe");
#endif

                bool created = Pipes.PipeManager.CreatePipe(CallerProcess.Id, Param1, (Pipes.CreatePipeRequest *)Param2);
                if (created)
                {
                    result = SystemCallResults.OK;
                }
                else
                {
                    result = SystemCallResults.Fail;
                }

#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Create Pipe - done");
#endif
            }
            break;

            case SystemCallNumbers.WaitOnPipeCreate:
            {
#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Wait On Pipe Create");
#endif

                bool waiting = Pipes.PipeManager.WaitOnPipeCreate(CallerProcess.Id, CallerThread.Id, (Pipes.PipeClasses)Param1, (Pipes.PipeSubclasses)Param2);
                if (waiting)
                {
                    result = SystemCallResults.Deferred;
                }
                else
                {
                    result = SystemCallResults.Fail;
                }

#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Wait On Pipe Create - done");
#endif
            }
            break;

            case SystemCallNumbers.ReadPipe:
            {
#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Read Pipe");
#endif

                // Need access to calling process' memory to be able to read values from request structure
                ProcessManager.EnableKernelAccessToProcessMemory(CallerProcess);
                Pipes.ReadPipeRequest *RequestPtr = (Pipes.ReadPipeRequest *)Param1;
                int  PipeId   = RequestPtr->PipeId;
                bool Blocking = RequestPtr->Blocking;
                ProcessManager.DisableKernelAccessToProcessMemory(CallerProcess);

                Pipes.PipeManager.RWResults RWResult = Pipes.PipeManager.ReadPipe(PipeId, Blocking, CallerProcess, CallerThread);

                if (RWResult == Pipes.PipeManager.RWResults.Error)
                {
                    result = SystemCallResults.Fail;
                }
                else
                {
                    // Returning Deferred state from here will leave the caller thread
                    //  in whatever state ReadPipe decided it should be in.
                    result = SystemCallResults.Deferred;
                }

#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Read Pipe - done");
#endif
            }
            break;

            case SystemCallNumbers.WritePipe:
            {
#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Write Pipe");
#endif

                // Need access to calling process' memory to be able to read values from request structure
                ProcessManager.EnableKernelAccessToProcessMemory(CallerProcess);
                Pipes.ReadPipeRequest *RequestPtr = (Pipes.ReadPipeRequest *)Param1;
                int  PipeId   = RequestPtr->PipeId;
                bool Blocking = RequestPtr->Blocking;
                ProcessManager.DisableKernelAccessToProcessMemory(CallerProcess);

                Pipes.PipeManager.RWResults RWResult = Pipes.PipeManager.WritePipe(PipeId, Blocking, CallerProcess, CallerThread);

                if (RWResult == Pipes.PipeManager.RWResults.Error)
                {
                    result = SystemCallResults.Fail;
                }
                else
                {
                    // Returning Deferred state from here will leave the caller thread
                    //  in whatever state WritePipe decided it should be in.
                    result = SystemCallResults.Deferred;
                }

#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Write Pipe - done");
#endif
            }
            break;

            default:
#if DSC_TRACE
                BasicConsole.WriteLine("DSC: Unrecognised call number.");
                BasicConsole.WriteLine((uint)syscallNumber);
#endif
                break;
            }

            return(result);
        }
Example #18
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();
                }
            }
        }
Example #19
0
        /// <summary>
        /// Gets the number of available outpoints of the specified class and subclass.
        /// </summary>
        /// <param name="numOutpoints">Out : The number of outpoints (correct iff SysCallResult is OK).</param>
        /// <param name="SysCallResult">Out : The result of the system call. Check this is set to OK.</param>
        /// <param name="Class">The class of pipe to search for.</param>
        /// <param name="Subclass">The subclass of pipe to search for.</param>
        public static void GetNumPipeOutpoints(out int numOutpoints, out SystemCallResults SysCallResult, Pipes.PipeClasses Class, Pipes.PipeSubclasses Subclass)
        {
            SysCallResult = SystemCalls.GetNumPipeOutpoints(Class, Subclass, out numOutpoints);
            switch (SysCallResult)
            {
                case SystemCallResults.Unhandled:
                    //BasicConsole.WriteLine("BasicServerHelpers > GetNumPipeOutpoints: Unhandled!");
                    break;
                case SystemCallResults.Fail:
                    //BasicConsole.WriteLine("BasicServerHelpers > GetNumPipeOutpoints: Failed!");
                    break;
                case SystemCallResults.OK:
                    //BasicConsole.WriteLine("BasicServerHelpers > GetNumPipeOutpoints: Succeeded.");

                    //BasicConsole.Write("BasicServerHelpers > Num pipe outpoints: ");
                    //BasicConsole.WriteLine(numOutpoints);
                    break;
                default:
                    //BasicConsole.WriteLine("BasicServerHelpers > GetNumPipeOutpoints: Unexpected system call result!");
                    break;
            }
        }
Example #20
0
        /// <summary>
        /// Gets the outpoint desciptors of the available outpoints of the specified class and subclass.
        /// </summary>
        /// <param name="numOutpoints">The known number of available outpoints. Use GetNumPipeOutpoints to obtain this number.</param>
        /// <param name="SysCallResult">Out : The result of the system call. Check this is set to OK.</param>
        /// <param name="OutpointDescriptors">Out : The array of outpoint descriptors.</param>
        /// <param name="Class">The class of pipe to search for.</param>
        /// <param name="Subclass">The subclass of pipe to search for.</param>
        public static void GetOutpointDescriptors(int numOutpoints, out SystemCallResults SysCallResult, out Pipes.PipeOutpointDescriptor[] OutpointDescriptors, Pipes.PipeClasses Class, Pipes.PipeSubclasses Subclass)
        {
            OutpointDescriptors = new Pipes.PipeOutpointDescriptor[numOutpoints];

            Pipes.PipeOutpointsRequest* RequestPtr = (Pipes.PipeOutpointsRequest*)Heap.AllocZeroed((uint)sizeof(Pipes.PipeOutpointsRequest), "BasicServerHelpers : Alloc PipeOutpointsRequest");
            if (RequestPtr != null)
            {
                try
                {
                    RequestPtr->MaxDescriptors = numOutpoints;
                    RequestPtr->Outpoints = (Pipes.PipeOutpointDescriptor*)((byte*)Utilities.ObjectUtilities.GetHandle(OutpointDescriptors) + FOS_System.Array.FieldsBytesSize);
                    if (RequestPtr->Outpoints != null)
                    {
                        SysCallResult = SystemCalls.GetPipeOutpoints(Class, Subclass, RequestPtr);
                        switch (SysCallResult)
                        {
                            case SystemCallResults.Unhandled:
                                //BasicConsole.WriteLine("BasicServerHelpers > GetPipeOutpoints: Unhandled!");
                                break;
                            case SystemCallResults.Fail:
                                //BasicConsole.WriteLine("BasicServerHelpers > GetPipeOutpoints: Failed!");
                                break;
                            case SystemCallResults.OK:
                                //BasicConsole.WriteLine("BasicServerHelpers > GetPipeOutpoints: Succeeded.");
                                break;
                            default:
                                //BasicConsole.WriteLine("BasicServerHelpers > GetPipeOutpoints: Unexpected system call result!");
                                break;
                        }
                    }
                    else
                    {
                        SysCallResult = SystemCallResults.Fail;
                        //BasicConsole.WriteLine("BasicServerHelpers > RequestPtr->Outpoints null! No memory allocated.");
                        ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicServerHelpers : Couldn't allocate memory outpoints list in outpoints request!"));
                    }
                }
                finally
                {
                    Heap.Free(RequestPtr);
                }
            }
            else
            {
                SysCallResult = SystemCallResults.Fail;
                //BasicConsole.WriteLine("BasicServerHelpers > RequestPtr null! No memory allocated.");
                ExceptionMethods.Throw(new FOS_System.Exceptions.ArgumentException("BasicServerHelpers : Couldn't allocate memory get outpoints request!"));
            }
        }