kernel/eka/nkernsmp/x86/vectors.cia
branchRCL_3
changeset 257 3e88ff8f41d5
parent 256 c1f20ce4abcf
equal deleted inserted replaced
256:c1f20ce4abcf 257:3e88ff8f41d5
   336 	asm("mov es, ax ");
   336 	asm("mov es, ax ");
   337 	asm("mov eax, ds:[%0]" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ID));
   337 	asm("mov eax, ds:[%0]" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ID));
   338 	asm("shr eax, 24 ");
   338 	asm("shr eax, 24 ");
   339 	asm("mov esi, [eax*4+%0]" : : "i" (&SubSchedulerLookupTable));
   339 	asm("mov esi, [eax*4+%0]" : : "i" (&SubSchedulerLookupTable));
   340 	asm("mov edi, esp ");								// edi points to saved stuff
   340 	asm("mov edi, esp ");								// edi points to saved stuff
   341 	asm("inc dword ptr [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqCount));	// increment i_IrqCount
   341 	asm("inc dword ptr [esi+36+%0]" : : "i" _FOFF(TSubScheduler, iExtras));	// increment i_IrqCount
   342 	asm("inc dword ptr [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));	// nest count starts at -1, iExtras[13]
   342 	asm("inc dword ptr [esi+52+%0]" : : "i" _FOFF(TSubScheduler, iExtras));	// nest count starts at -1, iExtras[13]
   343 	asm("jnz short nested_irq_entry ");
   343 	asm("jnz short nested_irq_entry ");
   344 	asm("mov esp, [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqStackTop));			// iExtras[14] = irq stack top
   344 	asm("mov esp, [esi+56+%0]" : : "i" _FOFF(TSubScheduler, iExtras));			// iExtras[14] = irq stack top
   345 	asm("push edi ");
   345 	asm("push edi ");
   346 	asm("nested_irq_entry: ");
   346 	asm("nested_irq_entry: ");
   347 	asm("mov edx, [esi+%0]" : : "i" _FOFF(TSubScheduler, iCpuMask));
   347 	asm("mov edx, [esi+%0]" : : "i" _FOFF(TSubScheduler, iCpuMask));
   348 	asm("lock or [%a0], edx" : : "i" (&TheScheduler.iCpusNotIdle));
   348 	asm("lock or [%a0], edx" : : "i" (&TheScheduler.iCpusNotIdle));
   349 	asm("mov ebx, [edi+%0]" : : "i" _FOFF(SThreadExcStack, iVector));
   349 	asm("mov ebx, [edi+%0]" : : "i" _FOFF(SThreadExcStack, iVector));
   391 	asm("add esp, 4 ");
   391 	asm("add esp, 4 ");
   392 
   392 
   393 	// Postamble. Interrupts disabled here.
   393 	// Postamble. Interrupts disabled here.
   394 	asm("postamble: ");
   394 	asm("postamble: ");
   395 	asm("cli ");
   395 	asm("cli ");
   396 	asm("dec dword ptr [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));
   396 	asm("dec dword ptr [esi+52+%0]" : : "i" _FOFF(TSubScheduler, iExtras));
   397 	asm("jns short nested_irq_exit ");
   397 	asm("jns short nested_irq_exit ");
   398 
   398 
   399 	// Check for deferred/transferred IRQs
   399 	// Check for deferred/transferred IRQs
   400 	asm("cmp byte ptr [esi+%0], 0 " : : "i" _FOFF(TSubScheduler,iEventHandlersPending));
   400 	asm("cmp byte ptr [esi+%0], 0 " : : "i" _FOFF(TSubScheduler,iEventHandlersPending));
   401 	asm("je short no_event_handlers ");
   401 	asm("je short no_event_handlers ");
   402 
   402 
   403 	// increment i_IrqNestCount again since we are going to run more ISRs
   403 	// increment i_IrqNestCount again since we are going to run more ISRs
   404 	asm("inc dword ptr [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));
   404 	asm("inc dword ptr [esi+52+%0]" : : "i" _FOFF(TSubScheduler, iExtras));
   405 	asm("push esi ");
   405 	asm("push esi ");
   406 	asm("call %a0" : : "i" (run_event_handlers));
   406 	asm("call %a0" : : "i" (run_event_handlers));
   407 	asm("add esp, 4 ");
   407 	asm("add esp, 4 ");
   408 	asm("dec dword ptr [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));
   408 	asm("dec dword ptr [esi+52+%0]" : : "i" _FOFF(TSubScheduler, iExtras));
   409 
   409 
   410 	asm("no_event_handlers: ");
   410 	asm("no_event_handlers: ");
   411 	asm("pop eax ");
   411 	asm("pop eax ");
   412 	asm("mov esp, eax ");
   412 	asm("mov esp, eax ");
   413 	asm("cmp dword ptr [esi+%0], 0" : : "i" _FOFF(TSubScheduler, iKernLockCount));
   413 	asm("cmp dword ptr [esi+%0], 0" : : "i" _FOFF(TSubScheduler, iKernLockCount));
   515 	asm("mov cx, %0" : : "i" (KRing0DS));
   515 	asm("mov cx, %0" : : "i" (KRing0DS));
   516 	asm("mov gs, cx ");			// exception in user mode -> GS = user mode DS
   516 	asm("mov gs, cx ");			// exception in user mode -> GS = user mode DS
   517 	asm("ring0_exception: ");
   517 	asm("ring0_exception: ");
   518 	asm("mov [ebp], eax ");
   518 	asm("mov [ebp], eax ");
   519 
   519 
   520 	asm("cmp dword ptr [esi+%0], -1 " : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));
   520 	asm("cmp dword ptr [esi+52+%0], -1 " : : "i" _FOFF(TSubScheduler, iExtras));
   521 	asm("jnz short fatal_exception_irq ");
   521 	asm("jnz short fatal_exception_irq ");
   522 	asm("cmp dword ptr [esi+%0], 0 " : : "i" _FOFF(TSubScheduler, iKernLockCount));
   522 	asm("cmp dword ptr [esi+%0], 0 " : : "i" _FOFF(TSubScheduler, iKernLockCount));
   523 	asm("jnz short fatal_exception_locked ");
   523 	asm("jnz short fatal_exception_locked ");
   524 	asm("sti ");
   524 	asm("sti ");
   525 	asm("cmp dword ptr [ebp+%0], 7 " : : "i" _FOFF(TX86ExcInfo, iExcId)); // check for device not available
   525 	asm("cmp dword ptr [ebp+%0], 7 " : : "i" _FOFF(TX86ExcInfo, iExcId)); // check for device not available
   600 	asm("mov bp, ss ");
   600 	asm("mov bp, ss ");
   601 	asm("mov ds, bp ");
   601 	asm("mov ds, bp ");
   602 	asm("mov esi, ds:[%0]" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ID));
   602 	asm("mov esi, ds:[%0]" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ID));
   603 	asm("shr esi, 24 ");
   603 	asm("shr esi, 24 ");
   604 	asm("mov esi, [esi*4+%0]" : : "i" (&SubSchedulerLookupTable));			// esi -> subscheduler
   604 	asm("mov esi, [esi*4+%0]" : : "i" (&SubSchedulerLookupTable));			// esi -> subscheduler
   605 	asm("mov ebp, [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iCrashState));
   605 	asm("mov ebp, [esi+44+%0]" : : "i" _FOFF(TSubScheduler, iExtras));
   606 	asm("cmp ebp, 16 ");
   606 	asm("cmp ebp, 16 ");
   607 	asm("jae nmihook ");
   607 	asm("jae nmihook ");
   608 	asm("mov ebp, [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iTss));		// points to SCpuData
   608 	asm("mov ebp, [esi+60+%0]" : : "i" _FOFF(TSubScheduler, iExtras));		// points to SCpuData
   609 	asm("mov edi, %0" : : "i" (addressof_TheScheduler)); 
   609 	asm("mov edi, %0" : : "i" (addressof_TheScheduler)); 
   610 	asm("lea ebp, [ebp+%0]" : : "i" _FOFF(SCpuData, iRegs));
   610 	asm("lea ebp, [ebp+%0]" : : "i" _FOFF(SCpuData, iRegs));
   611 	asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet, iEax));
   611 	asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet, iEax));
   612 	asm("mov [ebp+%0], ebx" : : "i" _FOFF(SFullX86RegSet, iEbx));
   612 	asm("mov [ebp+%0], ebx" : : "i" _FOFF(SFullX86RegSet, iEbx));
   613 	asm("mov [ebp+%0], ecx" : : "i" _FOFF(SFullX86RegSet, iEcx));
   613 	asm("mov [ebp+%0], ecx" : : "i" _FOFF(SFullX86RegSet, iEcx));
   625 	asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet, iEs));
   625 	asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet, iEs));
   626 	asm("mov ax, fs ");
   626 	asm("mov ax, fs ");
   627 	asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet, iFs));
   627 	asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet, iFs));
   628 	asm("mov ax, gs ");
   628 	asm("mov ax, gs ");
   629 	asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet, iGs));
   629 	asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet, iGs));
   630 	asm("lea ebx, [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));		// points to i_IrqNestCount
   630 	asm("lea ebx, [esi+52+%0]" : : "i" _FOFF(TSubScheduler, iExtras));		// points to i_IrqNestCount
   631 	asm("mov eax, 0x80000000 ");
   631 	asm("mov eax, 0x80000000 ");
   632 	asm("lock xchg eax, [ebx] ");
   632 	asm("lock xchg eax, [ebx] ");
   633 	asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet, iIrqNestCount));
   633 	asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet, iIrqNestCount));
   634 	asm("test dl, 3 ");
   634 	asm("test dl, 3 ");
   635 	asm("jnz short priv_change ");
   635 	asm("jnz short priv_change ");
   639 	asm("jmp short got_regs ");
   639 	asm("jmp short got_regs ");
   640 	asm("priv_change: ");
   640 	asm("priv_change: ");
   641 	asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet, iEsp));
   641 	asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet, iEsp));
   642 	asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet, iSs));
   642 	asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet, iSs));
   643 	asm("got_regs: ");
   643 	asm("got_regs: ");
   644 	asm("mov dword ptr [esi+%0], 2" : : "i" _FOFF(TSubScheduler, iSSX.iCrashState));	// flag that this CPU is done
   644 	asm("mov dword ptr [esi+44+%0], 2" : : "i" _FOFF(TSubScheduler, iExtras));	// flag that this CPU is done
   645 	asm("nmi_halt: ");
   645 	asm("nmi_halt: ");
   646 	asm("cli ");
   646 	asm("cli ");
   647 	asm("xor eax, eax ");
   647 	asm("xor eax, eax ");
   648 	asm("push eax ");
   648 	asm("push eax ");
   649 	asm("push eax ");
   649 	asm("push eax ");
   792 // Call from ISR
   792 // Call from ISR
   793 EXPORT_C __NAKED__ TLinAddr X86::IrqReturnAddress()
   793 EXPORT_C __NAKED__ TLinAddr X86::IrqReturnAddress()
   794 	{
   794 	{
   795 	asm("mov eax, ds:[%0]" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ID));
   795 	asm("mov eax, ds:[%0]" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ID));
   796 	asm("shr eax, 24 ");
   796 	asm("shr eax, 24 ");
   797 	asm("mov eax, [eax*4+%0]" : : "i" (&SubSchedulerLookupTable));				// esi -> subscheduler
   797 	asm("mov eax, [eax*4+%0]" : : "i" (&SubSchedulerLookupTable));			// esi -> subscheduler
   798 	asm("mov eax, [eax+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqStackTop));	// eax = i_IrqStackTop
   798 	asm("mov eax, [eax+56+%0]" : : "i" _FOFF(TSubScheduler, iExtras));		// eax = i_IrqStackTop
   799 	asm("mov eax, [eax-4] ");													// saved supervisor stack pointer
   799 	asm("mov eax, [eax-4] ");												// saved supervisor stack pointer
   800 	asm("mov eax, [eax+%0]" : : "i" _FOFF(SThreadExcStack, iEip));				// saved return address from original interrupt
   800 	asm("mov eax, [eax+%0]" : : "i" _FOFF(SThreadExcStack, iEip));			// saved return address from original interrupt
   801 	asm("ret ");
   801 	asm("ret ");
   802 	}
   802 	}
   803 
   803 
   804 __NAKED__ TUint32 get_cr0()
   804 __NAKED__ TUint32 get_cr0()
   805 	{
   805 	{
   861 	asm("mov esi, %0" : : "i" (addressof_TheSubSchedulers));
   861 	asm("mov esi, %0" : : "i" (addressof_TheSubSchedulers));
   862 	asm("mov ebx, %0" : : "i" (sss));
   862 	asm("mov ebx, %0" : : "i" (sss));
   863 	asm("shr eax, 1 ");
   863 	asm("shr eax, 1 ");
   864 	asm("jnc short sgi1 ");
   864 	asm("jnc short sgi1 ");
   865 	asm("sgi2: ");
   865 	asm("sgi2: ");
   866 	asm("mov ecx, [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iAPICID));
   866 	asm("mov ecx, [esi+48+%0]" : : "i" _FOFF(TSubScheduler, iExtras));	// ss.i_APICID
   867 	asm("mov ds:[%0], ecx" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRH));
   867 	asm("mov ds:[%0], ecx" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRH));
   868 	asm("mov ds:[%0], edx" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRL));
   868 	asm("mov ds:[%0], edx" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRL));
   869 	asm("sgi1: ");
   869 	asm("sgi1: ");
   870 	asm("add esi, ebx ");
   870 	asm("add esi, ebx ");
   871 	asm("shr eax, 1 ");
   871 	asm("shr eax, 1 ");