public override void AssembleNew(Assembler aAssembler, object aMethodInfo) { XS.ClearInterruptFlag(); XS.Set(XSRegisters.EAX, "_NATIVE_GDT_Pointer"); XS.LoadGdt(XSRegisters.EAX, isIndirect: true); XS.Set(XSRegisters.EAX, XSRegisters.CR0); XS.Or(XSRegisters.AL, 1); XS.Set(XSRegisters.CR0, XSRegisters.EAX); XS.JumpToSegment(0x08, "PMode"); XS.Label("PMode"); }
public override void AssembleNew(Assembler aAssembler, object aMethodInfo) { // IDT is already initialized but just for base hooks, and asm only. // ie Int 1, 3 and GPF // This routine updates the IDT now that we have C# running to allow C# hooks to handle // the other INTs // We are updating the IDT, disable interrupts XS.ClearInterruptFlag(); for (int i = 0; i < 256; i++) { // These are already mapped, don't remap them. // Maybe in the future we can look at ones that are present // and skip them, but some we may want to overwrite anyways. if (i == 1 || i == 3) { continue; } XS.Set(EAX, "__ISR_Handler_" + i.ToString("X2")); XS.Set("_NATIVE_IDT_Contents", AL, destinationDisplacement: (i * 8) + 0); XS.Set("_NATIVE_IDT_Contents", AH, destinationDisplacement: (i * 8) + 1); XS.Set("_NATIVE_IDT_Contents", 0x8, destinationDisplacement: (i * 8) + 2, size: RegisterSize.Byte8); XS.Set("_NATIVE_IDT_Contents", 0x8E, destinationDisplacement: (i * 8) + 5, size: RegisterSize.Byte8); XS.ShiftRight(EAX, 16); XS.Set("_NATIVE_IDT_Contents", AL, destinationDisplacement: (i * 8) + 6); XS.Set("_NATIVE_IDT_Contents", AH, destinationDisplacement: (i * 8) + 7); } XS.Jump("__AFTER__ALL__ISR__HANDLER__STUBS__"); var xInterruptsWithParam = new[] { 8, 10, 11, 12, 13, 14 }; for (int j = 0; j < 256; j++) { XS.Label("__ISR_Handler_" + j.ToString("X2")); XS.Call("__INTERRUPT_OCCURRED__"); if (Array.IndexOf(xInterruptsWithParam, j) == -1) { XS.Push(0); } XS.Push((uint)j); if (j != 0x20) { XS.PushAllRegisters(); XS.Sub(ESP, 4); XS.Set(EAX, ESP); // preserve old stack address for passing to interrupt handler // store floating point data XS.And(ESP, 0xfffffff0); // fxsave needs to be 16-byte alligned XS.Sub(ESP, 512); // fxsave needs 512 bytes XS.SSE.FXSave(ESP, isIndirect: true); // save the registers XS.Set(EAX, ESP, destinationIsIndirect: true); XS.Push(EAX); // XS.Push(EAX); // pass old stack address (pointer to InterruptContext struct) to the interrupt handler XS.JumpToSegment(8, "__ISR_Handler_" + j.ToString("X2") + "_SetCS"); XS.Label("__ISR_Handler_" + j.ToString("X2") + "_SetCS"); MethodBase xHandler = GetInterruptHandler((byte)j); if (xHandler == null) { xHandler = GetMethodDef(typeof(Cosmos.Core.INTs).Assembly, typeof(Cosmos.Core.INTs).FullName, "HandleInterrupt_Default", true); } XS.Call(LabelName.Get(xHandler)); XS.Pop(EAX); XS.SSE.FXRestore(ESP, isIndirect: true); XS.Set(ESP, EAX); // this restores the stack for the FX stuff, except the pointer to the FX data XS.Add(ESP, 4); // "pop" the pointer XS.PopAllRegisters(); } else { new LiteralAssemblerCode("pushad"); new LiteralAssemblerCode("mov eax, ds"); new LiteralAssemblerCode("push eax"); new LiteralAssemblerCode("mov eax, es"); new LiteralAssemblerCode("push eax"); new LiteralAssemblerCode("mov eax, fs"); new LiteralAssemblerCode("push eax"); new LiteralAssemblerCode("mov eax, gs"); new LiteralAssemblerCode("push eax"); new LiteralAssemblerCode("mov ax, 0x10"); new LiteralAssemblerCode("mov ds, ax"); new LiteralAssemblerCode("mov es, ax"); new LiteralAssemblerCode("mov fs, ax"); new LiteralAssemblerCode("mov gs, ax"); new LiteralAssemblerCode("mov eax, esp"); XS.Set("static_field__Cosmos_Core_INTs_mStackContext", EAX, destinationIsIndirect: true); XS.Call(LabelName.Get(GetMethodDef(typeof(Cosmos.Core.Processing.ProcessorScheduler).Assembly, typeof(Cosmos.Core.Processing.ProcessorScheduler).FullName, "SwitchTask", true))); XS.Set(EAX, "static_field__Cosmos_Core_INTs_mStackContext", sourceIsIndirect: true); new LiteralAssemblerCode("mov esp, eax"); new LiteralAssemblerCode("pop eax"); new LiteralAssemblerCode("mov gs, eax"); new LiteralAssemblerCode("pop eax"); new LiteralAssemblerCode("mov fs, eax"); new LiteralAssemblerCode("pop eax"); new LiteralAssemblerCode("mov es, eax"); new LiteralAssemblerCode("pop eax"); new LiteralAssemblerCode("mov ds, eax"); new LiteralAssemblerCode("popad"); } XS.Add(ESP, 8); XS.Label("__ISR_Handler_" + j.ToString("X2") + "_END"); XS.InterruptReturn(); } XS.Label("__INTERRUPT_OCCURRED__"); XS.Return(); XS.Label("__AFTER__ALL__ISR__HANDLER__STUBS__"); XS.Noop(); XS.Set(EAX, EBP, sourceDisplacement: 8); XS.Compare(EAX, 0); XS.Jump(ConditionalTestEnum.Zero, ".__AFTER_ENABLE_INTERRUPTS"); // reload interrupt list XS.Set(EAX, "_NATIVE_IDT_Pointer"); XS.Set(AsmMarker.Labels[AsmMarker.Type.Processor_IntsEnabled], 1, destinationIsIndirect: true, size: RegisterSize.Byte8); XS.LoadIdt(EAX, isIndirect: true); // Reenable interrupts XS.EnableInterrupts(); XS.Label(".__AFTER_ENABLE_INTERRUPTS"); }