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;
+ }
}