sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32\nkern\x86\ncutils.cia sl@0: // sl@0: // sl@0: sl@0: #include sl@0: sl@0: EXPORT_C __NAKED__ TUint64 X86::Timestamp() sl@0: { sl@0: asm("rdtsc"); sl@0: asm("ret"); sl@0: } sl@0: sl@0: extern "C" __NAKED__ void NKIdle(TInt) sl@0: { sl@0: asm("hlt"); sl@0: asm("ret"); sl@0: } sl@0: sl@0: __NAKED__ void InitFpu() sl@0: { sl@0: asm("mov eax, cr0"); sl@0: asm("and al, 0xf7"); // enable access to FPU sl@0: asm("mov cr0, eax"); sl@0: asm("fninit"); sl@0: asm("lea ecx, %a0": : "i"(DefaultCoprocessorState)); sl@0: asm("fwait"); sl@0: asm("fnsave [ecx]"); // save clean coprocessor state sl@0: asm("fwait"); sl@0: asm("or al, 8"); sl@0: asm("mov cr0, eax"); // disable access to coprocessor sl@0: asm("ret"); sl@0: } sl@0: sl@0: sl@0: const TLinAddr addressof_CrashState = (TLinAddr)&::CrashState; sl@0: const TLinAddr addressof_X86_Regs = (TLinAddr)&::X86_Regs; sl@0: const TLinAddr addressof_X86_IrqNestCount = (TLinAddr)&::X86_IrqNestCount; sl@0: sl@0: /** @internalTechnology sl@0: sl@0: Called to indicate that the system has crashed and all CPUs should be sl@0: halted and should dump their registers. sl@0: sl@0: Doesn't return sl@0: */ sl@0: __NAKED__ void NKern::NotifyCrash(const TAny* /*a0*/, TInt /*a1*/) sl@0: { sl@0: asm("pushfd "); sl@0: asm("cli "); sl@0: asm("push ebp "); sl@0: asm("mov ebp, %0" : : "i" (addressof_CrashState)); sl@0: asm("mov dword ptr [ebp], 1 "); sl@0: asm("mov ebp, %0" : : "i" (addressof_X86_Regs)); sl@0: asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet,iEax)); sl@0: asm("mov [ebp+%0], ebx" : : "i" _FOFF(SFullX86RegSet,iEbx)); sl@0: asm("mov [ebp+%0], ecx" : : "i" _FOFF(SFullX86RegSet,iEcx)); sl@0: asm("mov [ebp+%0], edx" : : "i" _FOFF(SFullX86RegSet,iEdx)); sl@0: asm("mov [ebp+%0], esi" : : "i" _FOFF(SFullX86RegSet,iEsi)); sl@0: asm("mov [ebp+%0], edi" : : "i" _FOFF(SFullX86RegSet,iEdi)); sl@0: asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iEbp)); // pushed EBP sl@0: asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iEflags)); // pushed EFLAGS sl@0: asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iEip)); // return address sl@0: asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iFaultCategory)); // a0 parameter sl@0: asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iFaultReason)); // a1 parameter sl@0: asm("mov [ebp+%0], esp" : : "i" _FOFF(SFullX86RegSet,iEsp)); sl@0: asm("lea eax, [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iCs)); sl@0: asm("mov [eax], cs "); sl@0: asm("mov [eax+4], ds "); sl@0: asm("mov [eax+8], es "); sl@0: asm("mov [eax+12], fs "); sl@0: asm("mov [eax+16], gs "); sl@0: asm("mov [eax+20], ss "); sl@0: asm("mov ebx, %0" : : "i" (addressof_X86_IrqNestCount)); sl@0: asm("mov eax, 0x80000000 "); sl@0: asm("lock xchg eax, [ebx] "); sl@0: asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet,iIrqNestCount)); sl@0: sl@0: asm("xor eax, eax "); sl@0: asm("push eax "); sl@0: asm("push eax "); sl@0: asm("push eax "); sl@0: asm("call %a0" : : "i" (NKCrashHandler)); sl@0: asm("pop eax "); sl@0: asm("pop eax "); sl@0: asm("pop eax "); sl@0: asm("push dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iFaultReason)); // a1 parameter sl@0: asm("push dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iFaultCategory)); // a0 parameter sl@0: asm("push 1 "); sl@0: asm("call %a0" : : "i" (NKCrashHandler)); sl@0: sl@0: asm("int 0xff "); // shouldn't get here sl@0: } sl@0: