kernel/eka/nkern/x86/vectors.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32\nkern\x86\vectors.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 // NThreadBase member data
       
    19 #define __INCLUDE_NTHREADBASE_DEFINES__
       
    20 
       
    21 #include <x86.h>
       
    22 #include "vectors.h"
       
    23 
       
    24 #ifdef _DEBUG
       
    25 #define __CHECK_LOCK_STATE__
       
    26 #endif
       
    27 
       
    28 void __X86VectorIrq();
       
    29 void __X86VectorExc();
       
    30 void __X86ExcFault(TAny*);
       
    31 
       
    32 
       
    33 /** Register the global IRQ handler
       
    34 	Called by the base port at boot time to bind the top level IRQ dispatcher
       
    35 	to the X86 common IRQ handler. Should not be called at any other time.
       
    36 
       
    37 	The handler specified will be called with IRQs disabled. ESP will point
       
    38 	to the top of the interrupt stack. On entry to the handler EAX will point
       
    39 	to a block of saved registers, as follows:
       
    40 
       
    41 	[EAX+00h] = saved EDX
       
    42 	[EAX+04h] = saved ECX
       
    43 	[EAX+08h] = saved EAX
       
    44 	[EAX+0Ch] = saved ES
       
    45 	[EAX+10h] = saved DS
       
    46 	[EAX+14h] = interrupt vector number
       
    47 	[EAX+18h] = return EIP
       
    48 	[EAX+1Ch] = return CS
       
    49 	[EAX+20h] = return EFLAGS
       
    50 	[EAX+24h] = return ESP if interrupt occurred while CPL>0
       
    51 	[EAX+28h] = return SS if interrupt occurred while CPL>0
       
    52 
       
    53 	The handler should preserve all registers other than EAX, ECX, EDX
       
    54 	and should return using a standard RET instruction.
       
    55 
       
    56 	@param	aHandler The address of the top level IRQ dispatcher routine
       
    57  */
       
    58 EXPORT_C void X86::SetIrqHandler(TLinAddr aHandler)
       
    59 	{
       
    60 	X86_IrqHandler=aHandler;
       
    61 	}
       
    62 
       
    63 
       
    64 /** Return the address immediately after the end of the interrupt stack.
       
    65 
       
    66 	@return Interrupt Stack Base + Interrupt Stack Size
       
    67  */
       
    68 EXPORT_C TLinAddr X86::IrqStackTop(TInt /*aCpu*/)
       
    69 	{
       
    70 	return TLinAddr(X86_IrqStack) + IRQ_STACK_SIZE;
       
    71 	}
       
    72 
       
    73 
       
    74 void SetTrapGate(SX86Des* aEntry, PFV aHandler, TInt aDPL)
       
    75 	{
       
    76 	aEntry->iLow=(KRing0CS<<16)|(TUint32(aHandler)&0xffff);
       
    77 	aEntry->iHigh=(TUint32(aHandler)&0xffff0000) | 0x8f00 | (aDPL<<13);
       
    78 	}
       
    79 
       
    80 void SetInterruptGate(SX86Des* aEntry, PFV aHandler, TInt aDPL)
       
    81 	{
       
    82 	aEntry->iLow=(KRing0CS<<16)|(TUint32(aHandler)&0xffff);
       
    83 	aEntry->iHigh=(TUint32(aHandler)&0xffff0000) | 0x8e00 | (aDPL<<13);
       
    84 	}
       
    85 
       
    86 void SetTssDescriptor(SX86Des* aEntry, TX86Tss* aTss)
       
    87 	{
       
    88 	TUint addr3=TUint(aTss)>>24;
       
    89 	TUint addr2=(TUint(aTss)>>16)&0xff;
       
    90 	TUint addr01=TUint(aTss)&0xffff;
       
    91 	aEntry->iLow=(addr01<<16)|(sizeof(TX86Tss)-1);
       
    92 	aEntry->iHigh=(addr3<<24)|0x00108900|addr2;
       
    93 	}
       
    94 
       
    95 void X86::Init1Interrupts()
       
    96 //
       
    97 // Initialise the interrupt and exception vector handlers.
       
    98 //
       
    99 	{
       
   100 //	TheIrqHandler=0;	// done by placing TheIrqHandler, TheFiqHandler in .bss
       
   101 	__KTRACE_OPT(KBOOT,DEBUGPRINT(">X86::Init1Interrupts()"));
       
   102 	memset(X86_IrqStack,0xaa,IRQ_STACK_SIZE);
       
   103 
       
   104 #ifndef __STANDALONE_NANOKERNEL__
       
   105 	TStackInfo& stackInfo =  TheSuperPage().iStackInfo;
       
   106 	stackInfo.iIrqStackBase = X86_IrqStack;
       
   107 	stackInfo.iIrqStackSize = IRQ_STACK_SIZE;
       
   108 #endif
       
   109 	
       
   110 	TCpuPage& cp=X86::CpuPage();
       
   111 	memclr(cp.iIdt, KIdtSize*sizeof(SX86Des));
       
   112 	TInt i;
       
   113 	for (i=0; i<64; i++)
       
   114 		{
       
   115 		if (i==0x03 || i==0x20 || i==0x21)
       
   116 			SetTrapGate(cp.iIdt+i, TheExcVectors[i], 3);
       
   117 		else if (i<0x20)
       
   118 			SetTrapGate(cp.iIdt+i, TheExcVectors[i], 0);
       
   119 		if (i>=0x30)
       
   120 			SetInterruptGate(cp.iIdt+i, TheExcVectors[i], 0);
       
   121 		}
       
   122 	X86_IrqNestCount=-1;
       
   123 	X86::DefaultCR0=get_cr0();
       
   124 	memclr(&cp.iTss,sizeof(TX86Tss));
       
   125 	cp.iTss.iCR3=get_cr3();
       
   126 	cp.iTss.iSs0=KRing0DS;
       
   127 	cp.iTss.iEsp0=get_esp();
       
   128 	SetTssDescriptor(&cp.iGdt[5],&cp.iTss);
       
   129 	X86_TSS_Ptr=&cp.iTss;
       
   130 	__lidt(cp.iIdt,KIdtSize);
       
   131 	__KTRACE_OPT(KBOOT,DEBUGPRINT("<X86::Init1Interrupts()"));
       
   132 	}
       
   133 
       
   134 
       
   135 /**	Return the current processor context type (thread, IDFC or interrupt)
       
   136 
       
   137 	@return	A value from NKern::TContext enumeration (but never EEscaped)
       
   138 	@pre	Any context
       
   139 
       
   140 	@see	NKern::TContext
       
   141  */
       
   142 EXPORT_C TInt NKern::CurrentContext()
       
   143 	{
       
   144 	if (X86_IrqNestCount >= 0)
       
   145 		return NKern::EInterrupt;
       
   146 	if (TheScheduler.iInIDFC)
       
   147 		return NKern::EIDFC;
       
   148 	return NKern::EThread;
       
   149 	}
       
   150 
       
   151 extern "C" void ExcFault(TAny*);
       
   152 void __X86ExcFault(TAny* aInfo)
       
   153 	{
       
   154 	ExcFault(aInfo);
       
   155 	}
       
   156