public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo) { XS.Mov(XSRegisters.EAX, CPUAll.ElementReference.New("MultiBootInfo_Memory_High"), sourceIsIndirect: true); XS.Xor(XSRegisters.EDX, XSRegisters.CPUx86.Registers.EDX); XS.Mov(XSRegisters.ECX, 1024); XS.Divide(XSRegisters.ECX); XS.Add(XSRegisters.EAX, 1); XS.Push(XSRegisters.EAX); }
public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo) { //ACPI Way...ONLY QEMu And Boschs XS.Mov(XSRegisters.DX, 0xB004); new CPUx86.Mov { DestinationReg = CPUx86.Registers.AX, SourceValue = 0x0 | 0x2000 }; new CPUx86.Out { DestinationReg = CPUx86.Registers.AX, Size = (byte)CPUx86.Instruction.InstructionSize.Word }; //TODO: ACPI Way...see http://forum.osdev.org/viewtopic.php?t=16990 }
// ; (No Type Info available) //; Method 'System.Void Cosmos.Kernel.Plugs.CPU.GetCPUId(System.UInt32&, System.UInt32&, System.UInt32&, System.UInt32&, System.UInt32)' //; Locals: //; (none) //; Arguments: //; (0) 16 4 ebp + 018h (Type = System.UInt32&) //; (1) 12 4 ebp + 014h (Type = System.UInt32&) //; (2) 8 4 ebp + 010h (Type = System.UInt32&) //; (3) 4 4 ebp + 0Ch (Type = System.UInt32&) //; (4) 0 4 ebp + 08h (Type = System.UInt32) //; ReturnSize: 0 public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo) { new CPUx86.ClrInterruptFlag(); XS.Mov(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: 8); XS.CpuId(); XS.Mov(XSRegisters.EDI, XSRegisters.EBP, sourceDisplacement: 0x18); XS.Mov(XSRegisters.EDI, XSRegisters.EDX, destinationIsIndirect: true); XS.Mov(XSRegisters.EDI, XSRegisters.EBP, sourceDisplacement: 0x14); XS.Mov(XSRegisters.EDI, XSRegisters.ECX, destinationIsIndirect: true); XS.Mov(XSRegisters.EDI, XSRegisters.EBP, sourceDisplacement: 0x10); XS.Mov(XSRegisters.EDI, XSRegisters.EBX, destinationIsIndirect: true); XS.Mov(XSRegisters.EDI, XSRegisters.EBP, sourceDisplacement: 0xC); XS.Mov(XSRegisters.EDI, XSRegisters.EAX, destinationIsIndirect: true); XS.Sti(); }
public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo) { new CPUx86.ClrInterruptFlag(); /* Clear all keyboard buffers (output and command buffers) */ new CPUAll.Label(".waitBuffer"); XS.Mov(XSRegisters.DX, 0x64); XS.InFromDX(XSRegisters.AL); XS.Test(XSRegisters.AL, 2); XS.Jump(ConditionalTestEnum.NotEqual, ".waitBuffer"); XS.Mov(XSRegisters.AL, 0xD1); XS.Mov(XSRegisters.DX, 0x64); XS.OutToDX(XSRegisters.AL); new CPUAll.Label(".clearBuffer"); XS.Mov(XSRegisters.DX, 0x64); XS.InFromDX(XSRegisters.AL); XS.Test(XSRegisters.AL, 2); XS.Jump(ConditionalTestEnum.NotEqual, ".clearBuffer"); XS.Mov(XSRegisters.AL, 0xFE); XS.Mov(XSRegisters.DX, 0x60); XS.OutToDX(XSRegisters.AL); new CPUAll.Label(".loop");//failed... halt XS.Halt(); XS.Jump(".loop"); }
public void Initialize() { uint xSig = 0x1BADB002; DataMembers.Add(new DataIfNotDefined("ELF_COMPILATION")); DataMembers.Add(new DataMember("MultibootSignature", new uint[] { xSig })); uint xFlags = 0x10003; DataMembers.Add(new DataMember("MultibootFlags", xFlags)); DataMembers.Add(new DataMember("MultibootChecksum", (int)(0 - (xFlags + xSig)))); DataMembers.Add(new DataMember("MultibootHeaderAddr", ElementReference.New("MultibootSignature"))); DataMembers.Add(new DataMember("MultibootLoadAddr", ElementReference.New("MultibootSignature"))); DataMembers.Add(new DataMember("MultibootLoadEndAddr", ElementReference.New("_end_code"))); DataMembers.Add(new DataMember("MultibootBSSEndAddr", ElementReference.New("_end_code"))); DataMembers.Add(new DataMember("MultibootEntryAddr", ElementReference.New("Kernel_Start"))); DataMembers.Add(new DataEndIfDefined()); DataMembers.Add(new DataIfDefined("ELF_COMPILATION")); xFlags = 0x00003; DataMembers.Add(new DataMember("MultibootSignature", new uint[] { xSig })); DataMembers.Add(new DataMember("MultibootFlags", xFlags)); DataMembers.Add(new DataMember("MultibootChecksum", (int)(0 - (xFlags + xSig)))); DataMembers.Add(new DataEndIfDefined()); // graphics info fields DataMembers.Add(new DataMember("MultibootGraphicsRuntime_VbeModeInfoAddr", Int32.MaxValue)); DataMembers.Add(new DataMember("MultibootGraphicsRuntime_VbeControlInfoAddr", Int32.MaxValue)); DataMembers.Add(new DataMember("MultibootGraphicsRuntime_VbeMode", Int32.MaxValue)); // memory DataMembers.Add(new DataMember("MultiBootInfo_Memory_High", 0)); DataMembers.Add(new DataMember("MultiBootInfo_Memory_Low", 0)); DataMembers.Add(new DataMember("Before_Kernel_Stack", new byte[0x50000])); DataMembers.Add(new DataMember("Kernel_Stack", new byte[0])); DataMembers.Add(new DataMember("MultiBootInfo_Structure", new uint[1])); // constants DataMembers.Add(new DataMember(@"__uint2double_const", new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x41 })); DataMembers.Add(new DataMember(@"__ulong2double_const", 0x5F800000)); DataMembers.Add(new DataMember(@"__doublesignbit", 0x8000000000000000)); DataMembers.Add(new DataMember(@"__floatsignbit", 0x80000000)); if (mComPort > 0) { new Define("DEBUGSTUB"); } // This is our first entry point. Multiboot uses this as Cosmos entry point. new Label("Kernel_Start", isGlobal: true); XS.Set(XSRegisters.ESP, "Kernel_Stack"); // Displays "Cosmos" in top left. Used to make sure Cosmos is booted in case of hang. // ie bootloader debugging. This must be the FIRST code, even before setup so we know // we are being called properly by the bootloader and that if there are problems its // somwhere in our code, not the bootloader. WriteDebugVideo("Cosmos pre boot"); // For when using Bochs, causes a break ASAP on entry after initial Cosmos display. //new LiteralAssemblerCode("xchg bx, bx"); // CLI ASAP WriteDebugVideo("Clearing interrupts."); XS.ClearInterruptFlag(); WriteDebugVideo("Begin multiboot info."); new LiteralAssemblerCode("%ifndef EXCLUDE_MULTIBOOT_MAGIC"); new Comment(this, "MultiBoot compliant loader provides info in registers: "); new Comment(this, "EBX=multiboot_info "); new Comment(this, "EAX=0x2BADB002 - check if it's really Multiboot-compliant loader "); new Comment(this, " ;- copy mb info - some stuff for you "); new Comment(this, "BEGIN - Multiboot Info"); new Mov { DestinationRef = ElementReference.New("MultiBootInfo_Structure"), DestinationIsIndirect = true, SourceReg = RegistersEnum.EBX }; XS.Add(XSRegisters.EBX, 4); XS.Set(XSRegisters.EAX, XSRegisters.EBX, sourceIsIndirect: true); new Mov { DestinationRef = ElementReference.New("MultiBootInfo_Memory_Low"), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX }; XS.Add(XSRegisters.EBX, 4); XS.Set(XSRegisters.EAX, XSRegisters.EBX, sourceIsIndirect: true); new Mov { DestinationRef = ElementReference.New("MultiBootInfo_Memory_High"), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX }; new Comment(this, "END - Multiboot Info"); new LiteralAssemblerCode("%endif"); WriteDebugVideo("Creating GDT."); CreateGDT(); WriteDebugVideo("Configuring PIC"); ConfigurePIC(); WriteDebugVideo("Creating IDT."); CreateIDT(); #if LFB_1024_8 new Comment("Set graphics fields"); XS.Mov(XSRegisters.EBX, Cosmos.Assembler.ElementReference.New("MultiBootInfo_Structure"), sourceIsIndirect: true); XS.Mov(XSRegisters.EAX, XSRegisters.EBX, sourceDisplacement: 72); new Move { DestinationRef = Cosmos.Assembler.ElementReference.New("MultibootGraphicsRuntime_VbeControlInfoAddr"), DestinationIsIndirect = true, SourceReg = Registers.EAX }; XS.Mov(XSRegisters.EAX, XSRegisters.EBX, sourceDisplacement: 76); new Move { DestinationRef = Cosmos.Assembler.ElementReference.New("MultibootGraphicsRuntime_VbeModeInfoAddr"), DestinationIsIndirect = true, SourceReg = Registers.EAX }; XS.Mov(XSRegisters.EAX, XSRegisters.EBX, sourceDisplacement: 80); new Move { DestinationRef = Cosmos.Assembler.ElementReference.New("MultibootGraphicsRuntime_VbeMode"), DestinationIsIndirect = true, SourceReg = Registers.EAX }; #endif //WriteDebugVideo("Initializing SSE."); //new Comment(this, "BEGIN - SSE Init"); //// CR4[bit 9]=1, CR4[bit 10]=1, CR0[bit 2]=0, CR0[bit 1]=1 //XS.Mov(XSRegisters.EAX, XSRegisters.Registers.CR4); //XS.Or(XSRegisters.EAX, 0x100); //XS.Mov(XSRegisters.CR4, XSRegisters.Registers.EAX); //XS.Mov(XSRegisters.EAX, XSRegisters.Registers.CR4); //XS.Or(XSRegisters.EAX, 0x200); //XS.Mov(XSRegisters.CR4, XSRegisters.Registers.EAX); //XS.Mov(XSRegisters.EAX, XSRegisters.Registers.CR0); //XS.And(XSRegisters.EAX, 0xfffffffd); //XS.Mov(XSRegisters.CR0, XSRegisters.Registers.EAX); //XS.Mov(XSRegisters.EAX, XSRegisters.Registers.CR0); //XS.And(XSRegisters.EAX, 1); //XS.Mov(XSRegisters.CR0, XSRegisters.Registers.EAX); //new Comment(this, "END - SSE Init"); if (mComPort > 0) { WriteDebugVideo("Initializing DebugStub."); XS.Call("DebugStub_Init"); } // Jump to Kernel entry point WriteDebugVideo("Jumping to kernel."); XS.Call(EntryPointName); new Comment(this, "Kernel done - loop till next IRQ"); XS.Label(".loop"); XS.ClearInterruptFlag(); XS.Halt(); XS.Jump(".loop"); if (mComPort > 0) { var xGen = new AsmGenerator(); var xGenerateAssembler = new Action <object>(i => { if (i is StreamReader) { var xAsm = xGen.Generate((StreamReader)i); CurrentInstance.Instructions.AddRange(xAsm.Instructions); CurrentInstance.DataMembers.AddRange(xAsm.DataMembers); } else if (i is string) { var xAsm = xGen.Generate((string)i); CurrentInstance.Instructions.AddRange(xAsm.Instructions); CurrentInstance.DataMembers.AddRange(xAsm.DataMembers); } else { throw new Exception("Object type '" + i.ToString() + "' not supported!"); } }); if (ReadDebugStubFromDisk) { foreach (var xFile in Directory.GetFiles(CosmosPaths.DebugStubSrc, "*.xs")) { xGenerateAssembler(xFile); } } else { foreach (var xManifestName in typeof(ReferenceHelper).GetTypeInfo().Assembly.GetManifestResourceNames()) { if (!xManifestName.EndsWith(".xs", StringComparison.OrdinalIgnoreCase)) { continue; } using (var xStream = typeof(ReferenceHelper).GetTypeInfo().Assembly.GetManifestResourceStream(xManifestName)) { using (var xReader = new StreamReader(xStream)) { xGenerateAssembler(xReader); } } } } OnAfterEmitDebugStub(); } else { XS.Label("DebugStub_Step"); XS.Return(); } // Start emitting assembly labels CurrentInstance.EmitAsmLabels = true; }
public override void AssembleNew(object aAssembler, object aMethodInfo) { XS.Mov(XSRegisters.BL, 0xa8); XS.Call("send_mouse_cmd"); XS.Call("mouse_read"); XS.Noop(); XS.Mov(XSRegisters.BL, 0x20); XS.Call("send_mouse_cmd"); XS.Call("mouse_read"); XS.Or(XSRegisters.AL, 3); XS.Mov(XSRegisters.BL, 0x60); XS.Push(XSRegisters.EAX); XS.Call("send_mouse_cmd"); XS.Pop(XSRegisters.EAX); XS.Call("mouse_write"); XS.Noop(); XS.Mov(XSRegisters.BL, 0xd4); XS.Call("send_mouse_cmd"); XS.Mov(XSRegisters.AL, 0xf4); XS.Call("mouse_write"); XS.Call("mouse_read"); #region mouse_read XS.Label("mouse_read"); { XS.Push(XSRegisters.ECX); XS.Push(XSRegisters.EDX); XS.Mov(XSRegisters.ECX, 0xffff); XS.Label("mouse_read_loop"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x64, Size = 8 }; XS.Test(XSRegisters.AL, 1); XS.Jump(ConditionalTestEnum.NotZero, "mouse_read_ready"); new Loop { DestinationLabel = "mouse_read_loop" }; XS.Mov(XSRegisters.AH, 1); XS.Jump("mouse_read_exit"); } XS.Label("mouse_read_ready"); { XS.Push(XSRegisters.ECX); XS.Mov(XSRegisters.ECX, 32); } XS.Label("mouse_read_delay"); { new Loop { DestinationLabel = "mouse_read_delay" }; XS.Pop(XSRegisters.ECX); new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x60, Size = 8 }; XS.Xor(XSRegisters.AH, XSRegisters.RegistersEnum.AH); } XS.Label("mouse_read_exit"); { XS.Pop(XSRegisters.EDX); XS.Pop(XSRegisters.ECX); XS.Return(); } } #endregion #region mouse_write XS.Label("mouse_write"); { XS.Push(XSRegisters.ECX); XS.Push(XSRegisters.EDX); XS.Mov(XSRegisters.BH, XSRegisters.RegistersEnum.AL); XS.Mov(XSRegisters.ECX, 0xffff); XS.Label("mouse_write_loop1"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x64, Size = 8 }; XS.Test(XSRegisters.AL, 32); XS.Jump(ConditionalTestEnum.Zero, "mouse_write_ok1"); new Loop { DestinationLabel = "mouse_write_loop1" }; XS.Mov(XSRegisters.AH, 1); XS.Jump("mouse_write_exit"); } XS.Label("mouse_write_ok1"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x60, Size = 8 }; XS.Mov(XSRegisters.ECX, 0xffff); } XS.Label("mouse_write_loop"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x64, Size = 8 }; XS.Test(XSRegisters.AL, 2); XS.Jump(ConditionalTestEnum.Zero, "mouse_write_ok"); new Loop { DestinationLabel = "mouse_write_loop" }; XS.Mov(XSRegisters.AH, 1); XS.Jump("mouse_write_exit"); } XS.Label("mouse_write_ok"); { XS.Mov(XSRegisters.AL, XSRegisters.RegistersEnum.BH); new Out2Port { DestinationValue = 0x60, SourceReg = RegistersEnum.AL, Size = 8 }; XS.Mov(XSRegisters.ECX, 0xffff); } XS.Label("mouse_write_loop3"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x64, Size = 8 }; XS.Test(XSRegisters.AL, 2); XS.Jump(ConditionalTestEnum.Zero, "mouse_write_ok3"); new Loop { DestinationLabel = "mouse_write_loop3" }; XS.Mov(XSRegisters.AH, 1); XS.Jump("mouse_write_exit"); } XS.Label("mouse_write_ok3"); { XS.Mov(XSRegisters.AH, 0x08); } XS.Label("mouse_write_loop4"); { XS.Mov(XSRegisters.ECX, 0xffff); } XS.Label("mouse_write_loop5"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x64, Size = 8 }; XS.Test(XSRegisters.AL, 1); XS.Jump(ConditionalTestEnum.NotZero, "mouse_write_ok4"); new Loop { DestinationLabel = "mouse_write_loop5" }; XS.Dec(XSRegisters.AH); XS.Jump(ConditionalTestEnum.NotZero, "mouse_write_loop4"); } XS.Label("mouse_write_ok4"); { XS.Xor(XSRegisters.AH, XSRegisters.RegistersEnum.AH); } XS.Label("mouse_write_exit"); { XS.Pop(XSRegisters.EDX); XS.Pop(XSRegisters.ECX); XS.Return(); } } #endregion #region send_mouse_cmd XS.Label("send_mouse_cmd"); { XS.Mov(XSRegisters.ECX, 0xffff); XS.Label("mouse_cmd_wait"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x64, Size = 8 }; XS.Test(XSRegisters.AL, 2); XS.Jump(ConditionalTestEnum.Zero, "mouse_cmd_send"); new Loop { DestinationLabel = "mouse_cmd_wait" }; XS.Jump("mouse_cmd_error"); } XS.Label("mouse_cmd_send"); { XS.Mov(XSRegisters.AL, XSRegisters.RegistersEnum.BL); new Out2Port { #if DebugMouse SourceValue = 0x64, DestinationReg = RegistersEnum.AL, #else DestinationValue = 0x64, SourceReg = RegistersEnum.AL, #endif Size = 8 }; XS.Mov(XSRegisters.ECX, 0xffff); } XS.Label("mouse_cmd_accept"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x64, Size = 8 }; XS.Test(XSRegisters.AL, 0x02); XS.Jump(ConditionalTestEnum.Zero, "mouse_cmd_ok"); new Loop { DestinationLabel = "mouse_cmd_accept" }; } XS.Label("mouse_cmd_error"); { XS.Mov(XSRegisters.AH, 0x01); XS.Jump("mouse_cmd_exit"); } XS.Label("mouse_cmd_ok"); { XS.Xor(XSRegisters.AH, XSRegisters.RegistersEnum.AH); } XS.Label("mouse_cmd_exit"); { XS.Return(); } } #endregion }
public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo) { XS.Mov(XSRegisters.EAX, XSRegisters.ESP, sourceDisplacement: 0x8); XS.Mov(XSRegisters.CR3, XSRegisters.CPUx86.Registers.EAX); }
public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo) { XS.Xor(XSRegisters.EAX, XSRegisters.Registers.EAX); XS.Mov(XSRegisters.AX, Cosmos.Assembler.ElementReference.New("MultibootGraphicsRuntime_VbeMode"), sourceIsIndirect: true); XS.Push(XSRegisters.EAX); }
public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo) { XS.Mov(XSRegisters.EAX, XSRegisters.CPUx86.Registers.CR0); XS.And(XSRegisters.EAX, 0x7FFFFFFF); XS.Mov(XSRegisters.CR0, XSRegisters.CPUx86.Registers.EAX); }
public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo) { XS.Mov(XSRegisters.EAX, XSRegisters.CPUx86.Registers.CR4); XS.Or(XSRegisters.EAX, 0x00000010); XS.Mov(XSRegisters.CR4, XSRegisters.CPUx86.Registers.EAX); }