From 1ac2ff7d0c3be8cefa92ccba1d5e8e4501a82fb1 Mon Sep 17 00:00:00 2001 From: Og-Rok Date: Mon, 26 Mar 2018 20:44:29 +0100 Subject: [PATCH 1/8] Starting work --- source/Cosmos.Core/Cosmos.Core.csproj | 2 +- source/Cosmos.Core/INTs.cs | 6 +- source/Cosmos.Core/ObjUtilities.cs | 16 +++ .../Cosmos.Core/Processing/ProcessContext.cs | 119 ++++++++++++++++++ .../Processing/ProcessorScheduler.cs | 52 ++++++++ source/Cosmos.Core_Asm/CPU/CPUUpdateIDTAsm.cs | 4 + source/Cosmos.Core_Asm/DelegateImpl.cs | 7 +- source/Cosmos.Core_Asm/ObjUtilitiesImpl.cs | 27 ++++ .../Cosmos.Core_Plugs/System/DelegateImpl.cs | 7 +- source/Cosmos.HAL2/Global.cs | 88 ++++++------- 10 files changed, 281 insertions(+), 47 deletions(-) create mode 100644 source/Cosmos.Core/ObjUtilities.cs create mode 100644 source/Cosmos.Core/Processing/ProcessContext.cs create mode 100644 source/Cosmos.Core/Processing/ProcessorScheduler.cs create mode 100644 source/Cosmos.Core_Asm/ObjUtilitiesImpl.cs diff --git a/source/Cosmos.Core/Cosmos.Core.csproj b/source/Cosmos.Core/Cosmos.Core.csproj index 80aad39bf..ccfbd9782 100644 --- a/source/Cosmos.Core/Cosmos.Core.csproj +++ b/source/Cosmos.Core/Cosmos.Core.csproj @@ -2,7 +2,7 @@ netstandard2.0 - True + true diff --git a/source/Cosmos.Core/INTs.cs b/source/Cosmos.Core/INTs.cs index 71cce306c..8aa6360eb 100644 --- a/source/Cosmos.Core/INTs.cs +++ b/source/Cosmos.Core/INTs.cs @@ -87,7 +87,8 @@ namespace Cosmos.Core { } [StructLayout(LayoutKind.Explicit, Size = 80)] - public struct IRQContext { + public struct IRQContext + { [FieldOffset(0)] public unsafe MMXContext* MMXContext; @@ -138,6 +139,8 @@ namespace Cosmos.Core { [AsmMarker(AsmMarker.Type.Int_LastKnownAddress)] private static uint mLastKnownAddress; + public static uint mStackContext; + private static IRQDelegate[] mIRQ_Handlers = new IRQDelegate[256]; // We used to use: @@ -494,6 +497,7 @@ namespace Cosmos.Core { if (xTest) { unsafe { + mStackContext = 0; var xCtx = new IRQContext(); HandleInterrupt_Default(ref xCtx); HandleInterrupt_00(ref xCtx); diff --git a/source/Cosmos.Core/ObjUtilities.cs b/source/Cosmos.Core/ObjUtilities.cs new file mode 100644 index 000000000..283526006 --- /dev/null +++ b/source/Cosmos.Core/ObjUtilities.cs @@ -0,0 +1,16 @@ +using IL2CPU.API.Attribs; +using System; + +namespace Cosmos.Core +{ + public static unsafe class ObjUtilities + { + public static uint GetPointer(Delegate aVal) + { + return (uint)aVal.GetHashCode(); + } + + [PlugMethod(PlugRequired = true)] + public static uint GetPointer(Object aVal) { return 0; } + } +} diff --git a/source/Cosmos.Core/Processing/ProcessContext.cs b/source/Cosmos.Core/Processing/ProcessContext.cs new file mode 100644 index 000000000..df119d6b3 --- /dev/null +++ b/source/Cosmos.Core/Processing/ProcessContext.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cosmos.Core.Processing +{ + public static unsafe class ProcessContext + { + public enum Thread_State + { + ALIVE = 0, + DEAD = 1, + WAITING_SLEEP = 2, + WAITING_SEMAPHORE = 3, + PAUSED = 4 + } + + public enum Context_Type + { + THREAD = 0, + PROCESS = 1 + } + + public class Context + { + public Context_Type type; + public uint tid; + public string name; + public uint esp; + public uint stacktop; + public uint eip; + public uint cr3; + public Thread_State state; + public Thread_State old_state; + public uint arg; + public uint priority; + public uint age; + public uint parent; + } + + public const uint STACK_SIZE = 4096; + public static uint m_NextCID; + public static int m_CurrentContext; + public static List m_ContextList = new List(256); + + public static Context GetContext() + { + return m_ContextList[m_CurrentContext]; + } + + public static Context GetContext(int tid) + { + for(int i = 0; i < m_ContextList.Count; i++) + { + if(m_ContextList[i].tid == tid) + { + return m_ContextList[i]; + } + } + return null; + } + + public static uint StartContext(string name, System.Threading.ThreadStart entry, Context_Type type, params object[] args) + { + uint address = ObjUtilities.GetPointer(entry); + Context context = new Context(); + context.type = type; + context.tid = m_NextCID++; + context.name = name; + uint[] tmp = new uint[STACK_SIZE / 4]; + fixed (uint* p = tmp) + { + context.esp = (uint)p; + } + context.stacktop = context.esp; + uint* stack = (uint*)(context.esp + 4000); + *--stack = 0xFFFFFFFF; // trash + *--stack = 0xFFFFFFFF; // trash + *--stack = 0xFFFFFFFF; // trash + *--stack = 0xFFFFFFFF; // trash + /*for(int i = 0; i < 512 / 4; i++) + { + *--stack = 0; // MMX + }*/ // nope, just not going to bother today + for(int i = args.Length - 1; i >= 0; i++) // will push arguments when we patch in the object utils + { + *--stack = 0; ObjUtilities.GetPointer(args[i]); + } + *--stack = 0x10; // ss ? + *--stack = 0x00000202; // eflags + *--stack = 0x8; // cs + *--stack = address; // eip + *--stack = 0; // error + *--stack = 0; // int + *--stack = 0; // eax + *--stack = 0; // ebx + *--stack = 0; // ecx + *--stack = *stack; // offset + *--stack = 0; // edx + *--stack = 0; // esi + *--stack = 0; // edi + *--stack = context.esp + 4000; //ebp + context.esp = (uint)stack; + context.eip = address; + context.state = Thread_State.ALIVE; + if (type == Context_Type.PROCESS) + { + context.parent = 0; + } + else + { + Context parent = GetContext(); + context.parent = parent.tid; + } + m_ContextList.Add(context); + return context.tid; + } + } +} diff --git a/source/Cosmos.Core/Processing/ProcessorScheduler.cs b/source/Cosmos.Core/Processing/ProcessorScheduler.cs new file mode 100644 index 000000000..7b63c1b1b --- /dev/null +++ b/source/Cosmos.Core/Processing/ProcessorScheduler.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cosmos.Core.Processing +{ + public static unsafe class ProcessorScheduler + { + public static void test() + { + while (true) + { + for (int i = 0; i < 1000; i++) + { + + } + Console.WriteLine("Thread 2"); + } + } + + public static void Initialize() + { + var context = new ProcessContext.Context(); + context.type = ProcessContext.Context_Type.PROCESS; + context.tid = ProcessContext.m_NextCID++; + context.name = "Boot"; + context.esp = 0; + context.stacktop = 0; + context.eip = 0; + context.cr3 = 0; + context.state = ProcessContext.Thread_State.ALIVE; + context.old_state = ProcessContext.Thread_State.ALIVE; + context.arg = 0; + context.priority = 0; + context.age = 0; + context.parent = 0; + ProcessContext.m_ContextList[0] = context; + //ProcessContext.StartContext("Test", test, ProcessContext.Context_Type.PROCESS); + } + + public static void SwitchTask() + { + /*if (ProcessContext.m_ContextList[0] != null) + { + ProcessContext.m_ContextList[ProcessContext.m_CurrentContext].esp = INTs.mStackContext; + ProcessContext.m_CurrentContext++; + ProcessContext.m_CurrentContext %= (ProcessContext.m_ContextList.Count - 1); + INTs.mStackContext = ProcessContext.m_ContextList[ProcessContext.m_CurrentContext].esp; + }*/ + } + } +} diff --git a/source/Cosmos.Core_Asm/CPU/CPUUpdateIDTAsm.cs b/source/Cosmos.Core_Asm/CPU/CPUUpdateIDTAsm.cs index e0b9db062..e2346ef6c 100644 --- a/source/Cosmos.Core_Asm/CPU/CPUUpdateIDTAsm.cs +++ b/source/Cosmos.Core_Asm/CPU/CPUUpdateIDTAsm.cs @@ -77,6 +77,7 @@ namespace Cosmos.Core_Asm } XS.Push((uint)j); XS.PushAllRegisters(); + XS.Set("static_field__Cosmos_Core_INTs_mStackContext", ESP, destinationIsIndirect: true); XS.Sub(ESP, 4); XS.Set(EAX, ESP); // preserve old stack address for passing to interrupt handler @@ -90,6 +91,7 @@ namespace Cosmos.Core_Asm XS.Push(EAX); // XS.Push(EAX); // pass old stack address (pointer to InterruptContext struct) to the interrupt handler + XS.JumpToSegment(8, "__ISR_Handler_" + j.ToString("X2") + "_SetCS"); XS.Label("__ISR_Handler_" + j.ToString("X2") + "_SetCS"); MethodBase xHandler = GetInterruptHandler((byte)j); @@ -98,12 +100,14 @@ namespace Cosmos.Core_Asm xHandler = GetMethodDef(typeof(Cosmos.Core.INTs).Assembly, typeof(Cosmos.Core.INTs).FullName, "HandleInterrupt_Default", true); } XS.Call(LabelName.Get(xHandler)); + XS.Pop(EAX); XS.SSE.FXRestore(ESP, isIndirect: true); XS.Set(ESP, EAX); // this restores the stack for the FX stuff, except the pointer to the FX data XS.Add(ESP, 4); // "pop" the pointer + XS.Set(ESP, "static_field__Cosmos_Core_INTs_mStackContext", sourceIsIndirect: true); XS.PopAllRegisters(); XS.Add(ESP, 8); diff --git a/source/Cosmos.Core_Asm/DelegateImpl.cs b/source/Cosmos.Core_Asm/DelegateImpl.cs index 627cb0b53..2db320525 100644 --- a/source/Cosmos.Core_Asm/DelegateImpl.cs +++ b/source/Cosmos.Core_Asm/DelegateImpl.cs @@ -4,7 +4,7 @@ using IL2CPU.API.Attribs; namespace Cosmos.Core_Asm { [Plug(Target = typeof(Delegate), Inheritable = true)] - public static class DelegateImpl + public static unsafe class DelegateImpl { [PlugMethod(Assembler = typeof(DelegateCtorAsm), IsWildcard = true, WildcardMatchParameters = true)] public static void Ctor(Delegate aThis, object aTarget, IntPtr aMethod) @@ -28,5 +28,10 @@ namespace Cosmos.Core_Asm { throw new NotImplementedException(); } + + public static int GetHashCode(Delegate aThis, [FieldAccess(Name = "System.IntPtr System.Delegate._methodPtr")] ref IntPtr aAddress) + { + return (int)aAddress.ToPointer(); + } } } diff --git a/source/Cosmos.Core_Asm/ObjUtilitiesImpl.cs b/source/Cosmos.Core_Asm/ObjUtilitiesImpl.cs new file mode 100644 index 000000000..060b95212 --- /dev/null +++ b/source/Cosmos.Core_Asm/ObjUtilitiesImpl.cs @@ -0,0 +1,27 @@ +using Cosmos.Core; +using IL2CPU.API.Attribs; +using System; +using XSharp; +using XSharp.Assembler; + +namespace Cosmos.Core_Asm +{ + [Plug(Target = typeof(ObjUtilities))] + public static unsafe class ObjUtilitiesImpl + { + [PlugMethod(Assembler = typeof(ObjUtilitiesGetPointer))] + public static uint GetPointer(Delegate aVal) { return 0; } + + [PlugMethod(Assembler = typeof(ObjUtilitiesGetPointer))] + public static uint GetPointer(Object aVal) { return 0; } + } + + public class ObjUtilitiesGetPointer : AssemblerMethod + { + public override void AssembleNew(Assembler aAssembler, object aMethodInfo) + { + XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: 0x8); + XS.Push(XSRegisters.EAX); + } + } +} diff --git a/source/Cosmos.Core_Plugs/System/DelegateImpl.cs b/source/Cosmos.Core_Plugs/System/DelegateImpl.cs index 48d81902a..08ec401da 100644 --- a/source/Cosmos.Core_Plugs/System/DelegateImpl.cs +++ b/source/Cosmos.Core_Plugs/System/DelegateImpl.cs @@ -8,7 +8,7 @@ namespace Cosmos.Core_Plugs.System [Plug(Target = typeof(Delegate), Inheritable = true)] [PlugField(FieldType = typeof(int), FieldId = "$$ArgSize$$")] [PlugField(FieldType = typeof(int), FieldId = "$$ReturnsValue$$")] - public static class DelegateImpl + public static unsafe class DelegateImpl { public static bool Equals(Delegate aThis, object aThat) { @@ -38,5 +38,10 @@ namespace Cosmos.Core_Plugs.System } return xResultAddr; } + + public static int GetHashCode(Delegate aThis, [FieldAccess(Name = "System.IntPtr System.Delegate._methodPtr")] ref IntPtr aAddress) + { + return (int)aAddress.ToPointer(); + } } } diff --git a/source/Cosmos.HAL2/Global.cs b/source/Cosmos.HAL2/Global.cs index 9b0dfd95d..d3cb446e8 100644 --- a/source/Cosmos.HAL2/Global.cs +++ b/source/Cosmos.HAL2/Global.cs @@ -5,57 +5,59 @@ using Cosmos.HAL.BlockDevice; namespace Cosmos.HAL { - public static class Global + public static class Global + { + public static readonly Debugger mDebugger = new Debugger("HAL", "Global"); + + static public PIT PIT = new PIT(); + // Must be static init, other static inits rely on it not being null + + public static TextScreenBase TextScreen = new TextScreen(); + public static PCI Pci; + + static public void Init(TextScreenBase textScreen) { - public static readonly Debugger mDebugger = new Debugger("HAL", "Global"); + if (textScreen != null) + { + TextScreen = textScreen; + } - static public PIT PIT = new PIT(); - // Must be static init, other static inits rely on it not being null + mDebugger.Send("Before Core.Global.Init"); + Core.Global.Init(); - public static TextScreenBase TextScreen = new TextScreen(); - public static PCI Pci; + //TODO Redo this - Global init should be other. + // Move PCI detection to hardware? Or leave it in core? Is Core PC specific, or deeper? + // If we let hardware do it, we need to protect it from being used by System. + // Probably belongs in hardware, and core is more specific stuff like CPU, memory, etc. + //Core.PCI.OnPCIDeviceFound = PCIDeviceFound; - static public void Init(TextScreenBase textScreen) - { - if (textScreen != null) - { - TextScreen = textScreen; - } + //TODO: Since this is FCL, its "common". Otherwise it should be + // system level and not accessible from Core. Need to think about this + // for the future. - mDebugger.Send("Before Core.Global.Init"); - Core.Global.Init(); + Console.WriteLine("Finding PCI Devices"); + mDebugger.Send("PCI Devices"); + PCI.Setup(); - //TODO Redo this - Global init should be other. - // Move PCI detection to hardware? Or leave it in core? Is Core PC specific, or deeper? - // If we let hardware do it, we need to protect it from being used by System. - // Probably belongs in hardware, and core is more specific stuff like CPU, memory, etc. - //Core.PCI.OnPCIDeviceFound = PCIDeviceFound; + Console.WriteLine("Starting ACPI"); + mDebugger.Send("ACPI Init"); + ACPI.Start(); - //TODO: Since this is FCL, its "common". Otherwise it should be - // system level and not accessible from Core. Need to think about this - // for the future. + IDE.InitDriver(); + AHCI.InitDriver(); + //EHCI.InitDriver(); + //Core.Processing.ProcessorScheduler.Initialize(); + //PIT.RegisterTimer(new PIT.PITTimer(Core.Processing.ProcessorScheduler.SwitchTask, 20, true)); - Console.WriteLine("Finding PCI Devices"); - mDebugger.Send("PCI Devices"); - PCI.Setup(); + mDebugger.Send("Done initializing Cosmos.HAL.Global"); - Console.WriteLine("Starting ACPI"); - mDebugger.Send("ACPI Init"); - ACPI.Start(); - - IDE.InitDriver(); - AHCI.InitDriver(); - //EHCI.InitDriver(); - - mDebugger.Send("Done initializing Cosmos.HAL.Global"); - - } - - public static void EnableInterrupts() - { - CPU.EnableInterrupts(); - } - - public static bool InterruptsEnabled => CPU.mInterruptsEnabled; } + + public static void EnableInterrupts() + { + CPU.EnableInterrupts(); + } + + public static bool InterruptsEnabled => CPU.mInterruptsEnabled; + } } From bd78428621a34291418906644c6bccb1636d31ea Mon Sep 17 00:00:00 2001 From: Og-Rok Date: Mon, 26 Mar 2018 23:36:09 +0100 Subject: [PATCH 2/8] Trying to use a manual register switching --- source/Cosmos.Core/Processing/ProcessContext.cs | 2 +- source/Cosmos.Core/Processing/ProcessorScheduler.cs | 2 +- source/Cosmos.HAL2/Global.cs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/Cosmos.Core/Processing/ProcessContext.cs b/source/Cosmos.Core/Processing/ProcessContext.cs index df119d6b3..3f8fadb68 100644 --- a/source/Cosmos.Core/Processing/ProcessContext.cs +++ b/source/Cosmos.Core/Processing/ProcessContext.cs @@ -84,7 +84,7 @@ namespace Cosmos.Core.Processing }*/ // nope, just not going to bother today for(int i = args.Length - 1; i >= 0; i++) // will push arguments when we patch in the object utils { - *--stack = 0; ObjUtilities.GetPointer(args[i]); + *--stack = ObjUtilities.GetPointer(args[i]); } *--stack = 0x10; // ss ? *--stack = 0x00000202; // eflags diff --git a/source/Cosmos.Core/Processing/ProcessorScheduler.cs b/source/Cosmos.Core/Processing/ProcessorScheduler.cs index 7b63c1b1b..c1b9c7479 100644 --- a/source/Cosmos.Core/Processing/ProcessorScheduler.cs +++ b/source/Cosmos.Core/Processing/ProcessorScheduler.cs @@ -34,7 +34,7 @@ namespace Cosmos.Core.Processing context.priority = 0; context.age = 0; context.parent = 0; - ProcessContext.m_ContextList[0] = context; + ProcessContext.m_ContextList.Add(context); //ProcessContext.StartContext("Test", test, ProcessContext.Context_Type.PROCESS); } diff --git a/source/Cosmos.HAL2/Global.cs b/source/Cosmos.HAL2/Global.cs index d3cb446e8..8e9496c3e 100644 --- a/source/Cosmos.HAL2/Global.cs +++ b/source/Cosmos.HAL2/Global.cs @@ -46,8 +46,8 @@ namespace Cosmos.HAL IDE.InitDriver(); AHCI.InitDriver(); //EHCI.InitDriver(); - //Core.Processing.ProcessorScheduler.Initialize(); - //PIT.RegisterTimer(new PIT.PITTimer(Core.Processing.ProcessorScheduler.SwitchTask, 20, true)); + Core.Processing.ProcessorScheduler.Initialize(); + PIT.RegisterTimer(new PIT.PITTimer(Core.Processing.ProcessorScheduler.SwitchTask, 20, true)); mDebugger.Send("Done initializing Cosmos.HAL.Global"); From 2d5f637a91c5417d219f824edc14862c38855ae1 Mon Sep 17 00:00:00 2001 From: Og-Rok Date: Wed, 4 Apr 2018 01:22:52 +0100 Subject: [PATCH 3/8] Softwaare Multitasking Working context switching but far from stable. Changes needed to be made to the internals of cosmos to include mutex's in vital components (Heap, Thread Manager, ect). Context switching currently only switches the general registers and does not switch the MMX context, however this will be added in the future. Also when a thread currently dies it takes the whole system down, patches to the IDT handlers needed to be made to prevent system lockup in the future --- source/Cosmos.Core/INTs.cs | 2 + source/Cosmos.Core/ObjUtilities.cs | 3 + .../Cosmos.Core/Processing/ProcessContext.cs | 106 +++++++++++------- .../Processing/ProcessorScheduler.cs | 64 +++++++---- source/Cosmos.Core_Asm/CPU/CPUUpdateIDTAsm.cs | 97 ++++++++++------ source/Cosmos.Core_Asm/ObjUtilitiesImpl.cs | 12 ++ .../System/Threading/ThreadImpl.cs | 6 + source/Cosmos.HAL2/Global.cs | 13 ++- 8 files changed, 209 insertions(+), 94 deletions(-) diff --git a/source/Cosmos.Core/INTs.cs b/source/Cosmos.Core/INTs.cs index 8aa6360eb..2643a8cad 100644 --- a/source/Cosmos.Core/INTs.cs +++ b/source/Cosmos.Core/INTs.cs @@ -548,6 +548,8 @@ namespace Cosmos.Core { HandleInterrupt_47(ref xCtx); HandleInterrupt_48(ref xCtx); HandleInterrupt_49(ref xCtx); + Processing.ProcessorScheduler.SwitchTask(); + Processing.ProcessorScheduler.EntryPoint(); } } } diff --git a/source/Cosmos.Core/ObjUtilities.cs b/source/Cosmos.Core/ObjUtilities.cs index 283526006..0de530713 100644 --- a/source/Cosmos.Core/ObjUtilities.cs +++ b/source/Cosmos.Core/ObjUtilities.cs @@ -12,5 +12,8 @@ namespace Cosmos.Core [PlugMethod(PlugRequired = true)] public static uint GetPointer(Object aVal) { return 0; } + + [PlugMethod(PlugRequired = true)] + public static uint GetEntryPoint() { return 0; } } } diff --git a/source/Cosmos.Core/Processing/ProcessContext.cs b/source/Cosmos.Core/Processing/ProcessContext.cs index df119d6b3..d1918ec06 100644 --- a/source/Cosmos.Core/Processing/ProcessContext.cs +++ b/source/Cosmos.Core/Processing/ProcessContext.cs @@ -23,15 +23,18 @@ namespace Cosmos.Core.Processing public class Context { + public Context next; public Context_Type type; public uint tid; public string name; public uint esp; public uint stacktop; - public uint eip; + public System.Threading.ThreadStart entry; + public System.Threading.ParameterizedThreadStart paramentry; public uint cr3; public Thread_State state; public Thread_State old_state; + public object param; public uint arg; public uint priority; public uint age; @@ -40,79 +43,106 @@ namespace Cosmos.Core.Processing public const uint STACK_SIZE = 4096; public static uint m_NextCID; - public static int m_CurrentContext; - public static List m_ContextList = new List(256); - - public static Context GetContext() - { - return m_ContextList[m_CurrentContext]; - } + public static Context m_CurrentContext; + public static Context m_ContextList; public static Context GetContext(int tid) { - for(int i = 0; i < m_ContextList.Count; i++) + /*for(int i = 0; i < m_ContextList.Count; i++) { if(m_ContextList[i].tid == tid) { return m_ContextList[i]; } + }*/ + Context ctx = m_ContextList; + while(ctx.next != null) + { + ctx = ctx.next; } return null; } - public static uint StartContext(string name, System.Threading.ThreadStart entry, Context_Type type, params object[] args) + public static uint* SetupStack(uint* stack) { - uint address = ObjUtilities.GetPointer(entry); - Context context = new Context(); - context.type = type; - context.tid = m_NextCID++; - context.name = name; - uint[] tmp = new uint[STACK_SIZE / 4]; - fixed (uint* p = tmp) - { - context.esp = (uint)p; - } - context.stacktop = context.esp; - uint* stack = (uint*)(context.esp + 4000); + uint origin = (uint)stack; *--stack = 0xFFFFFFFF; // trash *--stack = 0xFFFFFFFF; // trash *--stack = 0xFFFFFFFF; // trash *--stack = 0xFFFFFFFF; // trash - /*for(int i = 0; i < 512 / 4; i++) - { - *--stack = 0; // MMX - }*/ // nope, just not going to bother today - for(int i = args.Length - 1; i >= 0; i++) // will push arguments when we patch in the object utils - { - *--stack = 0; ObjUtilities.GetPointer(args[i]); - } *--stack = 0x10; // ss ? *--stack = 0x00000202; // eflags *--stack = 0x8; // cs - *--stack = address; // eip + *--stack = ObjUtilities.GetEntryPoint(); // eip *--stack = 0; // error *--stack = 0; // int *--stack = 0; // eax *--stack = 0; // ebx *--stack = 0; // ecx - *--stack = *stack; // offset + *--stack = 0; // offset *--stack = 0; // edx *--stack = 0; // esi *--stack = 0; // edi - *--stack = context.esp + 4000; //ebp - context.esp = (uint)stack; - context.eip = address; + *--stack = origin; //ebp + *--stack = 0x10; // ds + *--stack = 0x10; // fs + *--stack = 0x10; // es + *--stack = 0x10; // gs + return stack; + } + + public static uint StartContext(string name, System.Threading.ThreadStart entry, Context_Type type) + { + Context context = new Context(); + context.type = type; + context.tid = m_NextCID++; + context.name = name; + context.stacktop = GCImplementation.AllocNewObject(4096); + context.esp = (uint)SetupStack((uint*)(context.stacktop + 4000)); context.state = Thread_State.ALIVE; + context.entry = entry; if (type == Context_Type.PROCESS) { context.parent = 0; } else { - Context parent = GetContext(); - context.parent = parent.tid; + context.parent = m_CurrentContext.tid; } - m_ContextList.Add(context); + Context ctx = m_ContextList; + while (ctx.next != null) + { + ctx = ctx.next; + } + ctx.next = context; + return context.tid; + } + + public static uint StartContext(string name, System.Threading.ParameterizedThreadStart entry, Context_Type type, object param) + { + Context context = new Context(); + context.type = type; + context.tid = m_NextCID++; + context.name = name; + context.stacktop = GCImplementation.AllocNewObject(4096); + context.esp = (uint)SetupStack((uint*)(context.stacktop + 4000)); + context.state = Thread_State.ALIVE; + context.paramentry = entry; + context.param = param; + if (type == Context_Type.PROCESS) + { + context.parent = 0; + } + else + { + context.parent = m_CurrentContext.tid; + } + Context ctx = m_ContextList; + while (ctx.next != null) + { + ctx = ctx.next; + } + ctx.next = context; return context.tid; } } diff --git a/source/Cosmos.Core/Processing/ProcessorScheduler.cs b/source/Cosmos.Core/Processing/ProcessorScheduler.cs index 7b63c1b1b..6fe639c7b 100644 --- a/source/Cosmos.Core/Processing/ProcessorScheduler.cs +++ b/source/Cosmos.Core/Processing/ProcessorScheduler.cs @@ -1,32 +1,20 @@ using System; using System.Collections.Generic; using System.Text; +using IL2CPU.API.Attribs; namespace Cosmos.Core.Processing { public static unsafe class ProcessorScheduler { - public static void test() - { - while (true) - { - for (int i = 0; i < 1000; i++) - { - - } - Console.WriteLine("Thread 2"); - } - } - public static void Initialize() { var context = new ProcessContext.Context(); context.type = ProcessContext.Context_Type.PROCESS; context.tid = ProcessContext.m_NextCID++; - context.name = "Boot"; + //context.name = "Boot"; context.esp = 0; context.stacktop = 0; - context.eip = 0; context.cr3 = 0; context.state = ProcessContext.Thread_State.ALIVE; context.old_state = ProcessContext.Thread_State.ALIVE; @@ -34,19 +22,51 @@ namespace Cosmos.Core.Processing context.priority = 0; context.age = 0; context.parent = 0; - ProcessContext.m_ContextList[0] = context; - //ProcessContext.StartContext("Test", test, ProcessContext.Context_Type.PROCESS); + ProcessContext.m_ContextList = context; + ProcessContext.m_CurrentContext = context; + + IOPort counter0 = new IOPort(0x40); + IOPort cmd = new IOPort(0x43); + + int divisor = 1193182 / 20; + cmd.Byte = (0x06 | 0x30); + counter0.Byte = (byte)divisor; + counter0.Byte = (byte)(divisor >> 8); + + IOPort pA1 = new IOPort(0xA1); + IOPort p21 = new IOPort(0xA1); + pA1.Byte = 0x00; + p21.Byte = 0x00; } + public static void EntryPoint() + { + ProcessContext.m_CurrentContext.entry?.Invoke(); + ProcessContext.m_CurrentContext.paramentry?.Invoke(ProcessContext.m_CurrentContext.param); + ProcessContext.m_CurrentContext.state = ProcessContext.Thread_State.DEAD; + while(true) { } // remove from thread pool later + } + + public static int interruptCount; + public static void SwitchTask() { - /*if (ProcessContext.m_ContextList[0] != null) + interruptCount++; + if (ProcessContext.m_CurrentContext != null) { - ProcessContext.m_ContextList[ProcessContext.m_CurrentContext].esp = INTs.mStackContext; - ProcessContext.m_CurrentContext++; - ProcessContext.m_CurrentContext %= (ProcessContext.m_ContextList.Count - 1); - INTs.mStackContext = ProcessContext.m_ContextList[ProcessContext.m_CurrentContext].esp; - }*/ + ProcessContext.m_CurrentContext.esp = INTs.mStackContext; + if (ProcessContext.m_CurrentContext.next != null) + { + ProcessContext.m_CurrentContext = ProcessContext.m_CurrentContext.next; + } + else + { + ProcessContext.m_CurrentContext = ProcessContext.m_ContextList; + } + INTs.mStackContext = ProcessContext.m_CurrentContext.esp; + } + Global.PIC.EoiMaster(); + Global.PIC.EoiSlave(); } } } diff --git a/source/Cosmos.Core_Asm/CPU/CPUUpdateIDTAsm.cs b/source/Cosmos.Core_Asm/CPU/CPUUpdateIDTAsm.cs index e2346ef6c..b0eece31f 100644 --- a/source/Cosmos.Core_Asm/CPU/CPUUpdateIDTAsm.cs +++ b/source/Cosmos.Core_Asm/CPU/CPUUpdateIDTAsm.cs @@ -10,7 +10,7 @@ namespace Cosmos.Core_Asm { public class CPUUpdateIDTAsm : AssemblerMethod { - private static MethodBase GetMethodDef(Assembly aAssembly, string aType, string aMethodName, bool aErrorWhenNotFound) + public static MethodBase GetMethodDef(Assembly aAssembly, string aType, string aMethodName, bool aErrorWhenNotFound) { Type xType = aAssembly.GetType(aType, false); if (xType != null) @@ -70,45 +70,76 @@ namespace Cosmos.Core_Asm { XS.Label("__ISR_Handler_" + j.ToString("X2")); XS.Call("__INTERRUPT_OCCURRED__"); - if (Array.IndexOf(xInterruptsWithParam, j) == -1) { XS.Push(0); } XS.Push((uint)j); - XS.PushAllRegisters(); - XS.Set("static_field__Cosmos_Core_INTs_mStackContext", ESP, destinationIsIndirect: true); - - XS.Sub(ESP, 4); - XS.Set(EAX, ESP); // preserve old stack address for passing to interrupt handler - - // store floating point data - XS.And(ESP, 0xfffffff0); // fxsave needs to be 16-byte alligned - XS.Sub(ESP, 512); // fxsave needs 512 bytes - XS.SSE.FXSave(ESP, isIndirect: true); // save the registers - XS.Set(EAX, ESP, destinationIsIndirect: true); - - XS.Push(EAX); // - XS.Push(EAX); // pass old stack address (pointer to InterruptContext struct) to the interrupt handler - - - XS.JumpToSegment(8, "__ISR_Handler_" + j.ToString("X2") + "_SetCS"); - XS.Label("__ISR_Handler_" + j.ToString("X2") + "_SetCS"); - MethodBase xHandler = GetInterruptHandler((byte)j); - if (xHandler == null) + if (j != 0x20) { - xHandler = GetMethodDef(typeof(Cosmos.Core.INTs).Assembly, typeof(Cosmos.Core.INTs).FullName, "HandleInterrupt_Default", true); + XS.PushAllRegisters(); + + XS.Sub(ESP, 4); + XS.Set(EAX, ESP); // preserve old stack address for passing to interrupt handler + + // store floating point data + XS.And(ESP, 0xfffffff0); // fxsave needs to be 16-byte alligned + XS.Sub(ESP, 512); // fxsave needs 512 bytes + XS.SSE.FXSave(ESP, isIndirect: true); // save the registers + XS.Set(EAX, ESP, destinationIsIndirect: true); + + XS.Push(EAX); // + XS.Push(EAX); // pass old stack address (pointer to InterruptContext struct) to the interrupt handler + + + XS.JumpToSegment(8, "__ISR_Handler_" + j.ToString("X2") + "_SetCS"); + XS.Label("__ISR_Handler_" + j.ToString("X2") + "_SetCS"); + MethodBase xHandler = GetInterruptHandler((byte)j); + if (xHandler == null) + { + xHandler = GetMethodDef(typeof(Cosmos.Core.INTs).Assembly, typeof(Cosmos.Core.INTs).FullName, "HandleInterrupt_Default", true); + } + XS.Call(LabelName.Get(xHandler)); + + XS.Pop(EAX); + XS.SSE.FXRestore(ESP, isIndirect: true); + + XS.Set(ESP, EAX); // this restores the stack for the FX stuff, except the pointer to the FX data + XS.Add(ESP, 4); // "pop" the pointer + + XS.PopAllRegisters(); + } + else + { + new LiteralAssemblerCode("pushad"); + new LiteralAssemblerCode("mov eax, ds"); + new LiteralAssemblerCode("push eax"); + new LiteralAssemblerCode("mov eax, es"); + new LiteralAssemblerCode("push eax"); + new LiteralAssemblerCode("mov eax, fs"); + new LiteralAssemblerCode("push eax"); + new LiteralAssemblerCode("mov eax, gs"); + new LiteralAssemblerCode("push eax"); + new LiteralAssemblerCode("mov ax, 0x10"); + new LiteralAssemblerCode("mov ds, ax"); + new LiteralAssemblerCode("mov es, ax"); + new LiteralAssemblerCode("mov fs, ax"); + new LiteralAssemblerCode("mov gs, ax"); + new LiteralAssemblerCode("mov eax, esp"); + XS.Set("static_field__Cosmos_Core_INTs_mStackContext", EAX, destinationIsIndirect: true); + XS.Call(LabelName.Get(GetMethodDef(typeof(Cosmos.Core.Processing.ProcessorScheduler).Assembly, typeof(Cosmos.Core.Processing.ProcessorScheduler).FullName, "SwitchTask", true))); + XS.Set(EAX, "static_field__Cosmos_Core_INTs_mStackContext", sourceIsIndirect: true); + new LiteralAssemblerCode("mov esp, eax"); + new LiteralAssemblerCode("pop eax"); + new LiteralAssemblerCode("mov gs, eax"); + new LiteralAssemblerCode("pop eax"); + new LiteralAssemblerCode("mov fs, eax"); + new LiteralAssemblerCode("pop eax"); + new LiteralAssemblerCode("mov es, eax"); + new LiteralAssemblerCode("pop eax"); + new LiteralAssemblerCode("mov ds, eax"); + new LiteralAssemblerCode("popad"); } - XS.Call(LabelName.Get(xHandler)); - - XS.Pop(EAX); - XS.SSE.FXRestore(ESP, isIndirect: true); - - XS.Set(ESP, EAX); // this restores the stack for the FX stuff, except the pointer to the FX data - XS.Add(ESP, 4); // "pop" the pointer - - XS.Set(ESP, "static_field__Cosmos_Core_INTs_mStackContext", sourceIsIndirect: true); - XS.PopAllRegisters(); XS.Add(ESP, 8); XS.Label("__ISR_Handler_" + j.ToString("X2") + "_END"); diff --git a/source/Cosmos.Core_Asm/ObjUtilitiesImpl.cs b/source/Cosmos.Core_Asm/ObjUtilitiesImpl.cs index 060b95212..9f36204fb 100644 --- a/source/Cosmos.Core_Asm/ObjUtilitiesImpl.cs +++ b/source/Cosmos.Core_Asm/ObjUtilitiesImpl.cs @@ -14,6 +14,9 @@ namespace Cosmos.Core_Asm [PlugMethod(Assembler = typeof(ObjUtilitiesGetPointer))] public static uint GetPointer(Object aVal) { return 0; } + + [PlugMethod(Assembler = typeof(ObjUtilitiesGetEntry))] + public static uint GetEntryPoint() { return 0; } } public class ObjUtilitiesGetPointer : AssemblerMethod @@ -24,4 +27,13 @@ namespace Cosmos.Core_Asm XS.Push(XSRegisters.EAX); } } + + public class ObjUtilitiesGetEntry : AssemblerMethod + { + public override void AssembleNew(Assembler aAssembler, object aMethodInfo) + { + XS.Set(XSRegisters.EAX, LabelName.Get(CPUUpdateIDTAsm.GetMethodDef(typeof(Cosmos.Core.Processing.ProcessorScheduler).Assembly, typeof(Cosmos.Core.Processing.ProcessorScheduler).FullName, "EntryPoint", true))); + XS.Push(XSRegisters.EAX); + } + } } diff --git a/source/Cosmos.Core_Plugs/System/Threading/ThreadImpl.cs b/source/Cosmos.Core_Plugs/System/Threading/ThreadImpl.cs index 3aa0ec06d..bc89a40e9 100644 --- a/source/Cosmos.Core_Plugs/System/Threading/ThreadImpl.cs +++ b/source/Cosmos.Core_Plugs/System/Threading/ThreadImpl.cs @@ -1,5 +1,6 @@ using System.Threading; using IL2CPU.API.Attribs; +using Console = System.Console; namespace Cosmos.Core_Plugs.System.Threading { @@ -16,6 +17,11 @@ namespace Cosmos.Core_Plugs.System.Threading } + public static void Ctor(ThreadStart aThis, ThreadStart aEntry) + { + Console.WriteLine("Thread started"); + } + // public static void SleepInternal(int ms) // { // // Implementation of http://referencesource.microsoft.com/#mscorlib/system/threading/thread.cs,6a577476abf2f437,references diff --git a/source/Cosmos.HAL2/Global.cs b/source/Cosmos.HAL2/Global.cs index d3cb446e8..b4c679163 100644 --- a/source/Cosmos.HAL2/Global.cs +++ b/source/Cosmos.HAL2/Global.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using Cosmos.Core; using Cosmos.Debug.Kernel; using Cosmos.HAL.BlockDevice; @@ -46,7 +47,7 @@ namespace Cosmos.HAL IDE.InitDriver(); AHCI.InitDriver(); //EHCI.InitDriver(); - //Core.Processing.ProcessorScheduler.Initialize(); + Core.Processing.ProcessorScheduler.Initialize(); //PIT.RegisterTimer(new PIT.PITTimer(Core.Processing.ProcessorScheduler.SwitchTask, 20, true)); mDebugger.Send("Done initializing Cosmos.HAL.Global"); @@ -59,5 +60,15 @@ namespace Cosmos.HAL } public static bool InterruptsEnabled => CPU.mInterruptsEnabled; + + public static uint SpawnThread(ThreadStart aStart) + { + return Core.Processing.ProcessContext.StartContext("", aStart, Core.Processing.ProcessContext.Context_Type.THREAD); + } + + public static uint SpawnThread(ParameterizedThreadStart aStart, object param) + { + return Core.Processing.ProcessContext.StartContext("", aStart, Core.Processing.ProcessContext.Context_Type.THREAD, param); + } } } From e5085e32610179c48feeca36bc45c6380556e499 Mon Sep 17 00:00:00 2001 From: Og-Rok Date: Wed, 4 Apr 2018 22:41:42 +0100 Subject: [PATCH 4/8] Mutex --- source/Cosmos.Core/Memory/Old/Old_Heap.cs | 20 ++++++++++++- source/Cosmos.Core/Processing/Mutex.cs | 25 ++++++++++++++++ source/Cosmos.Core_Asm/MutexImpl.cs | 36 +++++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 source/Cosmos.Core/Processing/Mutex.cs create mode 100644 source/Cosmos.Core_Asm/MutexImpl.cs diff --git a/source/Cosmos.Core/Memory/Old/Old_Heap.cs b/source/Cosmos.Core/Memory/Old/Old_Heap.cs index 13c55a4a2..c017e64ff 100644 --- a/source/Cosmos.Core/Memory/Old/Old_Heap.cs +++ b/source/Cosmos.Core/Memory/Old/Old_Heap.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading.Tasks; using Cosmos.Core; +using Cosmos.Core.Processing; using Cosmos.Debug.Kernel; namespace Cosmos.Core.Memory.Old @@ -19,6 +20,8 @@ namespace Cosmos.Core.Memory.Old private static uint mLastEntryIndex = 0u; + private static Mutex mMemeoryGate = new Mutex(); + private static void DoInitialize(uint aEndOfRam) { mLastTableIndex = 0u; @@ -57,7 +60,10 @@ namespace Cosmos.Core.Memory.Old try { EnsureIsInitialized(); - + if(mMemeoryGate != null) + { + mMemeoryGate.Lock(); + } var xCurrentTableIdx = mLastTableIndex; DataLookupTable* xCurrentTable = GlobalSystemInfo.GlobalInformationTable->FirstDataLookupTable; DataLookupTable* xPreviousTable = null; @@ -75,6 +81,10 @@ namespace Cosmos.Core.Memory.Old { } } + if (mMemeoryGate != null) + { + mMemeoryGate.Unlock(); + } return xResult; } xCurrentTableIdx++; @@ -112,6 +122,10 @@ namespace Cosmos.Core.Memory.Old } mLastTableIndex = xCurrentTableIdx; mLastEntryIndex = 0; + if (mMemeoryGate != null) + { + mMemeoryGate.Unlock(); + } return xResult; } finally @@ -124,6 +138,10 @@ namespace Cosmos.Core.Memory.Old { //mDebugger.Trace(" Not enabling interrupts, because they weren't enabled yet!"); } + if (mMemeoryGate != null) + { + mMemeoryGate.Unlock(); + } } } diff --git a/source/Cosmos.Core/Processing/Mutex.cs b/source/Cosmos.Core/Processing/Mutex.cs new file mode 100644 index 000000000..0fda8f0e9 --- /dev/null +++ b/source/Cosmos.Core/Processing/Mutex.cs @@ -0,0 +1,25 @@ +using IL2CPU.API.Attribs; + +namespace Cosmos.Core.Processing +{ + public unsafe class Mutex + { + public int gate; + + [PlugMethod(PlugRequired = true)] + public static void MutexLock(int* mtx) { } + + public void Lock() + { + fixed (int* p = &gate) + { + MutexLock(p); + } + } + + public void Unlock() + { + gate = 0; + } + } +} diff --git a/source/Cosmos.Core_Asm/MutexImpl.cs b/source/Cosmos.Core_Asm/MutexImpl.cs new file mode 100644 index 000000000..1fb7a23fe --- /dev/null +++ b/source/Cosmos.Core_Asm/MutexImpl.cs @@ -0,0 +1,36 @@ +using Cosmos.Core.Processing; +using IL2CPU.API.Attribs; +using XSharp; +using XSharp.Assembler; + +namespace Cosmos.Core_Asm +{ + [Plug(Target = typeof(Mutex))] + public static unsafe class MutexImpl + { + [PlugMethod(Assembler = typeof(MutexLockASM))] + public static void MutexLock(int* mtx) { } + } + + public class MutexLockASM : AssemblerMethod + { + public override void AssembleNew(Assembler aAssembler, object aMethodInfo) + { + new LiteralAssemblerCode("lock_asm:"); + new LiteralAssemblerCode("mov eax, [esp + 8]"); + new LiteralAssemblerCode("mov ebx, 0"); + new LiteralAssemblerCode("lock bts[eax], ebx"); + new LiteralAssemblerCode("jc.spin_wait"); + new LiteralAssemblerCode("mov ebx, 1"); + new LiteralAssemblerCode("mov dword[eax], ebx"); + new LiteralAssemblerCode("jmp .finished"); + new LiteralAssemblerCode(".spin_wait:"); + new LiteralAssemblerCode("mov ebx, 1"); + new LiteralAssemblerCode("test dword[eax], ebx"); + new LiteralAssemblerCode("pause"); + new LiteralAssemblerCode("jnz.spin_wait"); + new LiteralAssemblerCode("jmp lock_asm"); + new LiteralAssemblerCode(".finished"); + } + } +} From c94ca83079263e6a369b92b659ddd7fec2563d8c Mon Sep 17 00:00:00 2001 From: Og-Rok Date: Wed, 4 Apr 2018 22:59:31 +0100 Subject: [PATCH 5/8] Removed conflicts issues --- source/Cosmos.Core/Processing/ProcessContext.cs | 11 ----------- source/Cosmos.Core/Processing/ProcessorScheduler.cs | 7 +------ source/Cosmos.HAL2/Global.cs | 6 +----- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/source/Cosmos.Core/Processing/ProcessContext.cs b/source/Cosmos.Core/Processing/ProcessContext.cs index 852e53a1a..d1918ec06 100644 --- a/source/Cosmos.Core/Processing/ProcessContext.cs +++ b/source/Cosmos.Core/Processing/ProcessContext.cs @@ -70,17 +70,6 @@ namespace Cosmos.Core.Processing *--stack = 0xFFFFFFFF; // trash *--stack = 0xFFFFFFFF; // trash *--stack = 0xFFFFFFFF; // trash -<<<<<<< HEAD -======= - /*for(int i = 0; i < 512 / 4; i++) - { - *--stack = 0; // MMX - }*/ // nope, just not going to bother today - for(int i = args.Length - 1; i >= 0; i++) // will push arguments when we patch in the object utils - { - *--stack = ObjUtilities.GetPointer(args[i]); - } ->>>>>>> origin/OgRok-Multitasking *--stack = 0x10; // ss ? *--stack = 0x00000202; // eflags *--stack = 0x8; // cs diff --git a/source/Cosmos.Core/Processing/ProcessorScheduler.cs b/source/Cosmos.Core/Processing/ProcessorScheduler.cs index 265bbe4a7..c859fe197 100644 --- a/source/Cosmos.Core/Processing/ProcessorScheduler.cs +++ b/source/Cosmos.Core/Processing/ProcessorScheduler.cs @@ -12,7 +12,7 @@ namespace Cosmos.Core.Processing var context = new ProcessContext.Context(); context.type = ProcessContext.Context_Type.PROCESS; context.tid = ProcessContext.m_NextCID++; - //context.name = "Boot"; + context.name = "Boot"; context.esp = 0; context.stacktop = 0; context.cr3 = 0; @@ -22,7 +22,6 @@ namespace Cosmos.Core.Processing context.priority = 0; context.age = 0; context.parent = 0; -<<<<<<< HEAD ProcessContext.m_ContextList = context; ProcessContext.m_CurrentContext = context; @@ -38,10 +37,6 @@ namespace Cosmos.Core.Processing IOPort p21 = new IOPort(0xA1); pA1.Byte = 0x00; p21.Byte = 0x00; -======= - ProcessContext.m_ContextList.Add(context); - //ProcessContext.StartContext("Test", test, ProcessContext.Context_Type.PROCESS); ->>>>>>> origin/OgRok-Multitasking } public static void EntryPoint() diff --git a/source/Cosmos.HAL2/Global.cs b/source/Cosmos.HAL2/Global.cs index 31dccdbd4..694576317 100644 --- a/source/Cosmos.HAL2/Global.cs +++ b/source/Cosmos.HAL2/Global.cs @@ -47,12 +47,8 @@ namespace Cosmos.HAL IDE.InitDriver(); AHCI.InitDriver(); //EHCI.InitDriver(); + Core.Processing.ProcessorScheduler.Initialize(); -<<<<<<< HEAD - //PIT.RegisterTimer(new PIT.PITTimer(Core.Processing.ProcessorScheduler.SwitchTask, 20, true)); -======= - PIT.RegisterTimer(new PIT.PITTimer(Core.Processing.ProcessorScheduler.SwitchTask, 20, true)); ->>>>>>> origin/OgRok-Multitasking mDebugger.Send("Done initializing Cosmos.HAL.Global"); From f0ff67bf9088b8bec68f64820f5e995ffc991b73 Mon Sep 17 00:00:00 2001 From: Og-Rok Date: Thu, 5 Apr 2018 01:22:06 +0100 Subject: [PATCH 6/8] Threading Added sleeping and task termination --- source/Cosmos.Core/Processing/Mutex.cs | 6 ++- .../Cosmos.Core/Processing/ProcessContext.cs | 19 +++++--- .../Processing/ProcessorScheduler.cs | 36 +++++++++++++-- source/Cosmos.System2/Thread.cs | 45 +++++++++++++++++++ 4 files changed, 94 insertions(+), 12 deletions(-) create mode 100644 source/Cosmos.System2/Thread.cs diff --git a/source/Cosmos.Core/Processing/Mutex.cs b/source/Cosmos.Core/Processing/Mutex.cs index 0fda8f0e9..1fc909a5f 100644 --- a/source/Cosmos.Core/Processing/Mutex.cs +++ b/source/Cosmos.Core/Processing/Mutex.cs @@ -11,10 +11,12 @@ namespace Cosmos.Core.Processing public void Lock() { - fixed (int* p = &gate) + while(gate != 0) { } + gate = 1; + /*fixed (int* p = &gate) { MutexLock(p); - } + }*/ } public void Unlock() diff --git a/source/Cosmos.Core/Processing/ProcessContext.cs b/source/Cosmos.Core/Processing/ProcessContext.cs index d1918ec06..f85a65f7d 100644 --- a/source/Cosmos.Core/Processing/ProcessContext.cs +++ b/source/Cosmos.Core/Processing/ProcessContext.cs @@ -11,8 +11,7 @@ namespace Cosmos.Core.Processing ALIVE = 0, DEAD = 1, WAITING_SLEEP = 2, - WAITING_SEMAPHORE = 3, - PAUSED = 4 + PAUSED = 3 } public enum Context_Type @@ -31,11 +30,9 @@ namespace Cosmos.Core.Processing public uint stacktop; public System.Threading.ThreadStart entry; public System.Threading.ParameterizedThreadStart paramentry; - public uint cr3; public Thread_State state; - public Thread_State old_state; public object param; - public uint arg; + public int arg; public uint priority; public uint age; public uint parent; @@ -46,7 +43,7 @@ namespace Cosmos.Core.Processing public static Context m_CurrentContext; public static Context m_ContextList; - public static Context GetContext(int tid) + public static Context GetContext(uint tid) { /*for(int i = 0; i < m_ContextList.Count; i++) { @@ -58,8 +55,16 @@ namespace Cosmos.Core.Processing Context ctx = m_ContextList; while(ctx.next != null) { + if(ctx.tid == tid) + { + return ctx; + } ctx = ctx.next; } + if (ctx.tid == tid) + { + return ctx; + } return null; } @@ -99,7 +104,7 @@ namespace Cosmos.Core.Processing context.name = name; context.stacktop = GCImplementation.AllocNewObject(4096); context.esp = (uint)SetupStack((uint*)(context.stacktop + 4000)); - context.state = Thread_State.ALIVE; + context.state = Thread_State.PAUSED; context.entry = entry; if (type == Context_Type.PROCESS) { diff --git a/source/Cosmos.Core/Processing/ProcessorScheduler.cs b/source/Cosmos.Core/Processing/ProcessorScheduler.cs index c859fe197..b39cdad31 100644 --- a/source/Cosmos.Core/Processing/ProcessorScheduler.cs +++ b/source/Cosmos.Core/Processing/ProcessorScheduler.cs @@ -15,9 +15,7 @@ namespace Cosmos.Core.Processing context.name = "Boot"; context.esp = 0; context.stacktop = 0; - context.cr3 = 0; context.state = ProcessContext.Thread_State.ALIVE; - context.old_state = ProcessContext.Thread_State.ALIVE; context.arg = 0; context.priority = 0; context.age = 0; @@ -28,7 +26,7 @@ namespace Cosmos.Core.Processing IOPort counter0 = new IOPort(0x40); IOPort cmd = new IOPort(0x43); - int divisor = 1193182 / 20; + int divisor = 1193182 / 25; cmd.Byte = (0x06 | 0x30); counter0.Byte = (byte)divisor; counter0.Byte = (byte)(divisor >> 8); @@ -54,7 +52,34 @@ namespace Cosmos.Core.Processing interruptCount++; if (ProcessContext.m_CurrentContext != null) { + ProcessContext.Context ctx = ProcessContext.m_ContextList; + ProcessContext.Context last = ctx; + while (ctx != null) + { + if(ctx.state == ProcessContext.Thread_State.DEAD) + { + last.next = ctx.next; + break; + } + last = ctx; + ctx = ctx.next; + } + ctx = ProcessContext.m_ContextList; + while (ctx != null) + { + if(ctx.state == ProcessContext.Thread_State.WAITING_SLEEP) + { + ctx.arg -= 1000 / 25; + if(ctx.arg <= 0) + { + ctx.state = ProcessContext.Thread_State.ALIVE; + } + } + ctx.age++; + ctx = ctx.next; + } ProcessContext.m_CurrentContext.esp = INTs.mStackContext; + tryagain:; if (ProcessContext.m_CurrentContext.next != null) { ProcessContext.m_CurrentContext = ProcessContext.m_CurrentContext.next; @@ -63,6 +88,11 @@ namespace Cosmos.Core.Processing { ProcessContext.m_CurrentContext = ProcessContext.m_ContextList; } + if(ProcessContext.m_CurrentContext.state != ProcessContext.Thread_State.ALIVE) + { + goto tryagain; + } + ProcessContext.m_CurrentContext.age = ProcessContext.m_CurrentContext.priority; INTs.mStackContext = ProcessContext.m_CurrentContext.esp; } Global.PIC.EoiMaster(); diff --git a/source/Cosmos.System2/Thread.cs b/source/Cosmos.System2/Thread.cs new file mode 100644 index 000000000..f3f62d026 --- /dev/null +++ b/source/Cosmos.System2/Thread.cs @@ -0,0 +1,45 @@ +using st = System.Threading; + +namespace Cosmos.System +{ + public class Thread + { + public uint ThreadID; + private Cosmos.Core.Processing.ProcessContext.Context Data; + + public Thread(st.ThreadStart start) + { + ThreadID = Cosmos.HAL.Global.SpawnThread(start); + ThreadFinalSetup(); + } + + public Thread(st.ParameterizedThreadStart start, object param) + { + ThreadID = Cosmos.HAL.Global.SpawnThread(start, param); + ThreadFinalSetup(); + } + + private void ThreadFinalSetup() + { + Data = Cosmos.Core.Processing.ProcessContext.GetContext(ThreadID); + Data.state = Core.Processing.ProcessContext.Thread_State.PAUSED; + } + + public void Start() + { + Data.state = Core.Processing.ProcessContext.Thread_State.ALIVE; + } + + public void Stop() + { + Data.state = Core.Processing.ProcessContext.Thread_State.PAUSED; + } + + public static void Sleep(int ms) + { + Cosmos.Core.Processing.ProcessContext.m_CurrentContext.arg = ms; + Cosmos.Core.Processing.ProcessContext.m_CurrentContext.state = Core.Processing.ProcessContext.Thread_State.WAITING_SLEEP; + while(Cosmos.Core.Processing.ProcessContext.m_CurrentContext.state == Core.Processing.ProcessContext.Thread_State.WAITING_SLEEP) { } + } + } +} From b2c8e33cdd1c6e0f6dd3c01bc5965ccb45dfa0ba Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Thu, 5 Apr 2018 09:24:54 +0200 Subject: [PATCH 7/8] Update Global.cs --- source/Cosmos.HAL2/Global.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/Cosmos.HAL2/Global.cs b/source/Cosmos.HAL2/Global.cs index 694576317..66986bdcc 100644 --- a/source/Cosmos.HAL2/Global.cs +++ b/source/Cosmos.HAL2/Global.cs @@ -43,11 +43,15 @@ namespace Cosmos.HAL Console.WriteLine("Starting ACPI"); mDebugger.Send("ACPI Init"); ACPI.Start(); - + + Console.WriteLine("Finding ATA Devices"); + mDebugger.Send("ATA Devices") IDE.InitDriver(); AHCI.InitDriver(); //EHCI.InitDriver(); + Console.WriteLine("Starting Processor Scheduler"); + mDebugger.Send("Processor Scheduler") Core.Processing.ProcessorScheduler.Initialize(); mDebugger.Send("Done initializing Cosmos.HAL.Global"); From 51c91a002132a1130cef5c8b73bc624ed7e45465 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Thu, 5 Apr 2018 19:06:08 +0200 Subject: [PATCH 8/8] Update Global.cs --- source/Cosmos.HAL2/Global.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/Cosmos.HAL2/Global.cs b/source/Cosmos.HAL2/Global.cs index 66986bdcc..8928e592e 100644 --- a/source/Cosmos.HAL2/Global.cs +++ b/source/Cosmos.HAL2/Global.cs @@ -45,13 +45,13 @@ namespace Cosmos.HAL ACPI.Start(); Console.WriteLine("Finding ATA Devices"); - mDebugger.Send("ATA Devices") + mDebugger.Send("ATA Devices"); IDE.InitDriver(); AHCI.InitDriver(); //EHCI.InitDriver(); Console.WriteLine("Starting Processor Scheduler"); - mDebugger.Send("Processor Scheduler") + mDebugger.Send("Processor Scheduler"); Core.Processing.ProcessorScheduler.Initialize(); mDebugger.Send("Done initializing Cosmos.HAL.Global");