From 1ac2ff7d0c3be8cefa92ccba1d5e8e4501a82fb1 Mon Sep 17 00:00:00 2001 From: Og-Rok Date: Mon, 26 Mar 2018 20:44:29 +0100 Subject: [PATCH] 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; + } }