diff --git a/Source/Data/ARM32-Instructions.json b/Source/Data/ARM32-Instructions.json index fff3c83d48..33d6395dd1 100644 --- a/Source/Data/ARM32-Instructions.json +++ b/Source/Data/ARM32-Instructions.json @@ -931,11 +931,11 @@ "OpcodeEncoding": [ { "Condition": "[register][constant]", - "Encoding": "[arm-single-data-transfer-immediate],u=updir:status,rd=reg4:r,rn=reg4:o1,i=0,p=0,l=1,w=0,b=0,offset=imm12:o2" + "Encoding": "[arm-single-data-transfer-immediate],u=updir:status,rd=reg4:r,rn=reg4:o1,i=0,p=0,l=1,w=writeback:status,b=0,offset=imm12:o2" }, { "Condition": "[register][register]", - "Encoding": "[arm-single-data-transfer-shift-register],u=updir:status,rd=reg4:r,rn=reg4:o1,shiftamount=00000,shifttype=00,rm=reg4:o2,i=0,p=0,l=1,w=0,b=0" + "Encoding": "[arm-single-data-transfer-shift-register],u=updir:status,rd=reg4:r,rn=reg4:o1,shiftamount=00000,shifttype=00,rm=reg4:o2,i=0,p=0,l=1,w=writeback:status,b=0" } ] }, @@ -956,11 +956,11 @@ "OpcodeEncoding": [ { "Condition": "[register][constant]", - "Encoding": "[arm-single-data-transfer-immediate],rd=reg4:r,rn=reg4:o1,i=0,p=0,l=1,w=0,b=1,u=updir:status,offset=imm12:o2" + "Encoding": "[arm-single-data-transfer-immediate],rd=reg4:r,rn=reg4:o1,i=0,p=0,l=1,w=writeback:status,b=1,u=updir:status,offset=imm12:o2" }, { "Condition": "[register][register]", - "Encoding": "[arm-single-data-transfer-shift-register],rd=reg4:r,rn=reg4:o1,shiftamount=00000,shifttype=00,rm=reg4:o2,i=0,p=0,l=1,w=0,b=1,u=updir:status" + "Encoding": "[arm-single-data-transfer-shift-register],rd=reg4:r,rn=reg4:o1,shiftamount=00000,shifttype=00,rm=reg4:o2,i=0,p=0,l=1,w=writeback:status,b=1,u=updir:status" } ] }, @@ -981,11 +981,11 @@ "OpcodeEncoding": [ { "Condition": "[register][constant]", - "Encoding": "[arm-halfword-data-transfer-immediate],rd=reg4:r,rn=reg4:o1,i=1,p=0,l=1,w=0,b=0,offsethigh=imm4hn:o2,offsetlow=imm4:o2,u=updir:status,s=0,h=1" + "Encoding": "[arm-halfword-data-transfer-immediate],rd=reg4:r,rn=reg4:o1,i=1,p=0,l=1,w=writeback:status,b=0,offsethigh=imm4hn:o2,offsetlow=imm4:o2,u=updir:status,s=0,h=1" }, { "Condition": "[register][register]", - "Encoding": "[arm-halfword-data-transfer-register],rd=reg4:r,rn=reg4:o1,h=1,rm=reg4:o2,i=0,p=0,l=1,w=0,b=1,u=updir:status,s=0,h=1" + "Encoding": "[arm-halfword-data-transfer-register],rd=reg4:r,rn=reg4:o1,h=1,rm=reg4:o2,i=0,p=0,l=1,w=writeback:status,b=1,u=updir:status,s=0,h=1" } ] }, @@ -1006,11 +1006,11 @@ "OpcodeEncoding": [ { "Condition": "[register][constant]", - "Encoding": "[arm-halfword-data-transfer-immediate],rd=reg4:r,rn=reg4:o1,i=1,p=0,l=1,w=0,b=1,offsethigh=imm4hn:o2,offsetlow=imm4:o2,u=updir:status,s=1,h=1" + "Encoding": "[arm-halfword-data-transfer-immediate],rd=reg4:r,rn=reg4:o1,i=1,p=0,l=1,w=writeback:status,b=1,offsethigh=imm4hn:o2,offsetlow=imm4:o2,u=updir:status,s=1,h=1" }, { "Condition": "[register][register]", - "Encoding": "[arm-halfword-data-transfer-register],rd=reg4:r,rn=reg4:o1,h=1,rm=reg4:o2,i=0,p=0,l=1,w=0,b=0,u=updir:status,s=1,h=1" + "Encoding": "[arm-halfword-data-transfer-register],rd=reg4:r,rn=reg4:o1,h=1,rm=reg4:o2,i=0,p=0,l=1,w=writeback:status,b=0,u=updir:status,s=1,h=1" } ] }, @@ -1031,11 +1031,11 @@ "OpcodeEncoding": [ { "Condition": "[register][constant]", - "Encoding": "[arm-halfword-data-transfer-immediate],rd=reg4:r,rn=reg4:o1,i=1,p=0,l=1,w=0,b=1,offsethigh=imm4hn:o2,offsetlow=imm4:o2,u=updir:status,s=1,h=0" + "Encoding": "[arm-halfword-data-transfer-immediate],rd=reg4:r,rn=reg4:o1,i=1,p=0,l=1,w=writeback:status,b=1,offsethigh=imm4hn:o2,offsetlow=imm4:o2,u=updir:status,s=1,h=0" }, { "Condition": "[register][register]", - "Encoding": "[arm-halfword-data-transfer-register],rd=reg4:r,rn=reg4:o1,rm=reg4:o2,i=0,p=0,l=1,w=0,b=0,u=updir:status,s=1,h=0" + "Encoding": "[arm-halfword-data-transfer-register],rd=reg4:r,rn=reg4:o1,rm=reg4:o2,i=0,p=0,l=1,w=writeback:status,b=0,u=updir:status,s=1,h=0" } ] }, @@ -1056,11 +1056,11 @@ "OpcodeEncoding": [ { "Condition": "[register][constant][register]", - "Encoding": "[arm-single-data-transfer-immediate],rd=reg4:o3,rn=reg4:o1,i=0,p=0,l=0,w=0,b=0,u=updir:status,offset=imm12:o2" + "Encoding": "[arm-single-data-transfer-immediate],rd=reg4:o3,rn=reg4:o1,i=0,p=0,l=0,w=writeback:status,b=0,u=updir:status,offset=imm12:o2" }, { "Condition": "[register][register][register]", - "Encoding": "[arm-single-data-transfer-shift-register],rd=reg4:o3,rn=reg4:o1,i=0,p=0,l=0,w=0,b=0,u=updir:status,shiftamount=00000,shifttype=00,rm=reg4:o2" + "Encoding": "[arm-single-data-transfer-shift-register],rd=reg4:o3,rn=reg4:o1,i=0,p=0,l=0,w=writeback:status,b=0,u=updir:status,shiftamount=00000,shifttype=00,rm=reg4:o2" } ] }, @@ -1081,11 +1081,11 @@ "OpcodeEncoding": [ { "Condition": "[register][constant][register]", - "Encoding": "[arm-single-data-transfer-immediate],rd=reg4:o3,rn=reg4:o1,i=0,p=0,l=0,w=0,b=1,u=updir:status,offset=imm12:o2" + "Encoding": "[arm-single-data-transfer-immediate],rd=reg4:o3,rn=reg4:o1,i=0,p=0,l=0,w=writeback:status,b=1,u=updir:status,offset=imm12:o2" }, { "Condition": "[register][register][register]", - "Encoding": "[arm-single-data-transfer-shift-register],rd=reg4:o3,rn=reg4:o1,i=0,p=0,l=0,w=0,b=1,u=updir:status,shiftamount=00000,shifttype=00,rm=reg4:o2" + "Encoding": "[arm-single-data-transfer-shift-register],rd=reg4:o3,rn=reg4:o1,i=0,p=0,l=0,w=writeback:status,b=1,u=updir:status,shiftamount=00000,shifttype=00,rm=reg4:o2" } ] }, @@ -1106,11 +1106,11 @@ "OpcodeEncoding": [ { "Condition": "[register][constant][register]", - "Encoding": "[arm-halfword-data-transfer-immediate],rd=reg4:o3,rn=reg4:o1,i=1,p=0,l=0,w=0,b=0,offsethigh=imm4hn:o2,offsetlow=imm4:o2,u=updir:status,s=0,h=1" + "Encoding": "[arm-halfword-data-transfer-immediate],rd=reg4:o3,rn=reg4:o1,i=1,p=0,l=0,w=writeback:status,b=0,offsethigh=imm4hn:o2,offsetlow=imm4:o2,u=updir:status,s=0,h=1" }, { "Condition": "[register][register][register]", - "Encoding": "[arm-single-data-transfer-immediate],rd=reg4:o3,rn=reg4:o1,rm=reg4:o2,i=0,p=0,l=0,w=0,b=1,u=updir:status,s=0,h=1" + "Encoding": "[arm-single-data-transfer-immediate],rd=reg4:o3,rn=reg4:o1,rm=reg4:o2,i=0,p=0,l=0,w=writeback:status,b=1,u=updir:status,s=0,h=1" } ] }, @@ -1131,11 +1131,11 @@ "OpcodeEncoding": [ { "Condition": "[register][constant][register]", - "Encoding": "[arm-halfword-data-transfer-immediate],rd=reg4:o3,rn=reg4:o1,i=1,p=0,l=0,w=0,b=1,offsethigh=imm4hn:o2,offsetlow=imm4:o2,u=updir:status,s=1,h=1" + "Encoding": "[arm-halfword-data-transfer-immediate],rd=reg4:o3,rn=reg4:o1,i=1,p=0,l=0,w=writeback:status,b=1,offsethigh=imm4hn:o2,offsetlow=imm4:o2,u=updir:status,s=1,h=1" }, { "Condition": "[register][register][register]", - "Encoding": "[arm-halfword-data-transfer-register],rd=reg4:o3,rn=reg4:o1,rm=reg4:o2,i=0,p=0,l=0,w=0,b=0,u=updir:status,s=1,h=1" + "Encoding": "[arm-halfword-data-transfer-register],rd=reg4:o3,rn=reg4:o1,rm=reg4:o2,i=0,p=0,l=0,w=writeback:status,b=0,u=updir:status,s=1,h=1" } ] }, @@ -1156,11 +1156,11 @@ "OpcodeEncoding": [ { "Condition": "[register][constant][register]", - "Encoding": "[arm-halfword-data-transfer-immediate],rd=reg4:o3,rn=reg4:o1,i=1,p=0,l=0,w=0,b=1,offsethigh=imm4hn:o2,offsetlow=imm4:o2,u=updir:status,s=1,h=0" + "Encoding": "[arm-halfword-data-transfer-immediate],rd=reg4:o3,rn=reg4:o1,i=1,p=0,l=0,w=writeback:status,b=1,offsethigh=imm4hn:o2,offsetlow=imm4:o2,u=updir:status,s=1,h=0" }, { "Condition": "[register][register][register]", - "Encoding": "[arm-halfword-data-transfer-register],rd=reg4:o3,rn=reg4:o1,rm=reg4:o2,i=0,p=0,l=0,w=0,b=0,u=updir:status,s=1,h=0" + "Encoding": "[arm-halfword-data-transfer-register],rd=reg4:o3,rn=reg4:o1,rm=reg4:o2,i=0,p=0,l=0,w=writeback:status,b=0,u=updir:status,s=1,h=0" } ] }, @@ -1366,7 +1366,7 @@ "OpcodeEncoding": [ { "Condition": "[register][constant][constant]", - "Encoding": "[arm-block-transfer],p=0,u=updir:status,s=imm1:o2,w=0,l=1,rn=reg4:o1,list=imm16:o2" + "Encoding": "[arm-block-transfer],p=0,u=updir:status,s=imm1:o2,w=writeback:status,l=1,rn=reg4:o1,list=imm16:o2" } ] }, @@ -1386,7 +1386,11 @@ "OpcodeEncoding": [ { "Condition": "[register][constant][constant]", - "Encoding": "[arm-block-transfer],p=1,u=updir:status,s=imm1:o2,w=0,l=0,rn=reg4:o1,list=imm16:o2" + "Encoding": "[arm-block-transfer],p=1,u=updir:status,s=imm1:o2,w=writeback:status,l=0,rn=reg4:o1,list=imm16:o3" + }, + { + "Condition": "[register][constant][register]", + "Encoding": "[arm-block-transfer],p=1,u=updir:status,s=imm1:o2,w=writeback:status,l=0,rn=reg4:o1,list=reg16pow2:o3" } ] }, diff --git a/Source/Docs/settings-options.rst b/Source/Docs/settings-options.rst index e74c99f75f..b50cc76e76 100644 --- a/Source/Docs/settings-options.rst +++ b/Source/Docs/settings-options.rst @@ -13,6 +13,7 @@ Compiler Settings Compiler.Platform,"Platform x86, x64, ARM32, ARM64" Compiler.BaseAddress,Base address of the compiled application + Compiler.InitialStackAddress,Intial stack's starting address (note the stack grows in the downward direction). Compiler.TraceLevel,Trace level for debugging Compiler.MethodScanner,"If true, enable the experimental method scanner" Compiler.Multithreading,"If true, enables multithreading during compiling process" diff --git a/Source/Mosa.BareMetal.HelloWorld/Apps/BootInfo.cs b/Source/Mosa.BareMetal.HelloWorld/Apps/BootInfo.cs index b7c31ff624..db097789e9 100644 --- a/Source/Mosa.BareMetal.HelloWorld/Apps/BootInfo.cs +++ b/Source/Mosa.BareMetal.HelloWorld/Apps/BootInfo.cs @@ -15,14 +15,20 @@ public class BootInfo : IApp public void Execute() { - Console.WriteLine("Command line : " + NullTermString(Multiboot.V2.CommandLinePointer)); - Console.WriteLine("Bootloader name : " + NullTermString(Multiboot.V2.BootloaderNamePointer)); + Console.WriteLine("Command line : " + NullTermString(Multiboot.V2.CommandLine)); + Console.WriteLine("Bootloader name : " + NullTermString(Multiboot.V2.BootloaderName)); Console.WriteLine("Memory lower : " + Multiboot.V2.MemoryLower / 1024 + " MiB"); Console.WriteLine("Memory upper : " + Multiboot.V2.MemoryUpper / 1024 + " MiB"); - Console.WriteLine("Memory map entries : " + Multiboot.V2.Entries); - Console.WriteLine("Framebuffer available : " + Multiboot.V2.FramebufferAvailable); - if (Multiboot.V2.FramebufferAvailable) Console.WriteLine("Framebuffer resolution : " + Multiboot.V2.Framebuffer.Width + "x" + Multiboot.V2.Framebuffer.Height); - Console.WriteLine("ACPI version : " + (Multiboot.V2.ACPIv2 ? "2" : "1")); + Console.WriteLine("Memory map entries : " + Multiboot.V2.MemoryMapEntries); + Console.WriteLine("Framebuffer available : " + !Multiboot.V2.FrameBuffer.IsNull); + + if (!Multiboot.V2.FrameBuffer.IsNull) + { + Console.WriteLine("Framebuffer resolution : " + Multiboot.V2.FrameBufferWidth + "x" + Multiboot.V2.FrameBufferHeight); + } + + Console.WriteLine("RSDPv1 version : " + !Multiboot.V2.RSDPv1.IsNull); + Console.WriteLine("RSDPv2 version : " + !Multiboot.V2.RSDPv2.IsNull); } private readonly StringBuilder Builder = new(); diff --git a/Source/Mosa.Compiler.ARM32/ARM32Instruction.cs b/Source/Mosa.Compiler.ARM32/ARM32Instruction.cs index 92ab123317..63f1ebc4df 100644 --- a/Source/Mosa.Compiler.ARM32/ARM32Instruction.cs +++ b/Source/Mosa.Compiler.ARM32/ARM32Instruction.cs @@ -33,7 +33,7 @@ protected ARM32Instruction(byte resultCount, byte operandCount) /// public override string FamilyName => "ARM32"; - public static byte GetConditionCode(ConditionCode condition) + protected static byte GetConditionCode(ConditionCode condition) { return condition switch { @@ -62,4 +62,9 @@ public static byte GetConditionCode(ConditionCode condition) _ => throw new NotSupportedException() }; } + + protected static uint ToPower2(uint r) + { + return (uint)(1 << (int)r); + } } diff --git a/Source/Mosa.Compiler.ARM32/CompilerStages/MultibootStage.cs b/Source/Mosa.Compiler.ARM32/CompilerStages/MultibootStage.cs new file mode 100644 index 0000000000..966bad4689 --- /dev/null +++ b/Source/Mosa.Compiler.ARM32/CompilerStages/MultibootStage.cs @@ -0,0 +1,55 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Compiler.ARM32.CompilerStages; + +public sealed class MultibootStage : Framework.Platform.BaseMultibootStage +{ + protected override void CreateMultibootMethod() + { + var basicBlocks = new BasicBlocks(); + + var methodCompiler = new MethodCompiler(Compiler, MultibootMethod, basicBlocks, 0); + methodCompiler.MethodData.DoNotInline = true; + + var transform = new Transform(); + transform.SetCompiler(Compiler); + transform.SetMethodCompiler(methodCompiler); + + var initializeMethod = TypeSystem.GetMethod("Mosa.Runtime.StartUp", "Initialize"); + var entryPoint = Operand.CreateLabel(initializeMethod, Architecture.Is32BitPlatform); + + var lr = transform.PhysicalRegisters.Allocate64(CPURegister.LR); + var sp = transform.PhysicalRegisters.Allocate64(CPURegister.SP); + + var d10 = transform.PhysicalRegisters.Allocate64(CPURegister.d10); + var d11 = transform.PhysicalRegisters.Allocate64(CPURegister.d11); + + var stackLocation = Operand.CreateConstant32(MosaSettings.InitialStackLocation); + + var prologueBlock = basicBlocks.CreatePrologueBlock(); + + var context = new Context(prologueBlock); + + // Set stack location + context.AppendInstruction(ARM32.Movw, sp, stackLocation); + context.AppendInstruction(ARM32.Movt, sp, sp, stackLocation); + + // Create stack sentinel + context.AppendInstruction(ARM32.Movw, lr, Operand.Constant32_0); + context.AppendInstruction(ARM32.Stm, null, sp, Operand.Constant32_0, lr); + context.AppendInstruction(ARM32.Stm, null, sp, Operand.Constant32_0, lr); + + //// Push registers onto the new stack + context.AppendInstruction(ARM32.Mov, lr, sp); + context.AppendInstruction(ARM32.Stm, null, sp, Operand.Constant32_0, Operand.Constant32_FFFF); + context.AppendInstruction(ARM32.Stm, null, sp, Operand.Constant32_0, sp); + + // Call entry point + context.AppendInstruction(ARM32.Bl, null, entryPoint); + context.AppendInstruction(ARM32.Pop, null, Operand.Constant32_0); + + Compiler.CompileMethod(transform); + } +} diff --git a/Source/Mosa.Compiler.ARM32/Instructions/Ldm.cs b/Source/Mosa.Compiler.ARM32/Instructions/Ldm.cs index e03c848636..5cb39f7fa1 100644 --- a/Source/Mosa.Compiler.ARM32/Instructions/Ldm.cs +++ b/Source/Mosa.Compiler.ARM32/Instructions/Ldm.cs @@ -28,7 +28,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1BitImmediate(node.Operand2); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b1); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append16BitImmediate(node.Operand2); diff --git a/Source/Mosa.Compiler.ARM32/Instructions/Ldr16.cs b/Source/Mosa.Compiler.ARM32/Instructions/Ldr16.cs index 1d8a097f70..48384b4728 100644 --- a/Source/Mosa.Compiler.ARM32/Instructions/Ldr16.cs +++ b/Source/Mosa.Compiler.ARM32/Instructions/Ldr16.cs @@ -28,7 +28,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b1); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b1); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Result.Register.RegisterCode); @@ -48,7 +48,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b0); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b1); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Result.Register.RegisterCode); diff --git a/Source/Mosa.Compiler.ARM32/Instructions/Ldr32.cs b/Source/Mosa.Compiler.ARM32/Instructions/Ldr32.cs index c16443de72..4ead5b49c5 100644 --- a/Source/Mosa.Compiler.ARM32/Instructions/Ldr32.cs +++ b/Source/Mosa.Compiler.ARM32/Instructions/Ldr32.cs @@ -29,7 +29,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b0); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b1); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Result.Register.RegisterCode); @@ -45,7 +45,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b0); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b1); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Result.Register.RegisterCode); diff --git a/Source/Mosa.Compiler.ARM32/Instructions/Ldr8.cs b/Source/Mosa.Compiler.ARM32/Instructions/Ldr8.cs index aefe0266cd..0c5ccead2d 100644 --- a/Source/Mosa.Compiler.ARM32/Instructions/Ldr8.cs +++ b/Source/Mosa.Compiler.ARM32/Instructions/Ldr8.cs @@ -29,7 +29,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b1); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b1); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Result.Register.RegisterCode); @@ -45,7 +45,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b1); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b1); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Result.Register.RegisterCode); diff --git a/Source/Mosa.Compiler.ARM32/Instructions/LdrS16.cs b/Source/Mosa.Compiler.ARM32/Instructions/LdrS16.cs index 7b49a5ba2c..4a3cc28394 100644 --- a/Source/Mosa.Compiler.ARM32/Instructions/LdrS16.cs +++ b/Source/Mosa.Compiler.ARM32/Instructions/LdrS16.cs @@ -28,7 +28,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b1); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b1); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Result.Register.RegisterCode); @@ -48,7 +48,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b0); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b1); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Result.Register.RegisterCode); diff --git a/Source/Mosa.Compiler.ARM32/Instructions/LdrS8.cs b/Source/Mosa.Compiler.ARM32/Instructions/LdrS8.cs index d246781e51..dc2345e119 100644 --- a/Source/Mosa.Compiler.ARM32/Instructions/LdrS8.cs +++ b/Source/Mosa.Compiler.ARM32/Instructions/LdrS8.cs @@ -28,7 +28,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b1); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b1); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Result.Register.RegisterCode); @@ -48,7 +48,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b0); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b1); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Result.Register.RegisterCode); diff --git a/Source/Mosa.Compiler.ARM32/Instructions/Stm.cs b/Source/Mosa.Compiler.ARM32/Instructions/Stm.cs index 56d7dddcf9..6bd108d1d9 100644 --- a/Source/Mosa.Compiler.ARM32/Instructions/Stm.cs +++ b/Source/Mosa.Compiler.ARM32/Instructions/Stm.cs @@ -28,10 +28,24 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b1); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1BitImmediate(node.Operand2); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); + opcodeEncoder.Append16BitImmediate(node.Operand3); + return; + } + + if (node.Operand1.IsPhysicalRegister && node.Operand2.IsConstant && node.Operand3.IsPhysicalRegister) + { + opcodeEncoder.Append4Bits(GetConditionCode(node.ConditionCode)); + opcodeEncoder.Append3Bits(0b100); + opcodeEncoder.Append1Bit(0b1); + opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); + opcodeEncoder.Append1BitImmediate(node.Operand2); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); - opcodeEncoder.Append16BitImmediate(node.Operand2); + opcodeEncoder.Append16Bits(ToPower2(node.Operand3.Register.RegisterCode)); return; } diff --git a/Source/Mosa.Compiler.ARM32/Instructions/Str16.cs b/Source/Mosa.Compiler.ARM32/Instructions/Str16.cs index 8ed59aa5d5..dd619b781b 100644 --- a/Source/Mosa.Compiler.ARM32/Instructions/Str16.cs +++ b/Source/Mosa.Compiler.ARM32/Instructions/Str16.cs @@ -28,7 +28,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b1); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Operand3.Register.RegisterCode); @@ -49,7 +49,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b1); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Operand3.Register.RegisterCode); diff --git a/Source/Mosa.Compiler.ARM32/Instructions/Str32.cs b/Source/Mosa.Compiler.ARM32/Instructions/Str32.cs index 65aefb90f3..de0c28af84 100644 --- a/Source/Mosa.Compiler.ARM32/Instructions/Str32.cs +++ b/Source/Mosa.Compiler.ARM32/Instructions/Str32.cs @@ -29,7 +29,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b0); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Operand3.Register.RegisterCode); @@ -45,7 +45,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b0); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Operand3.Register.RegisterCode); diff --git a/Source/Mosa.Compiler.ARM32/Instructions/Str8.cs b/Source/Mosa.Compiler.ARM32/Instructions/Str8.cs index 6bcb363ed8..962858c207 100644 --- a/Source/Mosa.Compiler.ARM32/Instructions/Str8.cs +++ b/Source/Mosa.Compiler.ARM32/Instructions/Str8.cs @@ -29,7 +29,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b1); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Operand3.Register.RegisterCode); @@ -45,7 +45,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b1); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Operand3.Register.RegisterCode); diff --git a/Source/Mosa.Compiler.ARM32/Instructions/StrS16.cs b/Source/Mosa.Compiler.ARM32/Instructions/StrS16.cs index f04b60c452..9e98987ca6 100644 --- a/Source/Mosa.Compiler.ARM32/Instructions/StrS16.cs +++ b/Source/Mosa.Compiler.ARM32/Instructions/StrS16.cs @@ -28,7 +28,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b1); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Operand3.Register.RegisterCode); @@ -48,7 +48,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b0); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Operand3.Register.RegisterCode); diff --git a/Source/Mosa.Compiler.ARM32/Instructions/StrS8.cs b/Source/Mosa.Compiler.ARM32/Instructions/StrS8.cs index ef0ecd472a..e5bc97c984 100644 --- a/Source/Mosa.Compiler.ARM32/Instructions/StrS8.cs +++ b/Source/Mosa.Compiler.ARM32/Instructions/StrS8.cs @@ -28,7 +28,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b1); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Operand3.Register.RegisterCode); @@ -48,7 +48,7 @@ public override void Emit(Node node, OpcodeEncoder opcodeEncoder) opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.IsUpDirection ? 1 : 0); opcodeEncoder.Append1Bit(0b0); - opcodeEncoder.Append1Bit(0b0); + opcodeEncoder.Append1Bit(node.IsWriteback ? 1 : 0); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append4Bits(node.Operand1.Register.RegisterCode); opcodeEncoder.Append4Bits(node.Operand3.Register.RegisterCode); diff --git a/Source/Mosa.Compiler.Framework/BaseMethodCompilerStage.cs b/Source/Mosa.Compiler.Framework/BaseMethodCompilerStage.cs index 3ea843519b..661913dd8b 100644 --- a/Source/Mosa.Compiler.Framework/BaseMethodCompilerStage.cs +++ b/Source/Mosa.Compiler.Framework/BaseMethodCompilerStage.cs @@ -511,7 +511,7 @@ public static void ReplaceOperand(Operand target, Operand replacement) protected MosaMethod GetMethod(string fullName, string methodName) { - var type = TypeSystem.GetTypeByName(fullName); + var type = TypeSystem.GetType(fullName); var method = type?.FindMethodByName(methodName); return method; diff --git a/Source/Mosa.Compiler.Framework/Compiler.cs b/Source/Mosa.Compiler.Framework/Compiler.cs index 531132fe0e..dfe4bb7a3c 100644 --- a/Source/Mosa.Compiler.Framework/Compiler.cs +++ b/Source/Mosa.Compiler.Framework/Compiler.cs @@ -609,12 +609,12 @@ public void PostEvent(CompilerEvent compilerEvent, string message = null, int th private MosaType GetPlatformInternalRuntimeType() { - return TypeSystem.GetTypeByName($"Mosa.Runtime.{Architecture.PlatformName}.Internal"); + return TypeSystem.GetType($"Mosa.Runtime.{Architecture.PlatformName}.Internal"); } private MosaType GeInternalRuntimeType() { - return TypeSystem.GetTypeByName("Mosa.Runtime.Internal"); + return TypeSystem.GetType("Mosa.Runtime.Internal"); } public MethodData GetMethodData(MosaMethod method) diff --git a/Source/Mosa.Compiler.Framework/CompilerStages/DebugFileStage.cs b/Source/Mosa.Compiler.Framework/CompilerStages/DebugFileStage.cs index 7e719c897a..ec1fe4f01a 100644 --- a/Source/Mosa.Compiler.Framework/CompilerStages/DebugFileStage.cs +++ b/Source/Mosa.Compiler.Framework/CompilerStages/DebugFileStage.cs @@ -1,5 +1,7 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. +using System.Reflection.Metadata; + namespace Mosa.Compiler.Framework.CompilerStages; /// @@ -170,6 +172,23 @@ private void EmitParameters() var methodData = Compiler.GetMethodData(method); + if (method.HasThis) + { + writer.WriteLine( + "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}", + method.ID, + index, + methodData == null || methodData.ParameterOffsets == null ? 0 : methodData.ParameterOffsets[index], + "this", + "this", + 0, + 0, + methodData == null || methodData.ParameterSizes == null ? 0 : methodData.ParameterSizes[index] + ); + + index++; + } + foreach (var parameter in method.Signature.Parameters) { writer.WriteLine( diff --git a/Source/Mosa.Compiler.Framework/CompilerStages/StartUpStage.cs b/Source/Mosa.Compiler.Framework/CompilerStages/StartUpStage.cs index 38ee3adc81..69a21e2c36 100644 --- a/Source/Mosa.Compiler.Framework/CompilerStages/StartUpStage.cs +++ b/Source/Mosa.Compiler.Framework/CompilerStages/StartUpStage.cs @@ -12,7 +12,7 @@ public sealed class StartUpStage : BaseCompilerStage { protected override void Setup() { - var startUpType = TypeSystem.GetTypeByName("Mosa.Runtime.StartUp"); + var startUpType = TypeSystem.GetType("Mosa.Runtime.StartUp"); var startUpMethod = startUpType.FindMethodByName("StartApplication"); Compiler.PlugSystem.CreatePlug(startUpMethod, TypeSystem.EntryPoint); diff --git a/Source/Mosa.Compiler.Framework/CompilerStages/TypeInitializerStage.cs b/Source/Mosa.Compiler.Framework/CompilerStages/TypeInitializerStage.cs index d6ef1a792c..4ade5cef5a 100644 --- a/Source/Mosa.Compiler.Framework/CompilerStages/TypeInitializerStage.cs +++ b/Source/Mosa.Compiler.Framework/CompilerStages/TypeInitializerStage.cs @@ -67,7 +67,7 @@ protected override void Setup() { typeInitializerMethod = Compiler.CreateLinkerMethod(TypeInitializerName); - var startUpType = TypeSystem.GetTypeByName("Mosa.Runtime.StartUp"); + var startUpType = TypeSystem.GetType("Mosa.Runtime.StartUp"); var initializeAssemblyMethod = startUpType.FindMethodByName("InitializeAssembly"); Compiler.PlugSystem.CreatePlug(initializeAssemblyMethod, typeInitializerMethod); diff --git a/Source/Mosa.Compiler.Framework/InstructionOption.cs b/Source/Mosa.Compiler.Framework/InstructionOption.cs index 56ec7bb8b2..bda737db32 100644 --- a/Source/Mosa.Compiler.Framework/InstructionOption.cs +++ b/Source/Mosa.Compiler.Framework/InstructionOption.cs @@ -3,7 +3,7 @@ namespace Mosa.Compiler.Framework; /// -/// Instruction Options +/// Instruction Option /// [Flags] public enum InstructionOption @@ -12,4 +12,6 @@ public enum InstructionOption SetFlags = 1, UpDirection = 2, Marked = 4, + PrefixAdd = 8, + Writeback = 16, }; diff --git a/Source/Mosa.Compiler.Framework/MethodScanner.cs b/Source/Mosa.Compiler.Framework/MethodScanner.cs index 54578a7a5a..66d350c8b2 100644 --- a/Source/Mosa.Compiler.Framework/MethodScanner.cs +++ b/Source/Mosa.Compiler.Framework/MethodScanner.cs @@ -377,19 +377,19 @@ public void Initialize() ScheduleMethod(entryPoint); } - var objectType = TypeSystem.GetTypeByName("System.Object"); + var objectType = TypeSystem.GetType("System.Object"); allocatedTypes.Add(objectType); - var stringType = TypeSystem.GetTypeByName("System.String"); + var stringType = TypeSystem.GetType("System.String"); allocatedTypes.Add(stringType); - var typeType = TypeSystem.GetTypeByName("System.Type"); + var typeType = TypeSystem.GetType("System.Type"); allocatedTypes.Add(typeType); - var exceptionType = TypeSystem.GetTypeByName("System.Exception"); + var exceptionType = TypeSystem.GetType("System.Exception"); allocatedTypes.Add(exceptionType); - var delegateType = TypeSystem.GetTypeByName("System.Delegate"); + var delegateType = TypeSystem.GetType("System.Delegate"); allocatedTypes.Add(delegateType); //var arrayType = TypeSystem.GetTypeByName("System", "Array"); diff --git a/Source/Mosa.Compiler.Framework/Node.cs b/Source/Mosa.Compiler.Framework/Node.cs index e42e6a129f..9277b7f917 100644 --- a/Source/Mosa.Compiler.Framework/Node.cs +++ b/Source/Mosa.Compiler.Framework/Node.cs @@ -332,6 +332,38 @@ public bool IsUpDirection } } + /// + /// Gets or sets a value indicating whether this intruction has a prefix add. + /// + public bool IsPrefixAdd + { + get + { + return Options.HasFlag(InstructionOption.PrefixAdd + ); + } + set + { + Options |= InstructionOption.PrefixAdd; + } + } + + /// + /// Gets or sets a value indicating whether this intruction has causes a writeback. + /// + public bool IsWriteback + { + get + { + return Options.HasFlag(InstructionOption.Writeback + ); + } + set + { + Options |= InstructionOption.Writeback; + } + } + /// /// Gets or sets a value indicating whether this intruction has an up direction. /// diff --git a/Source/Mosa.Compiler.Framework/OpcodeEncoder.cs b/Source/Mosa.Compiler.Framework/OpcodeEncoder.cs index 728286d9f1..7ee969c176 100644 --- a/Source/Mosa.Compiler.Framework/OpcodeEncoder.cs +++ b/Source/Mosa.Compiler.Framework/OpcodeEncoder.cs @@ -187,6 +187,11 @@ public void Append16Bits(ushort value) AppendBits(value, 16); } + public void Append16Bits(uint value) + { + AppendBits(value, 16); + } + public void AppendShort(ushort value) { AppendBits(value, 16); diff --git a/Source/Mosa.Compiler.Framework/Platform/BaseMultibootStage.cs b/Source/Mosa.Compiler.Framework/Platform/BaseMultibootStage.cs index b0808b846b..182ef6239b 100644 --- a/Source/Mosa.Compiler.Framework/Platform/BaseMultibootStage.cs +++ b/Source/Mosa.Compiler.Framework/Platform/BaseMultibootStage.cs @@ -21,18 +21,9 @@ namespace Mosa.Compiler.Framework.Platform; /// public abstract class BaseMultibootStage : BaseCompilerStage { - private const string MultibootHeaderSymbolName = "<$>mosa-multiboot-header"; - - public const string MultibootEAX = "<$>mosa-multiboot-eax"; - public const string MultibootEBX = "<$>mosa-multiboot-ebx"; - public const string MultibootInitialStack = "<$>mosa-multiboot-initial-stack"; - #region Constants - /// - /// This is the size of the initial kernel stack. (8KiB) - /// - protected const uint StackSize = 0x2000; + private const string MultibootHeaderSymbolName = "<$>mosa-multiboot-header"; private struct MultibootV2Constants { @@ -84,55 +75,45 @@ private struct MultibootV2Constants /// /// The multiboot method /// - protected MosaMethod multibootMethod; + protected MosaMethod MultibootMethod; /// /// The multiboot header /// - protected LinkerSymbol multibootHeader; - - public bool IsV2 { get; set; } - - public bool HasVideo { get; set; } - - public int Width { get; set; } - - public int Height { get; set; } + protected LinkerSymbol MultibootHeader; #endregion Data Members - protected override void Initialization() - { - IsV2 = MosaSettings.MultibootVersion == "v2"; - HasVideo = MosaSettings.MultibootVideo; - Width = MosaSettings.MultibootVideoWidth; - Height = MosaSettings.MultibootVideoHeight; - } - protected override void Setup() { - multibootHeader = Linker.DefineSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30); - - Linker.DefineSymbol(MultibootEAX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize); - Linker.DefineSymbol(MultibootEBX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize); - Linker.DefineSymbol(MultibootInitialStack, SectionKind.BSS, Architecture.NativeAlignment, StackSize); + MultibootHeader = Linker.DefineSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30); + MultibootMethod = Compiler.CreateLinkerMethod("MultibootInit"); - multibootMethod = Compiler.CreateLinkerMethod("MultibootInit"); - var methodData = Compiler.GetMethodData(multibootMethod); + var methodData = Compiler.GetMethodData(MultibootMethod); methodData.DoNotInline = true; methodData.StackFrameRequired = false; - Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName); + Linker.EntryPoint = Linker.GetSymbol(MultibootMethod.FullName); - MethodScanner.MethodInvoked(multibootMethod, multibootMethod); + MethodScanner.MethodInvoked(MultibootMethod, MultibootMethod); - var startUpType = TypeSystem.GetTypeByName("Mosa.Runtime.StartUp"); - var initializeMethod = startUpType?.FindMethodByName("Initialize"); + var initializeMethod = TypeSystem.GetMethod("Mosa.Runtime.StartUp", "Initialize"); Compiler.GetMethodData(initializeMethod).DoNotInline = true; - MethodScanner.MethodInvoked(initializeMethod, multibootMethod); + MethodScanner.MethodInvoked(initializeMethod, MultibootMethod); + } + + protected override void Finalization() + { + CreateMultibootMethod(); + + WriteMultibootHeader(Linker.EntryPoint); + } + + protected virtual void CreateMultibootMethod() + { } #region Internals @@ -144,44 +125,63 @@ protected override void Setup() protected void WriteMultibootHeader(LinkerSymbol entryPoint) { // According to the multiboot specification this header must be within the first 8K of the kernel binary. - Linker.SetFirst(multibootHeader); + Linker.SetFirst(MultibootHeader); - var writer = new BinaryWriter(multibootHeader.Stream, Encoding.ASCII); + var writer = new BinaryWriter(MultibootHeader.Stream, Encoding.ASCII); - if (!IsV2) throw new CompilerException("Multiboot.Version != v2"); + if (MosaSettings.MultibootVersion != "v2") + { + throw new CompilerException("Multiboot.Version != v2"); + } // Header size + entry tag size + (framebuffer size if chosen) + end tag size var headerLength = MultibootV2Constants.HeaderSize + MultibootV2Constants.EntryTagSize + sizeof(uint); - if (HasVideo) headerLength += MultibootV2Constants.FramebufferTagSize; + + if (MosaSettings.MultibootVideo) + { + headerLength += MultibootV2Constants.FramebufferTagSize; + } // Header - while (writer.BaseStream.Position % 8 != 0) writer.Write((byte)0); + while (writer.BaseStream.Position % 8 != 0) + { + writer.Write((byte)0); + } + writer.Write(MultibootV2Constants.HeaderMbMagic); writer.Write(MultibootV2Constants.HeaderMbArchitecture); writer.Write(headerLength); writer.Write((uint)(0x100000000 - (MultibootV2Constants.HeaderMbMagic + MultibootV2Constants.HeaderMbArchitecture + headerLength))); // Framebuffer tag - if (HasVideo) + if (MosaSettings.MultibootVideo) { while (writer.BaseStream.Position % 8 != 0) writer.Write((byte)0); writer.Write(MultibootV2Constants.FramebufferTag); writer.Write(MultibootV2Constants.RequiredFlag); writer.Write(MultibootV2Constants.FramebufferTagSize); - writer.Write((uint)Width); - writer.Write((uint)Height); + writer.Write((uint)MosaSettings.MultibootVideoWidth); + writer.Write((uint)MosaSettings.MultibootVideoHeight); writer.Write(32U); } // Entry tag - while (writer.BaseStream.Position % 8 != 0) writer.Write((byte)0); + while (writer.BaseStream.Position % 8 != 0) + { + writer.Write((byte)0); + } + writer.Write(MultibootV2Constants.EntryTag); writer.Write(MultibootV2Constants.RequiredFlag); writer.Write(MultibootV2Constants.EntryTagSize); - Linker.Link(LinkType.AbsoluteAddress, PatchType.I32, multibootHeader, writer.BaseStream.Position, entryPoint, 0); + Linker.Link(LinkType.AbsoluteAddress, PatchType.I32, MultibootHeader, writer.BaseStream.Position, entryPoint, 0); // End tag - while (writer.BaseStream.Position % 8 != 0) writer.Write((byte)0); + while (writer.BaseStream.Position % 8 != 0) + { + writer.Write((byte)0); + } + writer.Write((ushort)0); writer.Write((ushort)0); } diff --git a/Source/Mosa.Compiler.Framework/PlatformRegistry.cs b/Source/Mosa.Compiler.Framework/PlatformRegistry.cs index 1c994babeb..ba3a683712 100644 --- a/Source/Mosa.Compiler.Framework/PlatformRegistry.cs +++ b/Source/Mosa.Compiler.Framework/PlatformRegistry.cs @@ -17,7 +17,7 @@ public static void Register() if (!type.IsAbstract && typeof(BaseArchitecture).IsAssignableFrom(type)) { var platform = (BaseArchitecture)Activator.CreateInstance(type); - Registry.Add(platform.PlatformName, platform); + Add(platform); } } } @@ -25,12 +25,12 @@ public static void Register() public static void Add(BaseArchitecture platform) { - Registry.Add(platform.PlatformName, platform); + Registry.Add(platform.PlatformName.ToLowerInvariant(), platform); } public static BaseArchitecture GetPlatform(string platformName) { - Registry.TryGetValue(platformName, out BaseArchitecture platform); + Registry.TryGetValue(platformName.ToLowerInvariant(), out BaseArchitecture platform); return platform; } diff --git a/Source/Mosa.Compiler.Framework/Transform.cs b/Source/Mosa.Compiler.Framework/Transform.cs index ccd02ab003..2daf3726ce 100644 --- a/Source/Mosa.Compiler.Framework/Transform.cs +++ b/Source/Mosa.Compiler.Framework/Transform.cs @@ -520,7 +520,7 @@ public void SplitOperand(Operand operand, out Operand operandLow, out Operand op public MosaMethod GetMethod(string fullName, string methodName) { - var type = TypeSystem.GetTypeByName(fullName); + var type = TypeSystem.GetType(fullName); if (type == null) return null; diff --git a/Source/Mosa.Compiler.MosaTypeSystem.CLR/Metadata/ClrMetadataResolver.cs b/Source/Mosa.Compiler.MosaTypeSystem.CLR/Metadata/ClrMetadataResolver.cs index 90e5183d46..fb57a8d569 100644 --- a/Source/Mosa.Compiler.MosaTypeSystem.CLR/Metadata/ClrMetadataResolver.cs +++ b/Source/Mosa.Compiler.MosaTypeSystem.CLR/Metadata/ClrMetadataResolver.cs @@ -628,7 +628,7 @@ private void ResolveSZArray(MosaType? arrayType) throw new CompilerException("Type must be a SZ Array."); var typeSystem = arrayType.TypeSystem; - var szHelper = typeSystem.GetTypeByName(typeSystem.CorLib, "System.Array+SZArrayHelper"); + var szHelper = typeSystem.GetType(typeSystem.CorLib, "System.Array+SZArrayHelper"); if (szHelper == null) throw new InvalidOperationCompilerException("Type is null or does not exist"); @@ -656,9 +656,9 @@ private void ResolveSZArray(MosaType? arrayType) // Add interfaces to the type and copy properties from interfaces into type so we can expose them var list = new LinkedList(); - list.AddLast(typeSystem.GetTypeByName(typeSystem.CorLib, "System.Collections.Generic.IList`1<" + arrayType.ElementType?.FullName + ">")); - list.AddLast(typeSystem.GetTypeByName(typeSystem.CorLib, "System.Collections.Generic.ICollection`1<" + arrayType.ElementType?.FullName + ">")); - list.AddLast(typeSystem.GetTypeByName(typeSystem.CorLib, "System.Collections.Generic.IEnumerable`1<" + arrayType.ElementType?.FullName + ">")); + list.AddLast(typeSystem.GetType(typeSystem.CorLib, "System.Collections.Generic.IList`1<" + arrayType.ElementType?.FullName + ">")); + list.AddLast(typeSystem.GetType(typeSystem.CorLib, "System.Collections.Generic.ICollection`1<" + arrayType.ElementType?.FullName + ">")); + list.AddLast(typeSystem.GetType(typeSystem.CorLib, "System.Collections.Generic.IEnumerable`1<" + arrayType.ElementType?.FullName + ">")); foreach (var iface in list) { if (iface == null) diff --git a/Source/Mosa.Compiler.MosaTypeSystem/TypeSystem.cs b/Source/Mosa.Compiler.MosaTypeSystem/TypeSystem.cs index 7520b7fe8a..11971665aa 100644 --- a/Source/Mosa.Compiler.MosaTypeSystem/TypeSystem.cs +++ b/Source/Mosa.Compiler.MosaTypeSystem/TypeSystem.cs @@ -11,25 +11,30 @@ namespace Mosa.Compiler.MosaTypeSystem; public class TypeSystem { [NotNull] - public BuiltInTypes? BuiltIn { get; private set; } + public BuiltInTypes BuiltIn { get; private set; } - private MosaModule? corLib; + private MosaModule corLib; [NotNull] - public MosaModule? CorLib + public MosaModule CorLib { get { if (corLib == null) + { throw new AssemblyLoadException(); + } return corLib; } set { corLib = value; + if (corLib == null) + { throw new AssemblyLoadException(); + } BuiltIn = new BuiltInTypes(TypeResolver, corLib); } @@ -42,8 +47,11 @@ public IEnumerable AllTypes foreach (var module in Modules) { var types = module?.Types.Values; + if (types == null) + { throw new InvalidOperationCompilerException("Types list is null"); + } foreach (var type in types) { @@ -56,15 +64,15 @@ public IEnumerable AllTypes public IList Modules { get; } [NotNull] - public MosaModule? LinkerModule { get; private set; } + public MosaModule LinkerModule { get; private set; } [NotNull] - public MosaType? DefaultLinkerType { get; private set; } + public MosaType DefaultLinkerType { get; private set; } - public MosaMethod? EntryPoint { get; internal set; } + public MosaMethod EntryPoint { get; internal set; } [NotNull] - public ITypeSystemController? Controller { get; private set; } + public ITypeSystemController Controller { get; private set; } public ITypeResolver TypeResolver { get; } @@ -117,20 +125,30 @@ private void Load() } /// - /// Get a type by fullName + /// Get a type by name /// - /// fullName like namespace.typeName - public MosaType? GetTypeByName(string fullName) + /// fullName like namespace.typeName + public MosaType GetType(string typeName) + { + return string.IsNullOrEmpty(typeName) ? null : TypeResolver.GetTypeByName(Modules, typeName); + } + + public MosaMethod GetMethod(string typeName, string methodName) { - return string.IsNullOrEmpty(fullName) ? null : TypeResolver.GetTypeByName(Modules, fullName); + var type = GetType(typeName); + + if (type == null) + return null; + + return type.FindMethodByName(methodName); } - public MosaType? GetTypeByName(MosaModule module, string fullName) + public MosaType GetType(MosaModule module, string fullName) { return string.IsNullOrEmpty(fullName) ? null : TypeResolver.GetTypeByName(module, fullName); } - public MosaModule? GetModuleByAssembly(string name) + public MosaModule GetModuleByAssembly(string name) { foreach (var module in Modules) { @@ -141,7 +159,7 @@ private void Load() return null; } - public string? LookupUserString(MosaModule module, uint token) + public string LookupUserString(MosaModule module, uint token) { return metadata.LookupUserString(module, token); } diff --git a/Source/Mosa.Compiler.x64/CompilerStages/MultibootStage.cs b/Source/Mosa.Compiler.x64/CompilerStages/MultibootStage.cs index d9b7087bbf..c94e1065cb 100644 --- a/Source/Mosa.Compiler.x64/CompilerStages/MultibootStage.cs +++ b/Source/Mosa.Compiler.x64/CompilerStages/MultibootStage.cs @@ -4,61 +4,47 @@ namespace Mosa.Compiler.x64.CompilerStages; -public sealed class MultibootStage : Mosa.Compiler.Framework.Platform.BaseMultibootStage +public sealed class MultibootStage : Framework.Platform.BaseMultibootStage { - protected override void Finalization() - { - CreateMultibootMethod(); - - WriteMultibootHeader(Linker.EntryPoint); - } - - private void CreateMultibootMethod() + protected override void CreateMultibootMethod() { var basicBlocks = new BasicBlocks(); - var methodCompiler = new MethodCompiler(Compiler, multibootMethod, basicBlocks, 0); + var methodCompiler = new MethodCompiler(Compiler, MultibootMethod, basicBlocks, 0); methodCompiler.MethodData.DoNotInline = true; var transform = new Transform(); transform.SetCompiler(Compiler); transform.SetMethodCompiler(methodCompiler); - var startUpType = TypeSystem.GetTypeByName("Mosa.Runtime.StartUp"); - var initializeMethod = startUpType.FindMethodByName("Initialize"); - + var initializeMethod = TypeSystem.GetMethod("Mosa.Runtime.StartUp", "Initialize"); var entryPoint = Operand.CreateLabel(initializeMethod, Architecture.Is32BitPlatform); - var rax = transform.PhysicalRegisters.Allocate64(CPURegister.RAX); - var rbx = transform.PhysicalRegisters.Allocate64(CPURegister.RBX); var rbp = transform.PhysicalRegisters.Allocate64(CPURegister.RBP); var rsp = transform.PhysicalRegisters.Allocate64(CPURegister.RSP); - var multibootEAX = Operand.CreateLabel(MultibootEAX, Architecture.Is32BitPlatform); - var multibootEBX = Operand.CreateLabel(MultibootEBX, Architecture.Is32BitPlatform); - var stackBottom = Operand.CreateLabel(MultibootInitialStack, Architecture.Is32BitPlatform); - - var stackTopOffset = CreateConstant(StackSize - 16); + var stackLocation = Operand.CreateConstant64(MosaSettings.InitialStackLocation); var prologueBlock = basicBlocks.CreatePrologueBlock(); var context = new Context(prologueBlock); - // Setup the stack and place the sentinel on the stack to indicate the start of the stack - context.AppendInstruction(X64.Mov64, rsp, stackBottom); - context.AppendInstruction(X64.Add64, rsp, rsp, stackTopOffset); - context.AppendInstruction(X64.Mov64, rbp, stackBottom); - context.AppendInstruction(X64.Add64, rbp, rbp, stackTopOffset); - context.AppendInstruction(X64.MovStore64, null, rsp, Operand.Constant64_0, Operand.Constant64_0); - context.AppendInstruction(X64.MovStore64, null, rsp, Operand.Constant64_16, Operand.Constant64_0); + // Set stack location + context.AppendInstruction(X64.Mov32, rsp, stackLocation); + + // Create stack sentinel + context.AppendInstruction(X64.Push64, null, Operand.Constant32_0); + context.AppendInstruction(X64.Push64, null, Operand.Constant32_0); - // Place the multiboot address into a static field - context.AppendInstruction(X64.MovStore64, null, multibootEAX, Operand.Constant64_0, rax); - context.AppendInstruction(X64.MovStore64, null, multibootEBX, Operand.Constant64_0, rbx); + // Push registers onto the new stack + context.AppendInstruction(X64.Mov32, rbp, rsp); + context.AppendInstruction(X64.Pushad); + context.AppendInstruction(X64.Push64, null, rbp); + // Call entry point context.AppendInstruction(X64.Call, null, entryPoint); context.AppendInstruction(X64.Ret); - Compiler.CompileMethod(multibootMethod, basicBlocks); + Compiler.CompileMethod(transform); } } diff --git a/Source/Mosa.Compiler.x64/Intrinsic/GetMultibootRAX.cs b/Source/Mosa.Compiler.x64/Intrinsic/GetMultibootRAX.cs deleted file mode 100644 index 2209a80480..0000000000 --- a/Source/Mosa.Compiler.x64/Intrinsic/GetMultibootRAX.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) MOSA Project. Licensed under the New BSD License. - -using Mosa.Compiler.Framework; -using Mosa.Compiler.Framework.Platform; - -namespace Mosa.Compiler.x64.Intrinsic; - -/// -/// IntrinsicMethods -/// -internal static partial class IntrinsicMethods -{ - [IntrinsicMethod("Mosa.Compiler.x64.Intrinsic::GetMultibootRAX")] - private static void GetMultibootRAX(Context context, Transform transform) - { - var MultibootEAX = Operand.CreateLabel(BaseMultibootStage.MultibootEAX, transform.Is32BitPlatform); - - context.SetInstruction(IR.Load64, context.Result, MultibootEAX, Operand.Constant32_0); - } -} diff --git a/Source/Mosa.Compiler.x64/Intrinsic/GetMultibootRBX.cs b/Source/Mosa.Compiler.x64/Intrinsic/GetMultibootRBX.cs deleted file mode 100644 index ca2e94a807..0000000000 --- a/Source/Mosa.Compiler.x64/Intrinsic/GetMultibootRBX.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) MOSA Project. Licensed under the New BSD License. - -using Mosa.Compiler.Framework; -using Mosa.Compiler.Framework.Platform; - -namespace Mosa.Compiler.x64.Intrinsic; - -/// -/// IntrinsicMethods -/// -internal static partial class IntrinsicMethods -{ - [IntrinsicMethod("Mosa.Compiler.x64.Intrinsic::GetMultibootRBX")] - private static void GetMultibootRBX(Context context, Transform transform) - { - var MultibootEBX = Operand.CreateLabel(BaseMultibootStage.MultibootEBX, transform.Is32BitPlatform); - - context.SetInstruction(IR.Load64, context.Result, MultibootEBX, Operand.Constant32_0); - } -} diff --git a/Source/Mosa.Compiler.x64/Intrinsic/IRQs.cs b/Source/Mosa.Compiler.x64/Intrinsic/IRQs.cs index f2a55a60a7..af466c1e23 100644 --- a/Source/Mosa.Compiler.x64/Intrinsic/IRQs.cs +++ b/Source/Mosa.Compiler.x64/Intrinsic/IRQs.cs @@ -28,7 +28,7 @@ private static void InsertIRQ(int irq, Context context, Transform transform) var typeFullname = ar[0]; var methodName = ar[1]; - var type = transform.TypeSystem.GetTypeByName(typeFullname); + var type = transform.TypeSystem.GetType(typeFullname); if (type == null) return; diff --git a/Source/Mosa.Compiler.x86/CompilerStages/MultibootStage.cs b/Source/Mosa.Compiler.x86/CompilerStages/MultibootStage.cs index acf35d7cc6..9fd4d31ac3 100644 --- a/Source/Mosa.Compiler.x86/CompilerStages/MultibootStage.cs +++ b/Source/Mosa.Compiler.x86/CompilerStages/MultibootStage.cs @@ -4,58 +4,44 @@ namespace Mosa.Compiler.x86.CompilerStages; -public sealed class MultibootStage : Mosa.Compiler.Framework.Platform.BaseMultibootStage +public sealed class MultibootStage : Framework.Platform.BaseMultibootStage { - protected override void Finalization() - { - CreateMultibootMethod(); - - WriteMultibootHeader(Linker.EntryPoint); - } - - private void CreateMultibootMethod() + protected override void CreateMultibootMethod() { var basicBlocks = new BasicBlocks(); - var methodCompiler = new MethodCompiler(Compiler, multibootMethod, basicBlocks, 0); + var methodCompiler = new MethodCompiler(Compiler, MultibootMethod, basicBlocks, 0); methodCompiler.MethodData.DoNotInline = true; var transform = new Transform(); transform.SetCompiler(Compiler); transform.SetMethodCompiler(methodCompiler); - var startUpType = TypeSystem.GetTypeByName("Mosa.Runtime.StartUp"); - var initializeMethod = startUpType.FindMethodByName("Initialize"); - + var initializeMethod = TypeSystem.GetMethod("Mosa.Runtime.StartUp", "Initialize"); var entryPoint = Operand.CreateLabel(initializeMethod, Architecture.Is32BitPlatform); - var eax = transform.PhysicalRegisters.Allocate32(CPURegister.EAX); - var ebx = transform.PhysicalRegisters.Allocate32(CPURegister.EBX); var ebp = transform.PhysicalRegisters.Allocate32(CPURegister.EBP); var esp = transform.PhysicalRegisters.Allocate32(CPURegister.ESP); - var multibootEAX = Operand.CreateLabel(MultibootEAX, Architecture.Is32BitPlatform); - var multibootEBX = Operand.CreateLabel(MultibootEBX, Architecture.Is32BitPlatform); - var stackBottom = Operand.CreateLabel(MultibootInitialStack, Architecture.Is32BitPlatform); - - var stackTopOffset = CreateConstant(StackSize - 8); + var stackLocation = Operand.CreateConstant32(MosaSettings.InitialStackLocation); var prologueBlock = basicBlocks.CreatePrologueBlock(); var context = new Context(prologueBlock); - // Setup the stack and place the sentinel on the stack to indicate the start of the stack - context.AppendInstruction(X86.Mov32, esp, stackBottom); - context.AppendInstruction(X86.Add32, esp, esp, stackTopOffset); - context.AppendInstruction(X86.Mov32, ebp, stackBottom); - context.AppendInstruction(X86.Add32, ebp, ebp, stackTopOffset); - context.AppendInstruction(X86.MovStore32, null, esp, Operand.Constant32_0, Operand.Constant32_0); - context.AppendInstruction(X86.MovStore32, null, esp, Operand.Constant32_8, Operand.Constant32_0); + // Set stack location + context.AppendInstruction(X86.Mov32, esp, stackLocation); + + // Create stack sentinel + context.AppendInstruction(X86.Push32, null, Operand.Constant32_0); + context.AppendInstruction(X86.Push32, null, Operand.Constant32_0); - // Place the multiboot address into a static field - context.AppendInstruction(X86.MovStore32, null, multibootEAX, Operand.Constant32_0, eax); - context.AppendInstruction(X86.MovStore32, null, multibootEBX, Operand.Constant32_0, ebx); + // Push registers onto the new stack + context.AppendInstruction(X86.Mov32, ebp, esp); + context.AppendInstruction(X86.Pushad); + context.AppendInstruction(X86.Push32, null, ebp); + // Call entry point context.AppendInstruction(X86.Call, null, entryPoint); context.AppendInstruction(X86.Ret); diff --git a/Source/Mosa.Compiler.x86/Intrinsic/GetMultibootEAX.cs b/Source/Mosa.Compiler.x86/Intrinsic/GetMultibootEAX.cs deleted file mode 100644 index 55e3379a69..0000000000 --- a/Source/Mosa.Compiler.x86/Intrinsic/GetMultibootEAX.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) MOSA Project. Licensed under the New BSD License. - -using Mosa.Compiler.Framework; -using Mosa.Compiler.Framework.Platform; - -namespace Mosa.Compiler.x86.Intrinsic; - -/// -/// IntrinsicMethods -/// -internal static partial class IntrinsicMethods -{ - [IntrinsicMethod("Mosa.Compiler.x86.Intrinsic::GetMultibootEAX")] - private static void GetMultibootEAX(Context context, Transform transform) - { - var MultibootEAX = Operand.CreateLabel(BaseMultibootStage.MultibootEAX, transform.Is32BitPlatform); - - context.SetInstruction(IR.Load32, context.Result, MultibootEAX, Operand.Constant32_0); - } -} diff --git a/Source/Mosa.Compiler.x86/Intrinsic/GetMultibootEBX.cs b/Source/Mosa.Compiler.x86/Intrinsic/GetMultibootEBX.cs deleted file mode 100644 index 4e8638eb05..0000000000 --- a/Source/Mosa.Compiler.x86/Intrinsic/GetMultibootEBX.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) MOSA Project. Licensed under the New BSD License. - -using Mosa.Compiler.Framework; -using Mosa.Compiler.Framework.Platform; - -namespace Mosa.Compiler.x86.Intrinsic; - -/// -/// IntrinsicMethods -/// -internal static partial class IntrinsicMethods -{ - [IntrinsicMethod("Mosa.Compiler.x86.Intrinsic::GetMultibootEBX")] - private static void GetMultibootEBX(Context context, Transform transform) - { - var MultibootEBX = Operand.CreateLabel(BaseMultibootStage.MultibootEBX, transform.Is32BitPlatform); - - context.SetInstruction(IR.Load32, context.Result, MultibootEBX, Operand.Constant32_0); - } -} diff --git a/Source/Mosa.Compiler.x86/Intrinsic/IRQs.cs b/Source/Mosa.Compiler.x86/Intrinsic/IRQs.cs index 07d9ccc536..4d36666d9e 100644 --- a/Source/Mosa.Compiler.x86/Intrinsic/IRQs.cs +++ b/Source/Mosa.Compiler.x86/Intrinsic/IRQs.cs @@ -31,7 +31,7 @@ private static void InsertIRQ(int irq, Context context, Transform transform) var typeFullname = ar[0]; var methodName = ar[1]; - var type = transform.TypeSystem.GetTypeByName(typeFullname); + var type = transform.TypeSystem.GetType(typeFullname); if (type == null) return; diff --git a/Source/Mosa.DeviceDriver/ISA/ACPI/ACPIDriver.cs b/Source/Mosa.DeviceDriver/ISA/ACPI/ACPIDriver.cs index 4367ba65a2..341fdedf48 100644 --- a/Source/Mosa.DeviceDriver/ISA/ACPI/ACPIDriver.cs +++ b/Source/Mosa.DeviceDriver/ISA/ACPI/ACPIDriver.cs @@ -44,9 +44,45 @@ public unsafe class ACPIDriver : BaseDeviceDriver, IACPI public override void Initialize() { Device.Name = "ACPI"; + } + + /// + /// Probes this instance. + /// + public override void Probe() + { + //Device.Status = DeviceStatus.Available; + Device.Status = DeviceStatus.Offline; + //Setup(); + } + + /// + /// Starts this hardware device. + /// + public override void Start() + { + SMI_CommandPort.Write8(FADT.AcpiEnable); + HAL.Sleep(3000); + Device.Status = DeviceStatus.Online; + } + + /// + /// Stops this hardware device. + /// + public override void Stop() + { + SMI_CommandPort.Write8(FADT.AcpiDisable); + HAL.Sleep(3000); + Device.Status = DeviceStatus.Offline; + } - var rsdp = HAL.GetRSDP(); - var version2 = HAL.IsACPIVersion2(); + private void Setup() + { + // TODO: Find the multiboot service + // Multiboot.V2.RSDPv1 + + var rsdp = Pointer.Zero; // HAL.GetRSDP(); + var version2 = true; // HAL.IsACPIVersion2(); if (version2) { @@ -62,7 +98,8 @@ public override void Initialize() FADT = new FADT(HAL.GetPhysicalMemory(FindBySignature("FACP"), 0xFFFF).Address); MADT = new MADT(HAL.GetPhysicalMemory(FindBySignature("APIC"), 0xFFFF).Address); - if (FADT.Pointer.IsNull) return; + if (FADT.Pointer.IsNull) + return; if (!MADT.Pointer.IsNull) { @@ -74,28 +111,30 @@ public override void Initialize() for (ptr += 0x2C; ptr < ptr2;) { - var entry = (MADTEntry*)ptr; + var entry = new MADTEntry(ptr); - switch (entry->Type) + switch (entry.Type) { case 0: // Processor Local APIC - var plan = (ProcessorLocalAPICEntry*)ptr; - if ((plan->Flags & 1) != 0) - ProcessorIDs[ProcessorCount++] = plan->ApicID; + var plan = new ProcessorLocalAPICEntry(ptr); + + if ((plan.Flags & 1) != 0) + ProcessorIDs[ProcessorCount++] = plan.ApicID; + break; case 1: // I/O APIC - var ipe = (IOAPICEntry*)ptr; - IOApicAddress = ipe->ApicAddress; + var ipe = new IOAPICEntry(ptr); + IOApicAddress = ipe.ApicAddress; break; case 5: // 64-bit LAPIC - var llpe = (LongLocalAPICEntry*)ptr; - LocalApicAddress = llpe->ApicAddress; + var llpe = new LongLocalAPICEntry(ptr); + LocalApicAddress = llpe.ApicAddress; break; } - ptr += entry->Length; + ptr += entry.Length; } } @@ -157,34 +196,6 @@ public override void Initialize() } } - /// - /// Probes this instance. - /// - /// - /// Override for ISA devices, if example - /// - public override void Probe() => Device.Status = DeviceStatus.Available; - - /// - /// Starts this hardware device. - /// - public override void Start() - { - SMI_CommandPort.Write8(FADT.AcpiEnable); - HAL.Sleep(3000); - Device.Status = DeviceStatus.Online; - } - - /// - /// Stops this hardware device. - /// - public override void Stop() - { - SMI_CommandPort.Write8(FADT.AcpiDisable); - HAL.Sleep(3000); - Device.Status = DeviceStatus.Offline; - } - private Pointer FindBySignature(string signature) { var xsdt = !XSDT.Pointer.IsNull; diff --git a/Source/Mosa.DeviceDriver/Setup.cs b/Source/Mosa.DeviceDriver/Setup.cs index a5a4d78397..48ede00491 100644 --- a/Source/Mosa.DeviceDriver/Setup.cs +++ b/Source/Mosa.DeviceDriver/Setup.cs @@ -239,13 +239,13 @@ public static List GetDeviceDriverRegistryEntries() Factory = () => new PCI.VMware.VMwareSVGA2() }, - new ISADeviceDriverRegistryEntry - { - Name = "ACPI", - Platform = PlatformArchitecture.X86AndX64 | PlatformArchitecture.ARM32, - AutoLoad = true, - Factory = () => new ISA.ACPI.ACPIDriver() - }, + //new ISADeviceDriverRegistryEntry + //{ + // Name = "ACPI", + // Platform = PlatformArchitecture.X86AndX64 | PlatformArchitecture.ARM32, + // AutoLoad = true, + // Factory = () => new ISA.ACPI.ACPIDriver() + //}, }; } } diff --git a/Source/Mosa.DeviceSystem/BaseHardwareAbstraction.cs b/Source/Mosa.DeviceSystem/BaseHardwareAbstraction.cs index 78c33336da..bdaecd39cd 100644 --- a/Source/Mosa.DeviceSystem/BaseHardwareAbstraction.cs +++ b/Source/Mosa.DeviceSystem/BaseHardwareAbstraction.cs @@ -79,25 +79,6 @@ public abstract class BaseHardwareAbstraction /// public abstract void Yield(); - /// - /// Sets the ACPI RSDP pointer and if ACPI is version 2, as given by Multiboot v2. - /// - /// A pointer to a copy of the RSDP - /// If ACPI is 2.0. - public abstract void SetRSDP(Pointer pointer, bool version2); - - /// - /// Gets the ACPI RSDP pointer. - /// - /// The RSDP. - public abstract Pointer GetRSDP(); - - /// - /// Checks if ACPI is version 2.0. - /// - /// If ACPI is 2.0. - public abstract bool IsACPIVersion2(); - public abstract byte In8(ushort address); public abstract ushort In16(ushort address); diff --git a/Source/Mosa.DeviceSystem/HAL.cs b/Source/Mosa.DeviceSystem/HAL.cs index c65982eb84..747c1b16fa 100644 --- a/Source/Mosa.DeviceSystem/HAL.cs +++ b/Source/Mosa.DeviceSystem/HAL.cs @@ -111,25 +111,6 @@ public static void Assert(bool condition, string message) /// public static void Yield() => hardwareAbstraction.Yield(); - /// - /// Sets the ACPI RSDP pointer and if ACPI is version 2, as given by Multiboot v2. - /// - /// A pointer to a copy of the RSDP - /// If ACPI is 2.0. - public static void SetRSDP(Pointer pointer, bool version2) => hardwareAbstraction.SetRSDP(pointer, version2); - - /// - /// Gets the ACPI RSDP pointer. - /// - /// The RSDP. - public static Pointer GetRSDP() => hardwareAbstraction.GetRSDP(); - - /// - /// Checks if ACPI is version 2.0. - /// - /// If ACPI is 2.0. - public static bool IsACPIVersion2() => hardwareAbstraction.IsACPIVersion2(); - public static byte In8(ushort address) => hardwareAbstraction.In8(address); public static ushort In16(ushort address) => hardwareAbstraction.In16(address); diff --git a/Source/Mosa.DeviceSystem/Service/PCService.cs b/Source/Mosa.DeviceSystem/Service/PCService.cs index ef2eef79f1..9029e5ead0 100644 --- a/Source/Mosa.DeviceSystem/Service/PCService.cs +++ b/Source/Mosa.DeviceSystem/Service/PCService.cs @@ -28,13 +28,15 @@ protected override void Initialize() public bool Reset() { - if (ACPI == null) - { - ACPI = DeviceService.GetFirstDevice(DeviceStatus.Online).DeviceDriver as IACPI; + var device = DeviceService.GetFirstDevice(DeviceStatus.Online); + + if (device == null) + return false; - if (ACPI == null) - return false; - } + ACPI ??= device.DeviceDriver as IACPI; + + if (ACPI == null) + return false; var address = ACPI.ResetAddress; var value = ACPI.ResetValue; @@ -62,15 +64,18 @@ public bool Reset() public bool Shutdown() { - if (ACPI == null) - { - ACPI = DeviceService.GetFirstDevice(DeviceStatus.Online).DeviceDriver as IACPI; + var device = DeviceService.GetFirstDevice(DeviceStatus.Online); - if (ACPI == null) - return false; - } + if (device == null) + return false; + + ACPI ??= device.DeviceDriver as IACPI; + + if (ACPI == null) + return false; ACPI.PM1aControlBlock.Write16((ushort)(ACPI.SLP_TYPa | ACPI.SLP_EN)); + if (ACPI.PM1bControlBlock.Address != 0) ACPI.PM1bControlBlock.Write16((ushort)(ACPI.SLP_TYPb | ACPI.SLP_EN)); diff --git a/Source/Mosa.Kernel.BareMetal.Intel/PIC.cs b/Source/Mosa.Kernel.BareMetal.Intel/PIC.cs index 3183d0ba99..b3e68d486a 100644 --- a/Source/Mosa.Kernel.BareMetal.Intel/PIC.cs +++ b/Source/Mosa.Kernel.BareMetal.Intel/PIC.cs @@ -1,6 +1,6 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. -namespace Mosa.Kernel.BareMetal; +namespace Mosa.Kernel.BareMetal.Intel; /// /// Programmable Interrupt Controller (PIC) @@ -36,7 +36,7 @@ internal struct PICConstants public static void Setup() { - //Debug.WriteLine("PIC::Setup()"); + Debug.WriteLine("Intel.PIC::Setup()"); byte masterMask = Platform.IO.In8(PICConstants.PIC1_Data); byte slaveMask = Platform.IO.In8(PICConstants.PIC2_Data); @@ -71,7 +71,7 @@ public static void Setup() // OCW1 Platform.IO.Out8(PICConstants.PIC2_Data, slaveMask); - //Debug.WriteLine("PIC::Complete()"); + Debug.WriteLine("Intel.PIC::Setup() [Exit]"); } /// diff --git a/Source/Mosa.Kernel.BareMetal.x64/PlatformPlug.cs b/Source/Mosa.Kernel.BareMetal.x64/PlatformPlug.cs index bbf7913108..4fe701883c 100644 --- a/Source/Mosa.Kernel.BareMetal.x64/PlatformPlug.cs +++ b/Source/Mosa.Kernel.BareMetal.x64/PlatformPlug.cs @@ -18,12 +18,12 @@ public static void ForceInclude() { } [Plug("Mosa.Kernel.BareMetal.Platform::Initialization")] - public static void Initialization() + public static void Initialization(Pointer stackFrame) { - var rax = Native.GetMultibootRAX(); - var rbx = Native.GetMultibootRBX(); + var rax = stackFrame.Load32(-8); + var rbx = stackFrame.LoadPointer(-32); - Multiboot.Setup(new Pointer(rbx), (uint)rax); + Multiboot.Setup(rbx, rax); SSE.Setup(); PIC.Setup(); diff --git a/Source/Mosa.Kernel.BareMetal.x86/IDT.cs b/Source/Mosa.Kernel.BareMetal.x86/IDT.cs index 9a4937c047..33f364aadb 100644 --- a/Source/Mosa.Kernel.BareMetal.x86/IDT.cs +++ b/Source/Mosa.Kernel.BareMetal.x86/IDT.cs @@ -4,6 +4,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Mosa.Kernel.BareMetal.BootMemory; +using Mosa.Kernel.BareMetal.Intel; using Mosa.Runtime; using Mosa.Runtime.Plug; using Mosa.Runtime.x86; diff --git a/Source/Mosa.Kernel.BareMetal.x86/LocalAPIC.cs b/Source/Mosa.Kernel.BareMetal.x86/LocalAPIC.cs index 2a060c227d..5f98caaa9a 100644 --- a/Source/Mosa.Kernel.BareMetal.x86/LocalAPIC.cs +++ b/Source/Mosa.Kernel.BareMetal.x86/LocalAPIC.cs @@ -1,5 +1,6 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. +using Mosa.Kernel.BareMetal.Intel; using Mosa.Runtime; using Mosa.Runtime.x86; diff --git a/Source/Mosa.Kernel.BareMetal.x86/PlatformPlug.cs b/Source/Mosa.Kernel.BareMetal.x86/PlatformPlug.cs index c80aa01d53..0b0c48a606 100644 --- a/Source/Mosa.Kernel.BareMetal.x86/PlatformPlug.cs +++ b/Source/Mosa.Kernel.BareMetal.x86/PlatformPlug.cs @@ -17,13 +17,22 @@ public static class PlatformPlug public static void ForceInclude() { } - [Plug("Mosa.Kernel.BareMetal.Platform::Initialization")] - public static void Initialization() + [Plug("Mosa.Kernel.BareMetal.Platform::Setup")] + public static void Setup(Pointer stackFrame) { - var eax = Native.GetMultibootEAX(); - var ebx = Native.GetMultibootEBX(); + Debug.WriteLine("x86.PlatformPlug:Setup()"); - Multiboot.Setup(new Pointer(ebx), eax); + var eax = stackFrame.Load32(-4); + var ebx = stackFrame.LoadPointer(-16); + + Multiboot.Setup(ebx, eax); + Debug.WriteLine("x86.PlatformPlug:Setup() [Exit]"); + } + + [Plug("Mosa.Kernel.BareMetal.Platform::Initialize")] + public static void Initialize() + { + Debug.WriteLine("x86.PlatformPlug:Initialize()"); SSE.Setup(); PIC.Setup(); @@ -33,6 +42,8 @@ public static void Initialization() { SerialController.Setup(SerialController.COM1); } + + Debug.WriteLine("x86.PlatformPlug:Initialize() [Exit]"); } [Plug("Mosa.Kernel.BareMetal.Platform::GetBootReservedRegion")] @@ -50,7 +61,9 @@ public static void Initialization() public static void DebugWrite(byte c) { if (BootSettings.EnableDebugOutput) + { SerialController.Write(SerialController.COM1, c); + } } [Plug("Mosa.Kernel.BareMetal.Platform::GetTime")] diff --git a/Source/Mosa.Kernel.BareMetal.x86/Scheduler.cs b/Source/Mosa.Kernel.BareMetal.x86/Scheduler.cs index 813a74b300..62de29e2d7 100644 --- a/Source/Mosa.Kernel.BareMetal.x86/Scheduler.cs +++ b/Source/Mosa.Kernel.BareMetal.x86/Scheduler.cs @@ -1,6 +1,7 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. using System.Runtime.CompilerServices; +using Mosa.Kernel.BareMetal.Intel; using Mosa.Runtime; using Mosa.Runtime.x86; diff --git a/Source/Mosa.Kernel.BareMetal/BootMemory/BootMemoryMap.cs b/Source/Mosa.Kernel.BareMetal/BootMemory/BootMemoryMap.cs index 767cfe1696..415112cf2d 100644 --- a/Source/Mosa.Kernel.BareMetal/BootMemory/BootMemoryMap.cs +++ b/Source/Mosa.Kernel.BareMetal/BootMemory/BootMemoryMap.cs @@ -68,15 +68,15 @@ private static void ImportMultibootV2MemoryMap() { Debug.WriteLine("BootMemoryMap::ImportMultibootV2MemoryMap()"); - if (Multiboot.V2.EntrySize == 0) + if (Multiboot.V2.MemoryMapEntrySize == 0) return; AvailableMemory = new Pointer(Multiboot.V2.MemoryUpper * 1024); Debug.WriteLine(" > Available Memory: ", AvailableMemory.ToInt64()); - var entry = Multiboot.V2.FirstEntry; - for (var i = 0; i < Multiboot.V2.Entries; i++) + var entry = Multiboot.V2.MemoryMapStart; + for (var i = 0; i < Multiboot.V2.MemoryMapEntries; i++) { SetMemoryMap(entry.BaseAddress, entry.Length, entry.Type == 1 ? BootMemoryType.Available : BootMemoryType.Reserved); entry = entry.GetNext(); diff --git a/Source/Mosa.Kernel.BareMetal/Debug.cs b/Source/Mosa.Kernel.BareMetal/Debug.cs index 2fcb13ce66..f7c50b4159 100644 --- a/Source/Mosa.Kernel.BareMetal/Debug.cs +++ b/Source/Mosa.Kernel.BareMetal/Debug.cs @@ -5,7 +5,7 @@ namespace Mosa.Kernel.BareMetal; /// -/// Log +/// Debug /// public static class Debug { @@ -15,7 +15,7 @@ public static class Debug #region Public API - public static void Setup(bool enable = false) + public static void Setup() { IsEnabled = BootOptions.Contains("serialdebug"); diff --git a/Source/Mosa.Kernel.BareMetal/HardwareAbstractionLayer.cs b/Source/Mosa.Kernel.BareMetal/HardwareAbstractionLayer.cs index 48fe8af8eb..1bbac6f250 100644 --- a/Source/Mosa.Kernel.BareMetal/HardwareAbstractionLayer.cs +++ b/Source/Mosa.Kernel.BareMetal/HardwareAbstractionLayer.cs @@ -10,9 +10,6 @@ namespace Mosa.Kernel.BareMetal; /// public class HardwareAbstractionLayer : BaseHardwareAbstraction { - private Pointer RSDP; - private bool ACPIv2; - public override uint PageSize => Page.Size; public override PlatformArchitecture PlatformArchitecture => Platform.GetPlatformArchitecture(); @@ -46,15 +43,6 @@ public override void Abort(string message) public override void Yield() => Platform.Scheduler.Yield(); - public override void SetRSDP(Pointer pointer, bool version2) - { - RSDP = pointer; - ACPIv2 = version2; - } - - public override Pointer GetRSDP() => RSDP; - - public override bool IsACPIVersion2() => ACPIv2; public override byte In8(ushort address) => Platform.IO.In8(address); diff --git a/Source/Mosa.Kernel.BareMetal/InitialGCMemory.cs b/Source/Mosa.Kernel.BareMetal/InitialGCMemory.cs index c262fd159a..d0bf10dc74 100644 --- a/Source/Mosa.Kernel.BareMetal/InitialGCMemory.cs +++ b/Source/Mosa.Kernel.BareMetal/InitialGCMemory.cs @@ -25,13 +25,13 @@ public static void Initialize() public static Pointer AllocateMemory(uint size) { - Debug.WriteLine("+ Initial Allocation Object: size = ", size, " @ ", new Hex(Available)); + //Debug.WriteLine("+ Initial Allocation Object: size = ", size, " @ ", new Hex(Available)); var available = Available; Available += size; - Internal.MemoryClear(Available, size); + Internal.MemoryClear(available, size); return available; } diff --git a/Source/Mosa.Kernel.BareMetal/Multiboot.cs b/Source/Mosa.Kernel.BareMetal/Multiboot.cs index c15fe2dc7b..1fb775bda0 100644 --- a/Source/Mosa.Kernel.BareMetal/Multiboot.cs +++ b/Source/Mosa.Kernel.BareMetal/Multiboot.cs @@ -9,7 +9,7 @@ public static class Multiboot { public static MultibootV2 V2 { get; private set; } - public static Pointer CommandLinePointer => V2.CommandLinePointer; + public static Pointer CommandLinePointer => V2.CommandLine; public static void Setup(Pointer location, uint magic) { diff --git a/Source/Mosa.Kernel.BareMetal/MultibootSpecification/MultibootV2.cs b/Source/Mosa.Kernel.BareMetal/MultibootSpecification/MultibootV2.cs index c959c7e969..45c0c2a67c 100644 --- a/Source/Mosa.Kernel.BareMetal/MultibootSpecification/MultibootV2.cs +++ b/Source/Mosa.Kernel.BareMetal/MultibootSpecification/MultibootV2.cs @@ -1,105 +1,120 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. -using System; -using Mosa.DeviceSystem; using Mosa.Runtime; namespace Mosa.Kernel.BareMetal.MultibootSpecification; -public sealed class MultibootV2 +public struct MultibootV2 { public const uint Magic = 0x36D76289; - public readonly Pointer CommandLinePointer; - public readonly Pointer BootloaderNamePointer; - public readonly uint MemoryLower; - public readonly uint MemoryUpper; - public readonly uint EntrySize; - public readonly uint EntryVersion; - public readonly uint Entries; - public readonly MultibootV2MemoryMapEntry FirstEntry; - public readonly bool FramebufferAvailable; - public readonly FrameBuffer32 Framebuffer; - public readonly bool ACPIv2; - public readonly Pointer RSDP; + private readonly Pointer Pointer; - public MultibootV2(Pointer entry) + public readonly bool IsAvailable => !Pointer.IsNull; + + public Pointer CommandLine => GetEntryValuePointer(1, 12); + + public Pointer BootloaderName => GetEntryValuePointer(2, 8); + + public uint MemoryLower => GetEntryValue32(4, 8); + + public uint MemoryUpper => GetEntryValue32(4, 12); + + private uint MemoryMapSize => GetEntryValue32(6, 4); + + public uint MemoryMapEntrySize => GetEntryValue32(6, 8); + + public uint MemoryMapEntryVersion => GetEntryValue32(6, 12); + + public MultibootV2MemoryMapEntry MemoryMapStart => new(GetStructureEntryPointer(6, 16)); + + public uint MemoryMapEntries { - if (entry.IsNull) Environment.FailFast("Multiboot v2 is not available!"); + get + { + if (MemoryMapEntrySize == 0) + return 0; - var pointer = entry + 8; + return (MemoryMapSize - 16) / MemoryMapEntrySize; + } + } - uint type; + public Pointer FrameBuffer => GetEntryValuePointer(8, 8); - while ((type = pointer.Load32(0)) != 0) + public uint FrameBufferPitch => GetEntryValue32(8, 12); + + public uint FrameBufferWidth => GetEntryValue32(8, 16); + + public uint FrameBufferHeight => GetEntryValue32(8, 20); + + public byte FrameBufferBitPerPixel => GetEntryValue8(8, 24); + + public byte FrameBufferType => GetEntryValue8(8, 25); + + public Pointer RSDPv1 => GetEntryValuePointer(14, 8); + + public Pointer RSDPv2 => GetEntryValuePointer(15, 8); + + public MultibootV2(Pointer entry) + { + Pointer = entry; + } + + private readonly Pointer GetStructurePointer(int type) + { + for (var at = Pointer + 8; ;) { - var size = pointer.Load32(4); - - switch (type) - { - case 1: - { - CommandLinePointer = pointer + 8; - break; - } - case 2: - { - BootloaderNamePointer = pointer + 8; - break; - } - case 4: - { - MemoryLower = pointer.Load32(8); - MemoryUpper = pointer.Load32(12); - break; - } - case 6: - { - EntrySize = pointer.Load32(8); - EntryVersion = pointer.Load32(12); - Entries = (size - 16) / EntrySize; - FirstEntry = new MultibootV2MemoryMapEntry(pointer + 16); - break; - } - case 8: - { - var address = (Pointer)pointer.Load64(8); - var pitch = pointer.Load32(16); - var width = pointer.Load32(20); - var height = pointer.Load32(24); - var bpp = pointer.Load8(28); - var fbType = pointer.Load8(29); - - FramebufferAvailable = bpp == 32 && fbType <= 1; - Framebuffer = new FrameBuffer32( - new ConstrainedPointer(address, width * height * 4), - width, - height, - (x, y) => y * pitch + x * 4 - ); - - break; - } - case 13: - { - // TODO: SMBIOS - break; - } - case 14: - { - ACPIv2 = false; - RSDP = pointer + 8; - break; - } - case 15: - { - ACPIv2 = true; - RSDP = pointer + 8; - break; - } - } - - pointer += (size + 7) & ~7; + var entryType = at.Load32(); + + if (entryType == 0) + return Pointer.Zero; + + if (entryType == type) + return at; + + var size = at.Load32(4); + + at += (size + 7) & ~7; } } + + private readonly Pointer GetStructureEntryPointer(int type, int offset) + { + var entry = GetStructurePointer(type); + + if (entry.IsNull) + return Pointer.Zero; + + return entry + offset; + } + + private readonly uint GetEntryValue32(int type, int offset) + { + var entry = GetStructureEntryPointer(type, offset); + + if (entry.IsNull) + return 0; + + return entry.Load32(); + } + + private readonly byte GetEntryValue8(int type, int offset) + { + var entry = GetStructureEntryPointer(type, offset); + + if (entry.IsNull) + return 0; + + return entry.Load8(); + } + + private readonly Pointer GetEntryValuePointer(int type, int offset) + { + var entry = GetStructureEntryPointer(type, offset); + + if (entry.IsNull) + return Pointer.Zero; + + return entry; + } } diff --git a/Source/Mosa.Kernel.BareMetal/MultibootSpecification/MultibootV2MemoryMapEntry.cs b/Source/Mosa.Kernel.BareMetal/MultibootSpecification/MultibootV2MemoryMapEntry.cs index 47c405912b..4f2d90a130 100644 --- a/Source/Mosa.Kernel.BareMetal/MultibootSpecification/MultibootV2MemoryMapEntry.cs +++ b/Source/Mosa.Kernel.BareMetal/MultibootSpecification/MultibootV2MemoryMapEntry.cs @@ -4,7 +4,7 @@ namespace Mosa.Kernel.BareMetal.MultibootSpecification; -public class MultibootV2MemoryMapEntry +public struct MultibootV2MemoryMapEntry { private readonly Pointer Pointer; @@ -19,5 +19,5 @@ public MultibootV2MemoryMapEntry(Pointer entry) Pointer = entry; } - public MultibootV2MemoryMapEntry GetNext() => new(Pointer + Multiboot.V2.EntrySize); + public MultibootV2MemoryMapEntry GetNext() => new(Pointer + Multiboot.V2.MemoryMapEntrySize); } diff --git a/Source/Mosa.Kernel.BareMetal/Platform.cs b/Source/Mosa.Kernel.BareMetal/Platform.cs index e37faa2453..520c27f771 100644 --- a/Source/Mosa.Kernel.BareMetal/Platform.cs +++ b/Source/Mosa.Kernel.BareMetal/Platform.cs @@ -9,7 +9,10 @@ public static class Platform { // These methods will be plugged and implemented elsewhere in the platform specific implementation - public static void Initialization() + public static void Setup(Pointer stackFrame) + { } + + public static void Initialize() { } public static AddressRange GetBootReservedRegion() => new(0, 0); diff --git a/Source/Mosa.Kernel.BareMetal/Boot.cs b/Source/Mosa.Kernel.BareMetal/Startup.cs similarity index 91% rename from Source/Mosa.Kernel.BareMetal/Boot.cs rename to Source/Mosa.Kernel.BareMetal/Startup.cs index 861e43d08f..05bda15065 100644 --- a/Source/Mosa.Kernel.BareMetal/Boot.cs +++ b/Source/Mosa.Kernel.BareMetal/Startup.cs @@ -13,17 +13,20 @@ namespace Mosa.Kernel.BareMetal; -public static class Boot +public static class Startup { - [Plug("Mosa.Runtime.StartUp::PlatformInitialization")] - public static void PlatformInitialization() + [Plug("Mosa.Runtime.StartUp::InitializePlatform")] + public static void Initialize(Pointer stackFrame) { Platform.Interrupt.Disable(); - - Debug.WriteLine("[Platform Initialization]"); - + Platform.Setup(stackFrame); + BootOptions.Setup(); + Debug.Setup(); BootStatus.Initalize(); + Debug.WriteLine("Startup.Initialize()"); + Debug.WriteLine(" > Initial Stack @ ", new Hex(stackFrame)); + Console.BackgroundColor = ConsoleColor.Black; Console.ForegroundColor = ConsoleColor.Yellow; Console.Clear(); @@ -33,7 +36,6 @@ public static void PlatformInitialization() Console.WriteLine(); Console.WriteLine("Initializing kernel..."); - Debug.Setup(true); Console.ForegroundColor = ConsoleColor.LightGreen; Console.Write("> Initial garbage collection..."); @@ -41,27 +43,23 @@ public static void PlatformInitialization() Console.ForegroundColor = ConsoleColor.DarkGray; Console.WriteLine(" [Completed]"); - Console.ForegroundColor = ConsoleColor.LightGreen; - Console.Write("> Boot options..."); - BootOptions.Setup(); - Console.ForegroundColor = ConsoleColor.DarkGray; - Console.WriteLine(" [Completed]"); - Console.ForegroundColor = ConsoleColor.LightGreen; Console.Write("> Platform initialization..."); - Platform.Initialization(); + Platform.Initialize(); Console.ForegroundColor = ConsoleColor.DarkGray; Console.WriteLine(" [Completed]"); + + Debug.WriteLine("Startup.Initialize() [Exit]"); } [Plug("Mosa.Runtime.StartUp::KernelEntryPoint")] public static void EntryPoint() { - Debug.WriteLine("[Kernel Entry Point]"); + Debug.WriteLine("Startup.EntryPoint()"); Console.ForegroundColor = ConsoleColor.LightGreen; Console.Write("> Enabling debug logging..."); - Debug.Setup(true); + Debug.Setup(); Console.ForegroundColor = ConsoleColor.DarkGray; Console.WriteLine(" [Completed]"); @@ -133,12 +131,6 @@ public static void EntryPoint() Console.ForegroundColor = ConsoleColor.DarkGray; Console.WriteLine(" [Completed]"); - Console.ForegroundColor = ConsoleColor.LightGreen; - Console.Write("> Setting ACPI RSDP address..."); - HAL.SetRSDP(Multiboot.V2.RSDP, Multiboot.V2.ACPIv2); - Console.ForegroundColor = ConsoleColor.DarkGray; - Console.WriteLine(" [Completed]"); - Console.ForegroundColor = ConsoleColor.LightGreen; Console.Write("> Registering device drivers..."); deviceService.RegisterDeviceDriver(DeviceDriver.Setup.GetDeviceDriverRegistryEntries()); @@ -246,12 +238,16 @@ public static void EntryPoint() Platform.Interrupt.Enable(); Console.ForegroundColor = ConsoleColor.DarkGray; Console.WriteLine(" [Completed]"); + + Debug.WriteLine("Startup.EntryPoint() [Exit]"); } [Plug("Mosa.Runtime.GC::AllocateMemory")] private static Pointer AllocateMemory(uint size) { - return BootStatus.IsGCEnabled ? GCMemory.AllocateMemory(size) : InitialGCMemory.AllocateMemory(size); + return BootStatus.IsGCEnabled + ? GCMemory.AllocateMemory(size) + : InitialGCMemory.AllocateMemory(size); } private static void ProcessInterrupt(uint interrupt, uint errorCode) diff --git a/Source/Mosa.Runtime.x64/Native.cs b/Source/Mosa.Runtime.x64/Native.cs index eaf15b59f0..41215d8b5a 100644 --- a/Source/Mosa.Runtime.x64/Native.cs +++ b/Source/Mosa.Runtime.x64/Native.cs @@ -93,22 +93,22 @@ public static unsafe class Native public static extern float Roundss2Positive(float destination); //[DllImport("Mosa.Compiler.x64.Intrinsic::Popcnt32")] - //public static extern uint Popcnt32(uint esp); + //public static extern uint Popcnt32(uint rsp); //[DllImport("Mosa.Compiler.x64.Intrinsic::Popcnt64")] - //public static extern uint Popcnt64(uint esp); + //public static extern uint Popcnt64(uint rsp); //[DllImport("Mosa.Compiler.x64.Intrinsic::Lzcnt32")] - //public static extern uint Lzcnt32(uint esp); + //public static extern uint Lzcnt32(uint rsp); //[DllImport("Mosa.Compiler.x64.Intrinsic::Lzcnt64")] - //public static extern uint Lzcnt64(uint esp); + //public static extern uint Lzcnt64(uint rsp); //[DllImport("Mosa.Compiler.x64.Intrinsic::Tzcnt32")] - //public static extern uint Tzcnt32(uint esp); + //public static extern uint Tzcnt32(uint rsp); //[DllImport("Mosa.Compiler.x64.Intrinsic::Tzcnt64")] - //public static extern uint Tzcnt64(uint esp); + //public static extern uint Tzcnt64(uint rsp); #endregion Intrinsic Instructions @@ -198,23 +198,17 @@ public static unsafe class Native [DllImport("Mosa.Compiler.x64.Intrinsic::GetIDTJumpLocation")] public static extern long GetIDTJumpLocation(uint irq); - [DllImport("Mosa.Compiler.x64.Intrinsic::GetMultibootRAX")] - public static extern ulong GetMultibootRAX(); - - [DllImport("Mosa.Compiler.x64.Intrinsic::GetMultibootRBX")] - public static extern ulong GetMultibootRBX(); - [DllImport("Mosa.Compiler.x64.Intrinsic::FrameJump")] - public static extern void FrameJump(Pointer eip, Pointer esp, Pointer ebp, int exceptionRegister); + public static extern void FrameJump(Pointer rip, Pointer rsp, Pointer rbp, int exceptionRegister); [DllImport("Mosa.Compiler.x64.Intrinsic::FrameCall")] - public static extern void FrameCall(ulong eip); + public static extern void FrameCall(ulong rip); [DllImport("Mosa.Compiler.x64.Intrinsic::FrameCallRetU8")] - public static extern ulong FrameCallRetU8(ulong eip); + public static extern ulong FrameCallRetU8(ulong rip); [DllImport("Mosa.Compiler.x64.Intrinsic::FrameCallRetR8")] - public static extern ulong FrameCallRetR8(ulong eip); + public static extern ulong FrameCallRetR8(ulong rip); [DllImport("Mosa.Compiler.x64.Intrinsic::InterruptReturn")] public static extern void InterruptReturn(ulong esp); diff --git a/Source/Mosa.Runtime.x86/Native.cs b/Source/Mosa.Runtime.x86/Native.cs index 4eb9eac0d8..cff205800f 100644 --- a/Source/Mosa.Runtime.x86/Native.cs +++ b/Source/Mosa.Runtime.x86/Native.cs @@ -193,12 +193,6 @@ public static unsafe class Native [DllImport("Mosa.Compiler.x86.Intrinsic::GetIDTJumpLocation")] public static extern uint GetIDTJumpLocation(uint irq); - [DllImport("Mosa.Compiler.x86.Intrinsic::GetMultibootEAX")] - public static extern uint GetMultibootEAX(); - - [DllImport("Mosa.Compiler.x86.Intrinsic::GetMultibootEBX")] - public static extern uint GetMultibootEBX(); - [DllImport("Mosa.Compiler.x86.Intrinsic::FrameJump")] public static extern void FrameJump(Pointer eip, Pointer esp, Pointer ebp, int exceptionRegister); diff --git a/Source/Mosa.Runtime/StartUp.cs b/Source/Mosa.Runtime/StartUp.cs index 17a2dd0b31..332c371cea 100644 --- a/Source/Mosa.Runtime/StartUp.cs +++ b/Source/Mosa.Runtime/StartUp.cs @@ -4,10 +4,10 @@ namespace Mosa.Runtime; public static class StartUp { - public static void Initialize() + public static void Initialize(Pointer stackFrame) { BootOptions(); - PlatformInitialization(); + InitializePlatform(stackFrame); InitializeAssembly(); InitializeRuntimeMetadata(); KernelEntryPoint(); @@ -17,7 +17,7 @@ public static void Initialize() public static void BootOptions() { } - public static void PlatformInitialization() + public static void InitializePlatform(Pointer stackFrame) { } public static void InitializeAssembly() diff --git a/Source/Mosa.Runtime/ZeroString.cs b/Source/Mosa.Runtime/ZeroString.cs index 3e40ac259a..e853d2e7c4 100644 --- a/Source/Mosa.Runtime/ZeroString.cs +++ b/Source/Mosa.Runtime/ZeroString.cs @@ -19,7 +19,7 @@ public int Length { get { - for (int i = 0; ; i++) + for (var i = 0; ; i++) { if (Address.Load8(i) == 0) return i + 1; diff --git a/Source/Mosa.Tool.Debugger/DebugData/Source.cs b/Source/Mosa.Tool.Debugger/DebugData/Source.cs index c241fb563e..0eadd44855 100644 --- a/Source/Mosa.Tool.Debugger/DebugData/Source.cs +++ b/Source/Mosa.Tool.Debugger/DebugData/Source.cs @@ -16,7 +16,9 @@ public static SourceLocation Find(DebugSource debugSource, ulong address) if (sourceLabel == null) return null; - var sourceInfo = debugSource.GetSourcePreviousClosest(method.ID, sourceLabel.Label); + var label = sourceLabel.Label != 0x10000 ? sourceLabel.Label : 0; + + var sourceInfo = debugSource.GetSourcePreviousClosest(method.ID, label); if (sourceInfo == null) return null; diff --git a/Source/Mosa.Tool.Debugger/MainForm.cs b/Source/Mosa.Tool.Debugger/MainForm.cs index 0aa1a7fc5d..b157f5b4a1 100644 --- a/Source/Mosa.Tool.Debugger/MainForm.cs +++ b/Source/Mosa.Tool.Debugger/MainForm.cs @@ -82,6 +82,11 @@ public MainForm() { InitializeComponent(); + MosaSettings.LoadAppLocations(); + MosaSettings.SetDefaultSettings(); + + SetDefaultSettings(); + outputView = new OutputView(this); registersView = new RegisterView(this); displayView = new DisplayView(this); @@ -101,11 +106,6 @@ public MainForm() sourceDataView = new SourceDataView(this); // only useful when debugging this tool launchView = new LaunchView(this); - MosaSettings.LoadAppLocations(); - MosaSettings.SetDefaultSettings(); - - SetDefaultSettings(); - AppDomain.CurrentDomain.DomainUnload += (s, e) => { TerminateAll(); }; AppDomain.CurrentDomain.ProcessExit += (s, e) => { TerminateAll(); }; AppDomain.CurrentDomain.UnhandledException += (s, e) => { TerminateAll(); }; @@ -636,7 +636,11 @@ private void StartVM() { TerminateAll(); + MosaSettings.ResolveDefaults(); SetRequiredSettings(); + MosaSettings.ResolveFileAndPathSettings(); + MosaSettings.AddStandardPlugs(); + MosaSettings.ExpandSearchPaths(); var compilerHooks = new CompilerHooks { diff --git a/Source/Mosa.Tool.Debugger/Views/MethodParametersView.cs b/Source/Mosa.Tool.Debugger/Views/MethodParametersView.cs index 04c890f106..d89d0f0619 100644 --- a/Source/Mosa.Tool.Debugger/Views/MethodParametersView.cs +++ b/Source/Mosa.Tool.Debugger/Views/MethodParametersView.cs @@ -112,9 +112,9 @@ private void UpdateDisplay(ulong address, byte[] memory) foreach (var parameter in parameters) { - var type = DebugSource.GetTypeInfo(parameter.ParameterTypeID); + var type = parameter.ParameterTypeID > 0 ? DebugSource.GetTypeInfo(parameter.ParameterTypeID) : null; - uint size = (parameter.Size == NativeIntegerSize || parameter.Size == NativeIntegerSize * 2) ? parameter.Size : 0; + var size = (parameter.Size == NativeIntegerSize || parameter.Size == NativeIntegerSize * 2) ? parameter.Size : 0; if (size == 0 && parameter.Size <= NativeIntegerSize) { @@ -135,7 +135,7 @@ private void UpdateDisplay(ulong address, byte[] memory) Size = size, Value = value, HexValue = BasePlatform.ToHex(value, size), - Type = type.FullName, + Type = type != null ? type.FullName : "N/A", Info = MainForm.GetAddressInfo(value) }; diff --git a/Source/Mosa.Utility.Configuration/MOSASettings.cs b/Source/Mosa.Utility.Configuration/MOSASettings.cs index e9e45b608f..2a8e75f53d 100644 --- a/Source/Mosa.Utility.Configuration/MOSASettings.cs +++ b/Source/Mosa.Utility.Configuration/MOSASettings.cs @@ -20,6 +20,11 @@ public static class Constant public const int MaxAttempts = 20; public const int Port = 11110; public const int EmulatorMaxRuntime = 20; // in seconds + + public const int X86StackLocation = 0x30000; + public const int X64StackLocation = 0x30000; + public const int ARM32StackLocation = 0x30000; + public const int ARM64StackLocation = 0x30000; } #endregion Constants @@ -685,6 +690,12 @@ public int BootLoaderTimeout set => Settings.SetValue(Name.BootLoaderTimeout, value); } + public int InitialStackLocation + { + get => Settings.GetValue(Name.Compiler_InitialStackAddress, 0); + set => Settings.SetValue(Name.Compiler_InitialStackAddress, value); + } + #endregion Properties public MosaSettings() @@ -806,6 +817,8 @@ public void SetDefaultSettings() LinkerFormat = "elf32"; ExplorerFilter = "%REGISTRY%"; + + InitialStackLocation = 0; } public void NormalizeSettings() @@ -968,6 +981,28 @@ public void ResolveFileAndPathSettings() { NasmFile = Path.Combine(DefaultFolder, $"{baseFilename}.nasm"); } + + if (InitialStackLocation == 0) + { + switch (Platform.ToLowerInvariant()) + { + case "x86": + InitialStackLocation = Constant.X86StackLocation; + break; + + case "x64": + InitialStackLocation = Constant.X64StackLocation; + break; + + case "arm32": + InitialStackLocation = Constant.ARM32StackLocation; + break; + + case "arm64": + InitialStackLocation = Constant.ARM64StackLocation; + break; + } + } } public void AddStandardPlugs() diff --git a/Source/Mosa.Utility.Configuration/Name.cs b/Source/Mosa.Utility.Configuration/Name.cs index ff515ef2b0..0583958403 100644 --- a/Source/Mosa.Utility.Configuration/Name.cs +++ b/Source/Mosa.Utility.Configuration/Name.cs @@ -25,6 +25,7 @@ public static class Name public const string AppLocation_VirtualBox = "AppLocation.VirtualBox"; public const string Compiler_BaseAddress = "Compiler.BaseAddress"; + public const string Compiler_InitialStackAddress = "Compiler.InitialStackAddress"; public const string Compiler_Binary = "Compiler.Binary"; public const string Compiler_MethodScanner = "Compiler.MethodScanner"; public const string Compiler_Multithreading = "Compiler.Multithreading"; diff --git a/Source/Mosa.Utility.Launcher/Builder.cs b/Source/Mosa.Utility.Launcher/Builder.cs index 2996aa6132..bdf7892db5 100644 --- a/Source/Mosa.Utility.Launcher/Builder.cs +++ b/Source/Mosa.Utility.Launcher/Builder.cs @@ -249,7 +249,7 @@ private void LaunchNDISASM() private void GenerateASMFile() { - OutputStatus($"Executing Reko Disassembler: {MosaSettings.AsmFile}"); + OutputStatus($"Reko Disassembly: {MosaSettings.AsmFile}"); var map = new Dictionary>(); diff --git a/Source/Mosa.Utility.SourceCodeGenerator/BuildInstructionFiles.cs b/Source/Mosa.Utility.SourceCodeGenerator/BuildInstructionFiles.cs index a866d42ee2..8835d9cb4f 100644 --- a/Source/Mosa.Utility.SourceCodeGenerator/BuildInstructionFiles.cs +++ b/Source/Mosa.Utility.SourceCodeGenerator/BuildInstructionFiles.cs @@ -834,6 +834,8 @@ private static void GetCodes(string part, ref string code, ref string postcode) case "reg3not": code = "Append3BitsNot"; postcode = ".Register.RegisterCode"; return; case "reg4not": code = "Append4BitsNot"; postcode = ".Register.RegisterCode"; return; case "reg3s1": code = "Append3Bits"; postcode = ".Register.RegisterCode >> 1"; return; + case "reg16pow2": code = "Append16Bits(ToPower2"; postcode = ".Register.RegisterCode)"; return; + case "imm1": code = "Append1BitImmediate"; return; case "imm2": code = "Append2BitImmediate"; return; case "imm2scale": code = "Append2BitScale"; return; @@ -856,6 +858,8 @@ private static void GetCodes(string part, ref string code, ref string postcode) case "status": code = "Append1Bit"; postcode = ".IsSetFlags ? 1 : 0"; return; case "updir": code = "Append1Bit"; postcode = ".IsUpDirection ? 1 : 0"; return; case "downdir": code = "Append1Bit"; postcode = ".IsDownDirection ? 1 : 0"; return; + case "writeback": code = "Append1Bit"; postcode = ".IsWriteback ? 1 : 0"; return; + case "prefixadd": code = "Append1Bit"; postcode = ".IsPrefixAdd ? 1 : 0"; return; case "fp": code = "Append1Bit"; postcode = ".IsR4 ? 0 : 1"; return; case "int": code = "Append1Bit"; postcode = ".IsInteger ? 1 : 0"; return; case "float": code = "Append1Bit"; postcode = ".IsFloatingPoint ? 1 : 0"; return; diff --git a/Source/Mosa.sln b/Source/Mosa.sln index 1410114763..2570b20ba7 100644 --- a/Source/Mosa.sln +++ b/Source/Mosa.sln @@ -164,7 +164,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mosa.Utility.Configuration" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mosa.Tool.Launcher.Console", "Mosa.Tool.Launcher.Console\Mosa.Tool.Launcher.Console.csproj", "{1E16FC87-77BD-4065-A231-9E533D68C7D4}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BareMetal", "BareMetal", "{3A538FDC-0226-4971-A3C0-31570CDA340D}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BareMetal.Demos", "BareMetal.Demos", "{3A538FDC-0226-4971-A3C0-31570CDA340D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{A4028807-1B21-4D14-9CE3-5FD1AAD9EDD7}" ProjectSection(SolutionItems) = preProject