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);
 }
Beispiel #2
0
 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
 }
Beispiel #3
0
 //        ; (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();
 }
Beispiel #4
0
 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");
 }
Beispiel #5
0
        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;
        }
Beispiel #6
0
            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
            }
Beispiel #7
0
 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);
 }
Beispiel #8
0
 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);
 }
Beispiel #9
0
 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);
 }
Beispiel #10
0
 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);
 }