Update contrib.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\nkern\x86\vectors.cpp
18 // NThreadBase member data
19 #define __INCLUDE_NTHREADBASE_DEFINES__
25 #define __CHECK_LOCK_STATE__
28 void __X86VectorIrq();
29 void __X86VectorExc();
30 void __X86ExcFault(TAny*);
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.
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:
46 [EAX+14h] = interrupt vector number
47 [EAX+18h] = return EIP
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
53 The handler should preserve all registers other than EAX, ECX, EDX
54 and should return using a standard RET instruction.
56 @param aHandler The address of the top level IRQ dispatcher routine
58 EXPORT_C void X86::SetIrqHandler(TLinAddr aHandler)
60 X86_IrqHandler=aHandler;
64 /** Return the address immediately after the end of the interrupt stack.
66 @return Interrupt Stack Base + Interrupt Stack Size
68 EXPORT_C TLinAddr X86::IrqStackTop(TInt /*aCpu*/)
70 return TLinAddr(X86_IrqStack) + IRQ_STACK_SIZE;
74 void SetTrapGate(SX86Des* aEntry, PFV aHandler, TInt aDPL)
76 aEntry->iLow=(KRing0CS<<16)|(TUint32(aHandler)&0xffff);
77 aEntry->iHigh=(TUint32(aHandler)&0xffff0000) | 0x8f00 | (aDPL<<13);
80 void SetInterruptGate(SX86Des* aEntry, PFV aHandler, TInt aDPL)
82 aEntry->iLow=(KRing0CS<<16)|(TUint32(aHandler)&0xffff);
83 aEntry->iHigh=(TUint32(aHandler)&0xffff0000) | 0x8e00 | (aDPL<<13);
86 void SetTssDescriptor(SX86Des* aEntry, TX86Tss* aTss)
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;
95 void X86::Init1Interrupts()
97 // Initialise the interrupt and exception vector handlers.
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);
104 #ifndef __STANDALONE_NANOKERNEL__
105 TStackInfo& stackInfo = TheSuperPage().iStackInfo;
106 stackInfo.iIrqStackBase = X86_IrqStack;
107 stackInfo.iIrqStackSize = IRQ_STACK_SIZE;
110 TCpuPage& cp=X86::CpuPage();
111 memclr(cp.iIdt, KIdtSize*sizeof(SX86Des));
115 if (i==0x03 || i==0x20 || i==0x21)
116 SetTrapGate(cp.iIdt+i, TheExcVectors[i], 3);
118 SetTrapGate(cp.iIdt+i, TheExcVectors[i], 0);
120 SetInterruptGate(cp.iIdt+i, TheExcVectors[i], 0);
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()"));
135 /** Return the current processor context type (thread, IDFC or interrupt)
137 @return A value from NKern::TContext enumeration (but never EEscaped)
142 EXPORT_C TInt NKern::CurrentContext()
144 if (X86_IrqNestCount >= 0)
145 return NKern::EInterrupt;
146 if (TheScheduler.iInIDFC)
148 return NKern::EThread;
151 extern "C" void ExcFault(TAny*);
152 void __X86ExcFault(TAny* aInfo)