98 |
98 |
99 asm("cmp ebp, ebx "); |
99 asm("cmp ebp, ebx "); |
100 asm("je same_thread "); |
100 asm("je same_thread "); |
101 asm("mov eax, [ebx+%0]" : : "i" _FOFF(NThreadBase, iStackBase)); |
101 asm("mov eax, [ebx+%0]" : : "i" _FOFF(NThreadBase, iStackBase)); |
102 asm("add eax, [ebx+%0]" : : "i" _FOFF(NThreadBase, iStackSize)); |
102 asm("add eax, [ebx+%0]" : : "i" _FOFF(NThreadBase, iStackSize)); |
103 asm("mov ecx, [esi+60+%0]" : : "i" _FOFF(TSubScheduler, iExtras)); // iExtras[15] points to TSS |
103 asm("mov ecx, [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iTss)); // iExtras[15] points to TSS |
104 asm("mov [ecx+%0], eax" : : "i" _FOFF(TX86Tss, iEsp0)); // set ESP0 to top of new thread supervisor stack |
104 asm("mov [ecx+%0], eax" : : "i" _FOFF(TX86Tss, iEsp0)); // set ESP0 to top of new thread supervisor stack |
105 |
105 |
106 asm("test byte ptr [ebx+%0], 2" : : "i" _FOFF(NThreadBase,i_ThrdAttr)); // test for address space switch |
106 asm("test byte ptr [ebx+%0], 2" : : "i" _FOFF(NThreadBase,i_ThrdAttr)); // test for address space switch |
107 asm("jz short resched_no_as_switch "); |
107 asm("jz short resched_no_as_switch "); |
108 asm("call [edi+%0]" : : "i" _FOFF(TScheduler, iProcessHandler)); // call handler with |
108 asm("call [edi+%0]" : : "i" _FOFF(TScheduler, iProcessHandler)); // call handler with |
549 asm("mov edx, [edx*4+%0]" : : "i"(&SubSchedulerLookupTable)); |
549 asm("mov edx, [edx*4+%0]" : : "i"(&SubSchedulerLookupTable)); |
550 asm("cmp edx, eax"); |
550 asm("cmp edx, eax"); |
551 asm("jz bad_cc"); |
551 asm("jz bad_cc"); |
552 asm("test dl, 3"); |
552 asm("test dl, 3"); |
553 asm("jnz bad_cc"); |
553 asm("jnz bad_cc"); |
554 asm("cmp eax, [edx+52+%0]": : "i"_FOFF(TSubScheduler,iExtras)); // i_IrqNestCount |
554 asm("cmp eax, [edx+%0]": : "i"_FOFF(TSubScheduler,iSSX.iIrqNestCount)); // i_IrqNestCount |
555 asm("jle irq"); |
555 asm("jle irq"); |
556 asm("cmp al, [edx+%0]": : "i"_FOFF(TSubScheduler, iInIDFC)); |
556 asm("cmp al, [edx+%0]": : "i"_FOFF(TSubScheduler, iInIDFC)); |
557 asm("jz thread"); |
557 asm("jz thread"); |
558 asm("jmp idfc"); |
558 asm("jmp idfc"); |
559 |
559 |
607 asm("mov ds:[%0], eax" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRL)); |
607 asm("mov ds:[%0], eax" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRL)); |
608 asm("popfd "); |
608 asm("popfd "); |
609 asm("ret "); |
609 asm("ret "); |
610 } |
610 } |
611 |
611 |
612 extern "C" __NAKED__ void send_irq_ipi(TSubScheduler*) |
612 extern "C" __NAKED__ void send_irq_ipi(TSubScheduler*, TInt) |
613 { |
613 { |
|
614 /* check that EQueueEvent_WakeUp isn't set since we don't support that on x86 yet */ |
|
615 asm("test dword ptr [esp+8], 2 "); |
|
616 asm("jnz wake_up_requested "); |
614 asm("mov ecx, [esp+4] "); |
617 asm("mov ecx, [esp+4] "); |
615 asm("pushfd "); |
618 asm("pushfd "); |
616 asm("mov edx, [ecx+%0]" : : "i" _FOFF(TSubScheduler, i_APICID)); |
619 asm("mov edx, [ecx+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iAPICID)); |
617 asm("cli "); |
620 asm("cli "); |
618 asm("mov ds:[%0], edx" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRH)); |
621 asm("mov ds:[%0], edx" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRH)); |
619 asm("mov eax, %0" : : "i" (TRANSFERRED_IRQ_VECTOR | 0x4000)); |
622 asm("mov eax, %0" : : "i" (TRANSFERRED_IRQ_VECTOR | 0x4000)); |
620 asm("mov ds:[%0], eax" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRL)); |
623 asm("mov ds:[%0], eax" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRL)); |
621 asm("popfd "); |
624 asm("popfd "); |
622 asm("ret "); |
625 asm("ret "); |
623 } |
626 |
624 |
627 asm("wake_up_requested: "); |
|
628 asm("int 0xff "); |
|
629 } |
|
630 |